diff --git a/binary/bytes.go b/binary/bytes.go
index 03a736c45df1e1ebddb7b2535051899a97194138..85588da2076332762373e5af185b31df06270211 100644
--- a/binary/bytes.go
+++ b/binary/bytes.go
@@ -20,3 +20,25 @@ func (hb HexBytes) MarshalText() ([]byte, error) {
 func (hb HexBytes) String() string {
 	return hex.EncodeUpperToString(hb)
 }
+
+// Protobuf support
+func (hb HexBytes) Marshal() ([]byte, error) {
+	return hb, nil
+}
+
+func (hb *HexBytes) Unmarshal(data []byte) error {
+	*hb = data
+	return nil
+}
+
+func (hb HexBytes) MarshalTo(data []byte) (int, error) {
+	return copy(data, hb), nil
+}
+
+func (hb HexBytes) Size() int {
+	return len(hb)
+}
+
+func (hb HexBytes) Bytes() []byte {
+	return hb
+}
diff --git a/binary/integer.go b/binary/integer.go
index 5824a4a9a9efbdb0a596765dbbf004ede7ef02d4..82e757c2913db6219d50497d7b87d7c1b5300131 100644
--- a/binary/integer.go
+++ b/binary/integer.go
@@ -18,7 +18,6 @@ import (
 	"encoding/binary"
 	"math"
 	"math/big"
-	"sort"
 )
 
 var big1 = big.NewInt(1)
@@ -27,21 +26,6 @@ var tt256 = new(big.Int).Lsh(big1, 256)
 var tt256m1 = new(big.Int).Sub(new(big.Int).Lsh(big1, 256), big1)
 var tt255 = new(big.Int).Lsh(big1, 255)
 
-// Sort for []uint64
-
-type Uint64Slice []uint64
-
-func (p Uint64Slice) Len() int           { return len(p) }
-func (p Uint64Slice) Less(i, j int) bool { return p[i] < p[j] }
-func (p Uint64Slice) Swap(i, j int)      { p[i], p[j] = p[j], p[i] }
-func (p Uint64Slice) Sort()              { sort.Sort(p) }
-
-func SearchUint64s(a []uint64, x uint64) int {
-	return sort.Search(len(a), func(i int) bool { return a[i] >= x })
-}
-
-func (p Uint64Slice) Search(x uint64) int { return SearchUint64s(p, x) }
-
 //--------------------------------------------------------------------------------
 
 func PutUint64LE(dest []byte, i uint64) {
diff --git a/binary/word256.go b/binary/word256.go
index 7d69e60002b693adb184e3e39f2347041bf8de52..a41b60d7d54e797780c88dc931ed07121a91cf41 100644
--- a/binary/word256.go
+++ b/binary/word256.go
@@ -16,6 +16,7 @@ package binary
 
 import (
 	"bytes"
+	"fmt"
 	"math/big"
 	"sort"
 
@@ -95,6 +96,37 @@ func (w Word256) UnpadRight() []byte {
 	return bytes.TrimRight(w[:], trimCutSet)
 }
 
+// Gogo proto support
+func (w *Word256) Marshal() ([]byte, error) {
+	if w == nil {
+		return nil, nil
+	}
+	return w.Bytes(), nil
+}
+
+func (w *Word256) Unmarshal(data []byte) error {
+	if len(data) == 0 {
+		return nil
+	}
+	if len(data) != Word256Length {
+		return fmt.Errorf("error unmarshallling Word256 '%X' from bytes: %d bytes but should have %d bytes",
+			data, len(data), Word256Length)
+	}
+	copy(w[:], data)
+	return nil
+}
+
+func (w *Word256) MarshalTo(data []byte) (int, error) {
+	if w == nil {
+		return 0, nil
+	}
+	return copy(data, w[:]), nil
+}
+
+func (w Word256) Size() int {
+	return Word256Length
+}
+
 func Uint64ToWord256(i uint64) Word256 {
 	buf := [8]byte{}
 	PutUint64BE(buf[:], i)
diff --git a/blockchain/validators_test.go b/blockchain/validators_test.go
index 35513d43af9c052f3c31a494ec6d5ea4ee7c149b..433db89eb006de0cd176a6851f9e7460e6435168 100644
--- a/blockchain/validators_test.go
+++ b/blockchain/validators_test.go
@@ -7,7 +7,7 @@ import (
 
 	"math/rand"
 
-	acm "github.com/hyperledger/burrow/account"
+	"github.com/hyperledger/burrow/acm"
 	"github.com/hyperledger/burrow/crypto"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
diff --git a/client/client_do.go b/client/client_do.go
deleted file mode 100644
index 4816cafd84eebc8c8107c5044745f7c94cb9a755..0000000000000000000000000000000000000000
--- a/client/client_do.go
+++ /dev/null
@@ -1,74 +0,0 @@
-// Copyright 2017 Monax Industries Limited
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//    http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package client
-
-type Do struct {
-	// Persistent flags not reflected in the configuration files
-	// only set through command line flags or environment variables
-	Debug   bool // BURROW_DEBUG
-	Verbose bool // BURROW_VERBOSE
-
-	// Following parameters are global flags for burrow-client tx
-	SignAddrFlag string
-	NodeAddrFlag string
-	PubkeyFlag   string
-	AddrFlag     string
-
-	// signFlag      bool // TODO: remove; unsafe signing without monax-keys
-	BroadcastFlag bool
-	WaitFlag      bool
-
-	// Following parameters are vary for different Transaction subcommands
-	// some of these are strings rather than flags because the `core`
-	// functions have a pure string interface so they work nicely from http
-	AmtFlag      string
-	NonceFlag    string
-	NameFlag     string
-	DataFlag     string
-	DataFileFlag string
-	ToFlag       string
-	FeeFlag      string
-	GasFlag      string
-	UnbondtoFlag string
-	HeightFlag   string
-}
-
-func NewClientDo() *Do {
-	clientDo := new(Do)
-	clientDo.Debug = false
-	clientDo.Verbose = false
-
-	clientDo.SignAddrFlag = ""
-	clientDo.NodeAddrFlag = ""
-	clientDo.PubkeyFlag = ""
-	clientDo.AddrFlag = ""
-
-	// clientDo.signFlag = false
-	clientDo.BroadcastFlag = false
-	clientDo.WaitFlag = false
-
-	clientDo.AmtFlag = ""
-	clientDo.NonceFlag = ""
-	clientDo.NameFlag = ""
-	clientDo.DataFlag = ""
-	clientDo.DataFileFlag = ""
-	clientDo.ToFlag = ""
-	clientDo.FeeFlag = ""
-	clientDo.GasFlag = ""
-	clientDo.UnbondtoFlag = ""
-	clientDo.HeightFlag = ""
-
-	return clientDo
-}
diff --git a/client/cmd/burrow-client.go b/client/cmd/burrow-client.go
deleted file mode 100644
index bbd1d75636713c2ca7030c697dbd966a31734c62..0000000000000000000000000000000000000000
--- a/client/cmd/burrow-client.go
+++ /dev/null
@@ -1,103 +0,0 @@
-// Copyright 2017 Monax Industries Limited
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//    http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package commands
-
-import (
-	"os"
-	"strconv"
-
-	"fmt"
-
-	"github.com/hyperledger/burrow/client"
-	"github.com/hyperledger/burrow/project"
-	"github.com/spf13/cobra"
-)
-
-// Global flags for persistent flags
-var clientDo *client.Do
-
-var BurrowClientCmd = &cobra.Command{
-	Use:   "burrow-client",
-	Short: "burrow-client interacts with a running burrow chain.",
-	Long: `burrow-client interacts with a running burrow chain.
-
-Made with <3 by Monax Industries.
-
-Complete documentation is available at https://monax.io/docs
-
-VERSION: ` + project.FullVersion(),
-	Run: func(cmd *cobra.Command, args []string) { cmd.Help() },
-}
-
-func Execute() {
-	InitBurrowClientInit()
-	AddGlobalFlags()
-	AddClientCommands()
-	BurrowClientCmd.Execute()
-}
-
-func InitBurrowClientInit() {
-	// initialise an empty Do struct for command execution
-	clientDo = client.NewClientDo()
-}
-
-func AddGlobalFlags() {
-	BurrowClientCmd.PersistentFlags().BoolVarP(&clientDo.Verbose, "verbose", "v", defaultVerbose(), "verbose output; more output than no output flags; less output than debug level; default respects $BURROW_CLIENT_VERBOSE")
-	BurrowClientCmd.PersistentFlags().BoolVarP(&clientDo.Debug, "debug", "d", defaultDebug(), "debug level output; the most output available for burrow-client; if it is too chatty use verbose flag; default respects $BURROW_CLIENT_DEBUG")
-}
-
-func AddClientCommands() {
-	BurrowClientCmd.AddCommand(buildTransactionCommand(), buildStatusCommand())
-	BurrowClientCmd.AddCommand(&cobra.Command{
-		Use:   "version",
-		Short: "Print full version",
-		Run:   func(cmd *cobra.Command, args []string) { fmt.Println(project.FullVersion()) },
-	})
-}
-
-//------------------------------------------------------------------------------
-// Defaults
-
-// defaultVerbose is set to false unless the BURROW_CLIENT_VERBOSE environment
-// variable is set to a parsable boolean.
-func defaultVerbose() bool {
-	return setDefaultBool("BURROW_CLIENT_VERBOSE", false)
-}
-
-// defaultDebug is set to false unless the BURROW_CLIENT_DEBUG environment
-// variable is set to a parsable boolean.
-func defaultDebug() bool {
-	return setDefaultBool("BURROW_CLIENT_DEBUG", false)
-}
-
-// setDefaultBool returns the provided default value if the environment variable
-// is not set or not parsable as a bool.
-func setDefaultBool(environmentVariable string, defaultValue bool) bool {
-	value := os.Getenv(environmentVariable)
-	if value != "" {
-		if parsedValue, err := strconv.ParseBool(value); err == nil {
-			return parsedValue
-		}
-	}
-	return defaultValue
-}
-
-func setDefaultString(envVar, def string) string {
-	env := os.Getenv(envVar)
-	if env != "" {
-		return env
-	}
-	return def
-}
diff --git a/client/cmd/burrow-client/main.go b/client/cmd/burrow-client/main.go
deleted file mode 100644
index dc79298a937e5e1080a3d4515746db46cd02c207..0000000000000000000000000000000000000000
--- a/client/cmd/burrow-client/main.go
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright 2017 Monax Industries Limited
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//    http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package main
-
-import (
-	commands "github.com/hyperledger/burrow/client/cmd"
-)
-
-func main() {
-	commands.Execute()
-}
diff --git a/client/cmd/status.go b/client/cmd/status.go
deleted file mode 100644
index 555e9428d8214eb2a0c5b30a4e35ad041bf629e5..0000000000000000000000000000000000000000
--- a/client/cmd/status.go
+++ /dev/null
@@ -1,48 +0,0 @@
-// Copyright 2017 Monax Industries Limited
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//    http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package commands
-
-import (
-	"github.com/spf13/cobra"
-
-	"github.com/hyperledger/burrow/client/methods"
-	"github.com/hyperledger/burrow/util"
-)
-
-func buildStatusCommand() *cobra.Command {
-	statusCmd := &cobra.Command{
-		Use:   "status",
-		Short: "burrow-client status returns the current status from a chain.",
-		Long: `burrow-client status returns the current status from a chain.
-`,
-		Run: func(cmd *cobra.Command, args []string) {
-			err := methods.Status(clientDo)
-			if err != nil {
-				util.Fatalf("Could not get status: %s", err)
-			}
-		},
-	}
-	statusCmd.PersistentFlags().StringVarP(&clientDo.NodeAddrFlag, "node-addr", "", defaultNodeRpcAddress(), "set the burrow node rpc server address (default respects $BURROW_CLIENT_NODE_ADDRESS)")
-	// TransactionCmd.PersistentFlags().StringVarP(&clientDo.PubkeyFlag, "pubkey", "", defaultPublicKey(), "specify the public key to sign with (defaults to $BURROW_CLIENT_PUBLIC_KEY)")
-	// TransactionCmd.PersistentFlags().StringVarP(&clientDo.AddrFlag, "addr", "", defaultAddress(), "specify the account address (for which the public key can be found at monax-keys) (default respects $BURROW_CLIENT_ADDRESS)")
-	// TransactionCmd.PersistentFlags().StringVarP(&clientDo.ChainidFlag, "chain-id", "", defaultChainId(), "specify the chainID (default respects $CHAIN_ID)")
-	// TransactionCmd.PersistentFlags().StringVarP(&clientDo.NonceFlag, "sequence", "", "", "specify the sequence to use for the transaction (should equal the sender account's sequence + 1)")
-
-	// // TransactionCmd.PersistentFlags().BoolVarP(&clientDo.SignFlag, "sign", "s", false, "sign the transaction using the monax-keys daemon")
-	// TransactionCmd.PersistentFlags().BoolVarP(&clientDo.BroadcastFlag, "broadcast", "b", true, "broadcast the transaction to the blockchain")
-	// TransactionCmd.PersistentFlags().BoolVarP(&clientDo.WaitFlag, "wait", "w", false, "wait for the transaction to be committed in a block")
-
-	return statusCmd
-}
diff --git a/client/cmd/transaction.go b/client/cmd/transaction.go
deleted file mode 100644
index a5a1c0ac1ad231de5d1c823a3ebd0888fc79b938..0000000000000000000000000000000000000000
--- a/client/cmd/transaction.go
+++ /dev/null
@@ -1,192 +0,0 @@
-// Copyright 2017 Monax Industries Limited
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//    http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package commands
-
-import (
-	"strings"
-
-	"github.com/spf13/cobra"
-
-	"github.com/hyperledger/burrow/client/methods"
-	"github.com/hyperledger/burrow/util"
-)
-
-func buildTransactionCommand() *cobra.Command {
-	// Transaction command has subcommands send, name, call, bond,
-	// unbond, rebond, permissions.
-	transactionCmd := &cobra.Command{
-		Use:   "tx",
-		Short: "burrow-client tx formulates and signs a transaction to a chain",
-		Long:  "burrow-client tx formulates and signs a transaction to a chain.",
-		Run:   func(cmd *cobra.Command, args []string) { cmd.Help() },
-	}
-
-	addTransactionPersistentFlags(transactionCmd)
-
-	// SendTx
-	sendCmd := &cobra.Command{
-		Use:   "send",
-		Short: "burrow-client tx send --amt <amt> --to <addr>",
-		Long:  "burrow-client tx send --amt <amt> --to <addr>",
-		Run: func(cmd *cobra.Command, args []string) {
-			err := methods.Send(clientDo)
-			if err != nil {
-				util.Fatalf("Could not complete send: %s", err)
-			}
-		},
-		PreRun: assertParameters,
-	}
-	sendCmd.Flags().StringVarP(&clientDo.AmtFlag, "amt", "a", "", "specify an amount")
-	sendCmd.Flags().StringVarP(&clientDo.ToFlag, "to", "t", "", "specify an address to send to")
-
-	// NameTx
-	nameCmd := &cobra.Command{
-		Use:   "name",
-		Short: "burrow-client tx name --amt <amt> --name <name> --data <data>",
-		Long:  "burrow-client tx name --amt <amt> --name <name> --data <data>",
-		Run: func(cmd *cobra.Command, args []string) {
-			// transaction.Name(clientDo)
-		},
-		PreRun: assertParameters,
-	}
-	nameCmd.Flags().StringVarP(&clientDo.AmtFlag, "amt", "a", "", "specify an amount")
-	nameCmd.Flags().StringVarP(&clientDo.NameFlag, "name", "n", "", "specify a name")
-	nameCmd.Flags().StringVarP(&clientDo.DataFlag, "data", "", "", "specify some data")
-	nameCmd.Flags().StringVarP(&clientDo.DataFileFlag, "data-file", "", "", "specify a file with some data")
-	nameCmd.Flags().StringVarP(&clientDo.FeeFlag, "fee", "f", "", "specify the fee to send")
-
-	// CallTx
-	callCmd := &cobra.Command{
-		Use:   "call",
-		Short: "burrow-client tx call --amt <amt> --fee <fee> --gas <gas> --to <contract addr> --data <data>",
-		Long:  "burrow-client tx call --amt <amt> --fee <fee> --gas <gas> --to <contract addr> --data <data>",
-		Run: func(cmd *cobra.Command, args []string) {
-			err := methods.Call(clientDo)
-			if err != nil {
-				util.Fatalf("Could not complete call: %s", err)
-			}
-		},
-		PreRun: assertParameters,
-	}
-	callCmd.Flags().StringVarP(&clientDo.AmtFlag, "amt", "a", "", "specify an amount")
-	callCmd.Flags().StringVarP(&clientDo.ToFlag, "to", "t", "", "specify an address to send to")
-	callCmd.Flags().StringVarP(&clientDo.DataFlag, "data", "", "", "specify some data")
-	callCmd.Flags().StringVarP(&clientDo.FeeFlag, "fee", "f", "", "specify the fee to send")
-	callCmd.Flags().StringVarP(&clientDo.GasFlag, "gas", "g", "", "specify the gas limit for a CallTx")
-
-	// BondTx
-	bondCmd := &cobra.Command{
-		Use:   "bond",
-		Short: "burrow-client tx bond --pubkey <pubkey> --amt <amt> --unbond-to <address>",
-		Long:  "burrow-client tx bond --pubkey <pubkey> --amt <amt> --unbond-to <address>",
-		Run: func(cmd *cobra.Command, args []string) {
-			// transaction.Bond(clientDo)
-		},
-		PreRun: assertParameters,
-	}
-	bondCmd.Flags().StringVarP(&clientDo.AmtFlag, "amt", "a", "", "specify an amount")
-	bondCmd.Flags().StringVarP(&clientDo.UnbondtoFlag, "to", "t", "", "specify an address to unbond to")
-
-	// UnbondTx
-	unbondCmd := &cobra.Command{
-		Use:   "unbond",
-		Short: "burrow-client tx unbond --addr <address> --height <block_height>",
-		Long:  "burrow-client tx unbond --addr <address> --height <block_height>",
-		Run: func(cmd *cobra.Command, args []string) {
-			// transaction.Unbond(clientDo)
-		},
-		PreRun: assertParameters,
-	}
-	unbondCmd.Flags().StringVarP(&clientDo.AddrFlag, "addr", "a", "", "specify an address")
-	unbondCmd.Flags().StringVarP(&clientDo.HeightFlag, "height", "n", "", "specify a height to unbond at")
-
-	// RebondTx
-	var rebondCmd = &cobra.Command{
-		Use:   "rebond",
-		Short: "burrow-client tx rebond --addr <address> --height <block_height>",
-		Long:  "burrow-client tx rebond --addr <address> --height <block_height>",
-		Run: func(cmd *cobra.Command, args []string) {
-			// transaction.Rebond(clientDo)
-		},
-		PreRun: assertParameters,
-	}
-	rebondCmd.Flags().StringVarP(&clientDo.AddrFlag, "addr", "a", "", "specify an address")
-	rebondCmd.Flags().StringVarP(&clientDo.HeightFlag, "height", "n", "", "specify a height to unbond at")
-
-	// PermissionsTx
-	permissionsCmd := &cobra.Command{
-		Use:   "permission",
-		Short: "burrow-client tx perm <function name> <args ...>",
-		Long:  "burrow-client tx perm <function name> <args ...>",
-		Run: func(cmd *cobra.Command, args []string) {
-			// transaction.Permsissions(clientDo)
-		},
-		PreRun: assertParameters,
-	}
-
-	transactionCmd.AddCommand(sendCmd, nameCmd, callCmd, bondCmd, unbondCmd, rebondCmd, permissionsCmd)
-	return transactionCmd
-}
-
-func addTransactionPersistentFlags(transactionCmd *cobra.Command) {
-	transactionCmd.PersistentFlags().StringVarP(&clientDo.SignAddrFlag, "sign-addr", "", defaultKeyDaemonAddress(), "set monax-keys daemon address (default respects $BURROW_CLIENT_SIGN_ADDRESS)")
-	transactionCmd.PersistentFlags().StringVarP(&clientDo.NodeAddrFlag, "node-addr", "", defaultNodeRpcAddress(), "set the burrow node rpc server address (default respects $BURROW_CLIENT_NODE_ADDRESS)")
-	transactionCmd.PersistentFlags().StringVarP(&clientDo.PubkeyFlag, "pubkey", "", defaultPublicKey(), "specify the public key to sign with (defaults to $BURROW_CLIENT_PUBLIC_KEY)")
-	transactionCmd.PersistentFlags().StringVarP(&clientDo.AddrFlag, "addr", "", defaultAddress(), "specify the account address (for which the public key can be found at monax-keys) (default respects $BURROW_CLIENT_ADDRESS)")
-	transactionCmd.PersistentFlags().StringVarP(&clientDo.NonceFlag, "sequence", "", "", "specify the sequence to use for the transaction (should equal the sender account's sequence + 1)")
-
-	// transactionCmd.PersistentFlags().BoolVarP(&clientDo.SignFlag, "sign", "s", false, "sign the transaction using the monax-keys daemon")
-	transactionCmd.PersistentFlags().BoolVarP(&clientDo.BroadcastFlag, "broadcast", "b", true, "broadcast the transaction to the blockchain")
-	transactionCmd.PersistentFlags().BoolVarP(&clientDo.WaitFlag, "wait", "w", true, "wait for the transaction to be committed in a block")
-}
-
-//------------------------------------------------------------------------------
-// Defaults
-
-func defaultKeyDaemonAddress() string {
-	return setDefaultString("BURROW_CLIENT_SIGN_ADDRESS", "http://127.0.0.1:4767")
-}
-
-func defaultNodeRpcAddress() string {
-	return setDefaultString("BURROW_CLIENT_NODE_ADDRESS", "tcp://127.0.0.1:46657")
-}
-
-func defaultPublicKey() string {
-	return setDefaultString("BURROW_CLIENT_PUBLIC_KEY", "")
-}
-
-func defaultAddress() string {
-	return setDefaultString("BURROW_CLIENT_ADDRESS", "")
-}
-
-//------------------------------------------------------------------------------
-// Helper functions
-
-func assertParameters(cmd *cobra.Command, args []string) {
-	if !strings.HasPrefix(clientDo.NodeAddrFlag, "tcp://") &&
-		!strings.HasPrefix(clientDo.NodeAddrFlag, "unix://") {
-		// TODO: [ben] go-rpc will deprecate reformatting; also it is bad practice to auto-correct for this;
-		// TODO: [Silas] I've made this fatal, but I'm inclined to define the default as tcp:// and normalise as with http
-		// below
-		util.Fatalf(`Please use fully formed listening address for the node, including the tcp:// or unix:// prefix.`)
-	}
-
-	if !strings.HasPrefix(clientDo.SignAddrFlag, "http://") {
-		// NOTE: [ben] we preserve the auto-correction here as it is a simple http request-response to the key server.
-		// TODO: [Silas] we don't have logging here to log that we've done this. I'm inclined to either urls without a scheme
-		// and be quiet about it, or to make non-compliance fatal
-		clientDo.SignAddrFlag = "http://" + clientDo.SignAddrFlag
-	}
-}
diff --git a/client/methods/call.go b/client/methods/call.go
deleted file mode 100644
index 16655803f15bf4e7c1eaf8f8fcb936f756853cbc..0000000000000000000000000000000000000000
--- a/client/methods/call.go
+++ /dev/null
@@ -1,60 +0,0 @@
-// Copyright 2017 Monax Industries Limited
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//    http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package methods
-
-import (
-	"fmt"
-
-	"github.com/hyperledger/burrow/client"
-	"github.com/hyperledger/burrow/client/rpc"
-	"github.com/hyperledger/burrow/keys"
-	"github.com/hyperledger/burrow/txs"
-)
-
-func Call(do *client.Do) error {
-	// construct two clients to call out to keys server and
-	// blockchain node.
-	logger, err := loggerFromClientDo(do, "Call")
-	if err != nil {
-		return fmt.Errorf("Could not generate logging config from Do: %s", err)
-	}
-	burrowKeyClient, err := keys.NewRemoteKeyClient(do.SignAddrFlag, logger)
-	if err != nil {
-		return fmt.Errorf("Could not create remote key client: %s", err)
-	}
-	burrowNodeClient := client.NewBurrowNodeClient(do.NodeAddrFlag, logger)
-	// form the call transaction
-	callTransaction, err := rpc.Call(burrowNodeClient, burrowKeyClient,
-		do.PubkeyFlag, do.AddrFlag, do.ToFlag, do.AmtFlag, do.NonceFlag,
-		do.GasFlag, do.FeeFlag, do.DataFlag)
-	if err != nil {
-		return fmt.Errorf("Failed on forming Call Transaction: %s", err)
-	}
-	_, chainID, _, err := burrowNodeClient.ChainId()
-	if err != nil {
-		return err
-	}
-	// TODO: [ben] we carry over the sign bool, but always set it to true,
-	// as we move away from and deprecate the api that allows sending unsigned
-	// transactions and relying on (our) receiving node to sign it.
-	txResult, err := rpc.SignAndBroadcast(burrowNodeClient, burrowKeyClient,
-		txs.Enclose(chainID, callTransaction), true, do.BroadcastFlag, do.WaitFlag)
-
-	if err != nil {
-		return fmt.Errorf("Failed on signing (and broadcasting) transaction: %s", err)
-	}
-	unpackSignAndBroadcast(txResult, logger)
-	return nil
-}
diff --git a/client/methods/helpers.go b/client/methods/helpers.go
deleted file mode 100644
index 6fbf1f46ebc2b2d3c863193f6c5312d4e270d777..0000000000000000000000000000000000000000
--- a/client/methods/helpers.go
+++ /dev/null
@@ -1,55 +0,0 @@
-// Copyright 2017 Monax Industries Limited
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//    http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package methods
-
-import (
-	"github.com/hyperledger/burrow/client"
-	"github.com/hyperledger/burrow/client/rpc"
-	"github.com/hyperledger/burrow/logging"
-	"github.com/hyperledger/burrow/logging/config"
-	"github.com/hyperledger/burrow/logging/lifecycle"
-)
-
-func unpackSignAndBroadcast(result *rpc.TxResult, logger *logging.Logger) {
-	if result == nil {
-		// if we don't provide --sign or --broadcast
-		return
-	}
-
-	logger = logger.With("transaction hash", result.Hash)
-
-	if result.Address != nil {
-		logger = logger.With("Contract Address", result.Address)
-	}
-
-	if result.Return != nil {
-		logger = logger.With("Block Hash", result.BlockHash,
-			"Return Value", result.Return,
-			"Exception", result.Exception,
-		)
-	}
-
-	logger.InfoMsg("SignAndBroadcast result")
-}
-
-func loggerFromClientDo(do *client.Do, scope string) (*logging.Logger, error) {
-	logger, err := lifecycle.NewLoggerFromLoggingConfig(config.DefaultClientLoggingConfig())
-	if err != nil {
-		return nil, err
-	}
-	logger = logger.WithScope(scope)
-	lifecycle.CaptureStdlibLogOutput(logger)
-	return logger, nil
-}
diff --git a/client/methods/send.go b/client/methods/send.go
deleted file mode 100644
index 6ce809721629d4c7e87b6f62dec578f51d6609c7..0000000000000000000000000000000000000000
--- a/client/methods/send.go
+++ /dev/null
@@ -1,58 +0,0 @@
-// Copyright 2017 Monax Industries Limited
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//    http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package methods
-
-import (
-	"fmt"
-
-	"github.com/hyperledger/burrow/client"
-	"github.com/hyperledger/burrow/client/rpc"
-	"github.com/hyperledger/burrow/keys"
-	"github.com/hyperledger/burrow/txs"
-)
-
-func Send(do *client.Do) error {
-	// construct two clients to call out to keys server and
-	// blockchain node.
-	logger, err := loggerFromClientDo(do, "Send")
-	if err != nil {
-		return fmt.Errorf("Could not generate logging config from Do: %s", err)
-	}
-	burrowKeyClient, err := keys.NewRemoteKeyClient(do.SignAddrFlag, logger)
-	if err != nil {
-		return fmt.Errorf("Could not create remote key client: %s", err)
-	}
-	burrowNodeClient := client.NewBurrowNodeClient(do.NodeAddrFlag, logger)
-	// form the send transaction
-	sendTransaction, err := rpc.Send(burrowNodeClient, burrowKeyClient,
-		do.PubkeyFlag, do.AddrFlag, do.ToFlag, do.AmtFlag, do.NonceFlag)
-	if err != nil {
-		fmt.Errorf("Failed on forming Send Transaction: %s", err)
-	}
-	_, chainID, _, err := burrowNodeClient.ChainId()
-	if err != nil {
-		return err
-	}
-	// TODO: [ben] we carry over the sign bool, but always set it to true,
-	// as we move away from and deprecate the api that allows sending unsigned
-	// transactions and relying on (our) receiving node to sign it.
-	txResult, err := rpc.SignAndBroadcast(burrowNodeClient, burrowKeyClient,
-		txs.Enclose(chainID, sendTransaction), true, do.BroadcastFlag, do.WaitFlag)
-	if err != nil {
-		return fmt.Errorf("Failed on signing (and broadcasting) transaction: %s", err)
-	}
-	unpackSignAndBroadcast(txResult, logger)
-	return nil
-}
diff --git a/client/methods/status.go b/client/methods/status.go
deleted file mode 100644
index 7487fdf19bafecda67104aad6a7d4b871ec8f080..0000000000000000000000000000000000000000
--- a/client/methods/status.go
+++ /dev/null
@@ -1,50 +0,0 @@
-// Copyright 2017 Monax Industries Limited
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//    http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package methods
-
-import (
-	"fmt"
-
-	"github.com/hyperledger/burrow/client"
-)
-
-func Status(do *client.Do) error {
-	logger, err := loggerFromClientDo(do, "Status")
-	if err != nil {
-		return fmt.Errorf("Could not generate logging config from Do: %s", err)
-	}
-	burrowNodeClient := client.NewBurrowNodeClient(do.NodeAddrFlag, logger)
-	genesisHash, validatorPublicKey, latestBlockHash, latestBlockHeight, latestBlockTime, err := burrowNodeClient.Status()
-	if err != nil {
-		return fmt.Errorf("Error requesting status from chain at (%s): %s", do.NodeAddrFlag, err)
-	}
-
-	chainName, chainId, genesisHashfromChainId, err := burrowNodeClient.ChainId()
-	if err != nil {
-		return fmt.Errorf("Error requesting chainId from chain at (%s): %s", do.NodeAddrFlag, err)
-	}
-
-	logger.Info.Log("chain", do.NodeAddrFlag,
-		"genesisHash", fmt.Sprintf("%X", genesisHash),
-		"chainName", chainName,
-		"chainId", chainId,
-		"genesisHash from chainId", fmt.Sprintf("%X", genesisHashfromChainId),
-		"validator public key", fmt.Sprintf("%X", validatorPublicKey),
-		"latest block hash", fmt.Sprintf("%X", latestBlockHash),
-		"latest block height", latestBlockHeight,
-		"latest block time", latestBlockTime,
-	)
-	return nil
-}
diff --git a/client/mock/client_mock.go b/client/mock/client_mock.go
deleted file mode 100644
index 2231661225556c619474ea9f2e607f51d6784d1b..0000000000000000000000000000000000000000
--- a/client/mock/client_mock.go
+++ /dev/null
@@ -1,103 +0,0 @@
-// Copyright 2017 Monax Industries Limited
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//    http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package mock
-
-import (
-	acm "github.com/hyperledger/burrow/account"
-	. "github.com/hyperledger/burrow/client"
-	"github.com/hyperledger/burrow/crypto"
-	"github.com/hyperledger/burrow/logging"
-	"github.com/hyperledger/burrow/rpc"
-	"github.com/hyperledger/burrow/txs"
-)
-
-var _ NodeClient = (*MockNodeClient)(nil)
-
-type MockNodeClient struct {
-	accounts map[string]*acm.ConcreteAccount
-}
-
-func NewMockNodeClient() *MockNodeClient {
-	return &MockNodeClient{
-		accounts: make(map[string]*acm.ConcreteAccount),
-	}
-}
-
-func (mock *MockNodeClient) Broadcast(txEnv *txs.Envelope) (*txs.Receipt, error) {
-	// make zero transaction receipt
-	txReceipt := &txs.Receipt{
-		TxHash:          make([]byte, 20),
-		CreatesContract: false,
-	}
-	return txReceipt, nil
-}
-
-func (mock *MockNodeClient) DeriveWebsocketClient() (nodeWsClient NodeWebsocketClient, err error) {
-	return nil, nil
-}
-
-func (mock *MockNodeClient) GetAccount(address crypto.Address) (acm.Account, error) {
-	// make zero account
-	return acm.FromAddressable(acm.GeneratePrivateAccountFromSecret("mock-node-client-account")), nil
-}
-
-func (mock *MockNodeClient) MockAddAccount(account *acm.ConcreteAccount) {
-	addressString := string(account.Address[:])
-	mock.accounts[addressString] = account.Copy()
-}
-
-func (mock *MockNodeClient) Status() (ChainId []byte, ValidatorPublicKey []byte, LatestBlockHash []byte,
-	BlockHeight uint64, LatestBlockTime int64, err error) {
-	// fill return values
-	ChainId = make([]byte, 64)
-	LatestBlockHash = make([]byte, 64)
-	BlockHeight = 0
-	LatestBlockTime = 0
-	return
-}
-
-// QueryContract executes the contract code at address with the given data
-func (mock *MockNodeClient) QueryContract(callerAddress, calleeAddress crypto.Address,
-	data []byte) (ret []byte, gasUsed uint64, err error) {
-
-	// return zero
-	ret = make([]byte, 0)
-	return
-}
-
-// QueryContractCode executes the contract code at address with the given data but with provided code
-func (mock *MockNodeClient) QueryContractCode(address crypto.Address, code,
-	data []byte) (ret []byte, gasUsed uint64, err error) {
-	// return zero
-	ret = make([]byte, 0)
-	return
-}
-
-func (mock *MockNodeClient) DumpStorage(address crypto.Address) (storage *rpc.ResultDumpStorage, err error) {
-	return
-}
-
-func (mock *MockNodeClient) GetName(name string) (owner crypto.Address, data string, expirationBlock uint64, err error) {
-	return
-}
-
-func (mock *MockNodeClient) ListValidators() (blockHeight uint64, bondedValidators,
-	unbondingValidators []acm.Validator, err error) {
-	return
-}
-
-func (mock *MockNodeClient) Logger() *logging.Logger {
-	return logging.NewNoopLogger()
-}
diff --git a/client/node_client.go b/client/node_client.go
deleted file mode 100644
index 8c3464cf09088211428a4383d6197a33f4a349cb..0000000000000000000000000000000000000000
--- a/client/node_client.go
+++ /dev/null
@@ -1,264 +0,0 @@
-// Copyright 2017 Monax Industries Limited
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//    http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package client
-
-import (
-	"fmt"
-
-	acm "github.com/hyperledger/burrow/account"
-	"github.com/hyperledger/burrow/crypto"
-	"github.com/hyperledger/burrow/logging"
-	"github.com/hyperledger/burrow/rpc"
-	rpcClient "github.com/hyperledger/burrow/rpc/lib/client"
-	tmClient "github.com/hyperledger/burrow/rpc/tm/client"
-	"github.com/hyperledger/burrow/txs"
-)
-
-type NodeClient interface {
-	Broadcast(transaction *txs.Envelope) (*txs.Receipt, error)
-	DeriveWebsocketClient() (nodeWsClient NodeWebsocketClient, err error)
-
-	Status() (ChainId []byte, ValidatorPublicKey []byte, LatestBlockHash []byte,
-		LatestBlockHeight uint64, LatestBlockTime int64, err error)
-	GetAccount(address crypto.Address) (acm.Account, error)
-	QueryContract(callerAddress, calleeAddress crypto.Address, data []byte) (ret []byte, gasUsed uint64, err error)
-	QueryContractCode(address crypto.Address, code, data []byte) (ret []byte, gasUsed uint64, err error)
-
-	DumpStorage(address crypto.Address) (storage *rpc.ResultDumpStorage, err error)
-	GetName(name string) (owner crypto.Address, data string, expirationBlock uint64, err error)
-	ListValidators() (blockHeight uint64, bondedValidators, unbondingValidators []acm.Validator, err error)
-
-	// Logging context for this NodeClient
-	Logger() *logging.Logger
-}
-
-type NodeWebsocketClient interface {
-	Subscribe(eventId string) error
-	Unsubscribe(eventId string) error
-	WaitForConfirmation(tx *txs.Envelope, inputAddr crypto.Address) (chan Confirmation, error)
-	Close()
-}
-
-// NOTE [ben] Compiler check to ensure burrowNodeClient successfully implements
-// burrow/client.NodeClient
-var _ NodeClient = (*burrowNodeClient)(nil)
-
-// burrow-client is a simple struct exposing the client rpc methods
-type burrowNodeClient struct {
-	broadcastRPC string
-	logger       *logging.Logger
-}
-
-// BurrowKeyClient.New returns a new monax-keys client for provided rpc location
-// Monax-keys connects over http request-responses
-func NewBurrowNodeClient(rpcString string, logger *logging.Logger) *burrowNodeClient {
-	return &burrowNodeClient{
-		broadcastRPC: rpcString,
-		logger:       logger.WithScope("BurrowNodeClient"),
-	}
-}
-
-//------------------------------------------------------------------------------------
-// broadcast to blockchain node
-
-func (burrowNodeClient *burrowNodeClient) Broadcast(txEnv *txs.Envelope) (*txs.Receipt, error) {
-	client := rpcClient.NewURIClient(burrowNodeClient.broadcastRPC)
-	receipt, err := tmClient.BroadcastTx(client, txEnv)
-	if err != nil {
-		return nil, err
-	}
-	return receipt, nil
-}
-
-func (burrowNodeClient *burrowNodeClient) DeriveWebsocketClient() (nodeWsClient NodeWebsocketClient, err error) {
-	var wsAddr string
-	// TODO: clean up this inherited mess on dealing with the address prefixes.
-	nodeAddr := burrowNodeClient.broadcastRPC
-	// if strings.HasPrefix(nodeAddr, "http://") {
-	// 	wsAddr = strings.TrimPrefix(nodeAddr, "http://")
-	// }
-	// if strings.HasPrefix(nodeAddr, "tcp://") {
-	// 	wsAddr = strings.TrimPrefix(nodeAddr, "tcp://")
-	// }
-	// if strings.HasPrefix(nodeAddr, "unix://") {
-	// 	log.WithFields(log.Fields{
-	// 		"node address": nodeAddr,
-	// 	}).Error("Unable to subscribe to websocket from unix socket.")
-	// 	return nil, fmt.Errorf("Unable to construct websocket from unix socket: %s", nodeAddr)
-	// }
-	// wsAddr = "ws://" + wsAddr
-	wsAddr = nodeAddr
-	burrowNodeClient.logger.TraceMsg("Subscribing to websocket address",
-		"websocket address", wsAddr,
-		"endpoint", "/websocket",
-	)
-	wsClient := rpcClient.NewWSClient(wsAddr, "/websocket")
-	if err = wsClient.Start(); err != nil {
-		return nil, err
-	}
-	derivedBurrowNodeWebsocketClient := &burrowNodeWebsocketClient{
-		tendermintWebsocket: wsClient,
-		logger:              burrowNodeClient.logger.WithScope("BurrowNodeWebsocketClient"),
-	}
-	return derivedBurrowNodeWebsocketClient, nil
-}
-
-//------------------------------------------------------------------------------------
-// RPC requests other than transaction related
-
-// Status returns the ChainId (GenesisHash), validator's PublicKey, latest block hash
-// the block height and the latest block time.
-func (burrowNodeClient *burrowNodeClient) Status() (GenesisHash []byte, ValidatorPublicKey []byte,
-	LatestBlockHash []byte, LatestBlockHeight uint64, LatestBlockTime int64, err error) {
-
-	client := rpcClient.NewJSONRPCClient(burrowNodeClient.broadcastRPC)
-	res, err := tmClient.Status(client)
-	if err != nil {
-		err = fmt.Errorf("error connecting to node (%s) to get status: %s",
-			burrowNodeClient.broadcastRPC, err.Error())
-		return
-	}
-
-	// unwrap return results
-	GenesisHash = res.GenesisHash
-	ValidatorPublicKey = res.PubKey.RawBytes()
-	LatestBlockHash = res.LatestBlockHash
-	LatestBlockHeight = res.LatestBlockHeight
-	LatestBlockTime = res.LatestBlockTime
-	return
-}
-
-func (burrowNodeClient *burrowNodeClient) ChainId() (ChainName, ChainId string, GenesisHash []byte, err error) {
-	client := rpcClient.NewJSONRPCClient(burrowNodeClient.broadcastRPC)
-	chainIdResult, err := tmClient.ChainId(client)
-	if err != nil {
-		err = fmt.Errorf("error connecting to node (%s) to get chain id: %s",
-			burrowNodeClient.broadcastRPC, err.Error())
-		return "", "", nil, err
-	}
-	// unwrap results
-	ChainName = chainIdResult.ChainName
-	ChainId = chainIdResult.ChainId
-	GenesisHash = make([]byte, len(chainIdResult.GenesisHash))
-	copy(GenesisHash[:], chainIdResult.GenesisHash)
-	return
-}
-
-// QueryContract executes the contract code at address with the given data
-// NOTE: there is no check on the caller;
-func (burrowNodeClient *burrowNodeClient) QueryContract(callerAddress, calleeAddress crypto.Address,
-	data []byte) (ret []byte, gasUsed uint64, err error) {
-
-	client := rpcClient.NewJSONRPCClient(burrowNodeClient.broadcastRPC)
-	callResult, err := tmClient.Call(client, callerAddress, calleeAddress, data)
-	if err != nil {
-		err = fmt.Errorf("error (%v) connnecting to node (%s) to query contract at (%s) with data (%X)",
-			err.Error(), burrowNodeClient.broadcastRPC, calleeAddress, data)
-		return
-	}
-	return callResult.Return, callResult.GasUsed, nil
-}
-
-// QueryContractCode executes the contract code at address with the given data but with provided code
-func (burrowNodeClient *burrowNodeClient) QueryContractCode(address crypto.Address, code,
-	data []byte) (ret []byte, gasUsed uint64, err error) {
-
-	client := rpcClient.NewJSONRPCClient(burrowNodeClient.broadcastRPC)
-	// TODO: [ben] Call and CallCode have an inconsistent signature; it makes sense for both to only
-	// have a single address that is the contract to query.
-	callResult, err := tmClient.CallCode(client, address, code, data)
-	if err != nil {
-		err = fmt.Errorf("error connnecting to node (%s) to query contract code at (%s) with data (%X) and code (%X): %v",
-			burrowNodeClient.broadcastRPC, address, data, code, err.Error())
-		return nil, uint64(0), err
-	}
-	return callResult.Return, callResult.GasUsed, nil
-}
-
-// GetAccount returns a copy of the account
-func (burrowNodeClient *burrowNodeClient) GetAccount(address crypto.Address) (acm.Account, error) {
-	client := rpcClient.NewJSONRPCClient(burrowNodeClient.broadcastRPC)
-	account, err := tmClient.GetAccount(client, address)
-	if err != nil {
-		err = fmt.Errorf("error connecting to node (%s) to fetch account (%s): %s",
-			burrowNodeClient.broadcastRPC, address, err.Error())
-		return nil, err
-	}
-	if account == nil {
-		err = fmt.Errorf("unknown account %s at node (%s)", address, burrowNodeClient.broadcastRPC)
-		return nil, err
-	}
-
-	return account, nil
-}
-
-// DumpStorage returns the full storage for an acm.
-func (burrowNodeClient *burrowNodeClient) DumpStorage(address crypto.Address) (*rpc.ResultDumpStorage, error) {
-	client := rpcClient.NewJSONRPCClient(burrowNodeClient.broadcastRPC)
-	resultStorage, err := tmClient.DumpStorage(client, address)
-	if err != nil {
-		return nil, fmt.Errorf("error connecting to node (%s) to get storage for account (%X): %s",
-			burrowNodeClient.broadcastRPC, address, err.Error())
-	}
-	return resultStorage, nil
-}
-
-//--------------------------------------------------------------------------------------------
-// Name registry
-
-func (burrowNodeClient *burrowNodeClient) GetName(name string) (owner crypto.Address, data string,
-	expirationBlock uint64, err error) {
-
-	client := rpcClient.NewJSONRPCClient(burrowNodeClient.broadcastRPC)
-	entryResult, err := tmClient.GetName(client, name)
-	if err != nil {
-		err = fmt.Errorf("error connecting to node (%s) to get name registrar entry for name (%s)",
-			burrowNodeClient.broadcastRPC, name)
-		return crypto.ZeroAddress, "", 0, err
-	}
-	// unwrap return results
-	owner = entryResult.Owner
-	data = entryResult.Data
-	expirationBlock = entryResult.Expires
-	return
-}
-
-//--------------------------------------------------------------------------------------------
-
-func (burrowNodeClient *burrowNodeClient) ListValidators() (blockHeight uint64,
-	bondedValidators, unbondingValidators []acm.Validator, err error) {
-
-	client := rpcClient.NewJSONRPCClient(burrowNodeClient.broadcastRPC)
-	validatorsResult, err := tmClient.ListValidators(client)
-	if err != nil {
-		err = fmt.Errorf("error connecting to node (%s) to get validators", burrowNodeClient.broadcastRPC)
-		return
-	}
-	// unwrap return results
-	blockHeight = validatorsResult.BlockHeight
-	bondedValidators = make([]acm.Validator, len(validatorsResult.BondedValidators))
-	for i, cv := range validatorsResult.BondedValidators {
-		bondedValidators[i] = cv.Validator()
-	}
-	unbondingValidators = make([]acm.Validator, len(validatorsResult.UnbondingValidators))
-	for i, cv := range validatorsResult.UnbondingValidators {
-		unbondingValidators[i] = cv.Validator()
-	}
-	return
-}
-
-func (burrowNodeClient *burrowNodeClient) Logger() *logging.Logger {
-	return burrowNodeClient.logger
-}
diff --git a/client/rpc/client.go b/client/rpc/client.go
deleted file mode 100644
index 9e5364246cc38ae2975b50f2252391db73ae46be..0000000000000000000000000000000000000000
--- a/client/rpc/client.go
+++ /dev/null
@@ -1,307 +0,0 @@
-// Copyright 2017 Monax Industries Limited
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//    http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package rpc
-
-import (
-	"encoding/hex"
-	"fmt"
-	"strconv"
-
-	"github.com/hyperledger/burrow/client"
-	"github.com/hyperledger/burrow/crypto"
-	"github.com/hyperledger/burrow/keys"
-	"github.com/hyperledger/burrow/permission/snatives"
-	ptypes "github.com/hyperledger/burrow/permission/types"
-	"github.com/hyperledger/burrow/txs"
-	"github.com/hyperledger/burrow/txs/payload"
-)
-
-//------------------------------------------------------------------------------------
-// core functions with string args.
-// validates strings and forms transaction
-
-func Send(nodeClient client.NodeClient, keyClient keys.KeyClient, pubkey, addr, toAddr, amtS, sequenceS string) (*payload.SendTx, error) {
-	pub, amt, sequence, err := checkCommon(nodeClient, keyClient, pubkey, addr, amtS, sequenceS)
-	if err != nil {
-		return nil, err
-	}
-
-	if toAddr == "" {
-		return nil, fmt.Errorf("destination address must be given with --to flag")
-	}
-
-	toAddress, err := addressFromHexString(toAddr)
-	if err != nil {
-		return nil, err
-	}
-
-	tx := payload.NewSendTx()
-	tx.AddInputWithSequence(pub, amt, sequence)
-	tx.AddOutput(toAddress, amt)
-
-	return tx, nil
-}
-
-func Call(nodeClient client.NodeClient, keyClient keys.KeyClient, pubkey, addr, toAddr, amtS, sequenceS, gasS, feeS, data string) (*payload.CallTx, error) {
-	pub, amt, sequence, err := checkCommon(nodeClient, keyClient, pubkey, addr, amtS, sequenceS)
-	if err != nil {
-		return nil, err
-	}
-
-	var toAddress *crypto.Address
-
-	if toAddr != "" {
-		address, err := addressFromHexString(toAddr)
-		if err != nil {
-			return nil, fmt.Errorf("toAddr is bad hex: %v", err)
-		}
-		toAddress = &address
-	}
-
-	fee, err := strconv.ParseUint(feeS, 10, 64)
-	if err != nil {
-		return nil, fmt.Errorf("fee is misformatted: %v", err)
-	}
-
-	gas, err := strconv.ParseUint(gasS, 10, 64)
-	if err != nil {
-		return nil, fmt.Errorf("gas is misformatted: %v", err)
-	}
-
-	dataBytes, err := hex.DecodeString(data)
-	if err != nil {
-		return nil, fmt.Errorf("data is bad hex: %v", err)
-	}
-
-	tx := payload.NewCallTxWithSequence(pub, toAddress, dataBytes, amt, gas, fee, sequence)
-	return tx, nil
-}
-
-func Name(nodeClient client.NodeClient, keyClient keys.KeyClient, pubkey, addr, amtS, sequenceS, feeS, name, data string) (*payload.NameTx, error) {
-	pub, amt, sequence, err := checkCommon(nodeClient, keyClient, pubkey, addr, amtS, sequenceS)
-	if err != nil {
-		return nil, err
-	}
-
-	fee, err := strconv.ParseUint(feeS, 10, 64)
-	if err != nil {
-		return nil, fmt.Errorf("fee is misformatted: %v", err)
-	}
-
-	tx := payload.NewNameTxWithSequence(pub, name, data, amt, fee, sequence)
-	return tx, nil
-}
-
-func Permissions(nodeClient client.NodeClient, keyClient keys.KeyClient, pubkey, addrS, sequenceS string,
-	action, target, permissionFlag, role, value string) (*payload.PermissionsTx, error) {
-
-	pub, _, sequence, err := checkCommon(nodeClient, keyClient, pubkey, addrS, "0", sequenceS)
-	if err != nil {
-		return nil, err
-	}
-	permFlag, err := ptypes.PermStringToFlag(action)
-	if err != nil {
-		return nil, fmt.Errorf("could not convert action '%s' to PermFlag: %v", action, err)
-	}
-	permArgs := snatives.PermArgs{
-		PermFlag: permFlag,
-	}
-
-	// Try and set each PermArg field for which a string has been provided we'll validate afterwards
-	if target != "" {
-		address, err := crypto.AddressFromHexString(target)
-		if err != nil {
-			return nil, err
-		}
-		permArgs.Address = &address
-	}
-
-	if value != "" {
-		valueBool := value == "true"
-		permArgs.Value = &valueBool
-		if !valueBool && value != "false" {
-			return nil, fmt.Errorf("did not recognise value %s as boolean, use 'true' or 'false'", value)
-		}
-		permArgs.Value = &valueBool
-	}
-
-	if permissionFlag != "" {
-		permission, err := ptypes.PermStringToFlag(permissionFlag)
-		if err != nil {
-			return nil, err
-		}
-		permArgs.Permission = &permission
-	}
-
-	if role != "" {
-		permArgs.Role = &role
-	}
-
-	err = permArgs.EnsureValid()
-	if err != nil {
-		return nil, err
-	}
-
-	tx := payload.NewPermissionsTxWithSequence(pub, permArgs, sequence)
-	return tx, nil
-}
-
-func Bond(nodeClient client.NodeClient, keyClient keys.KeyClient, pubkey, unbondAddr, amtS, sequenceS string) (*payload.BondTx, error) {
-	return nil, fmt.Errorf("Bond Transaction formation to be implemented on 0.12.0")
-	// pub, amt, sequence, err := checkCommon(nodeAddr, signAddr, pubkey, "", amtS, sequenceS)
-	// if err != nil {
-	// 	return nil, err
-	// }
-	// var pubKey acm.PublicKeyEd25519
-	// var unbondAddrBytes []byte
-
-	// if unbondAddr == "" {
-	// 	pkb, _ := hex.DecodeString(pubkey)
-	// 	copy(pubKey[:], pkb)
-	// 	unbondAddrBytes = pubKey.Address()
-	// } else {
-	// 	unbondAddrBytes, err = hex.DecodeString(unbondAddr)
-	// 	if err != nil {
-	// 		return nil, fmt.Errorf("unbondAddr is bad hex: %v", err)
-	// 	}
-
-	// }
-
-	// tx, err := types.NewBondTx(pub)
-	// if err != nil {
-	// 	return nil, err
-	// }
-	// tx.AddInputWithSequence(pub, amt, int(sequence))
-	// tx.AddOutput(unbondAddrBytes, amt)
-
-	// return tx, nil
-}
-
-func Unbond(addrS, heightS string) (*payload.UnbondTx, error) {
-	return nil, fmt.Errorf("Unbond Transaction formation to be implemented on 0.12.0")
-	// if addrS == "" {
-	// 	return nil, fmt.Errorf("Validator address must be given with --addr flag")
-	// }
-
-	// addrBytes, err := hex.DecodeString(addrS)
-	// if err != nil {
-	// 	return nil, fmt.Errorf("addr is bad hex: %v", err)
-	// }
-
-	// height, err := strconv.ParseInt(heightS, 10, 32)
-	// if err != nil {
-	// 	return nil, fmt.Errorf("height is misformatted: %v", err)
-	// }
-
-	// return &types.UnbondTx{
-	// 	Address: addrBytes,
-	// 	Height:  int(height),
-	// }, nil
-}
-
-type TxResult struct {
-	BlockHash []byte // all txs get in a block
-	Hash      []byte // all txs get a hash
-
-	// only CallTx
-	Address   *crypto.Address // only for new contracts
-	Return    []byte
-	Exception string
-
-	//TODO: make Broadcast() errors more responsive so we
-	// can differentiate mempool errors from other
-}
-
-// Preserve
-func SignAndBroadcast(nodeClient client.NodeClient, keyClient keys.KeyClient, txEnv *txs.Envelope, sign,
-	broadcast, wait bool) (txResult *TxResult, err error) {
-
-	var inputAddr crypto.Address
-	if sign {
-		inputAddr, txEnv, err = signTx(keyClient, txEnv.Tx)
-		if err != nil {
-			return nil, err
-		}
-	}
-
-	if broadcast {
-		if wait {
-			var wsClient client.NodeWebsocketClient
-			wsClient, err = nodeClient.DeriveWebsocketClient()
-			if err != nil {
-				return nil, err
-			}
-			var confirmationChannel chan client.Confirmation
-			confirmationChannel, err = wsClient.WaitForConfirmation(txEnv, inputAddr)
-			if err != nil {
-				return nil, err
-			}
-			defer func() {
-				if err != nil {
-					// if broadcast threw an error, just return
-					return
-				}
-				if txResult == nil {
-					err = fmt.Errorf("txResult unexpectedly not initialised in SignAndBroadcast")
-					return
-				}
-				confirmation := <-confirmationChannel
-				if confirmation.Error != nil {
-					err = fmt.Errorf("encountered error waiting for event: %s", confirmation.Error)
-					return
-				}
-				if confirmation.Exception != nil {
-					err = fmt.Errorf("encountered Exception from chain: %s", confirmation.Exception)
-					return
-				}
-				txResult.BlockHash = confirmation.BlockHash
-				txResult.Exception = ""
-				eventDataTx := confirmation.EventDataTx
-				if eventDataTx == nil {
-					err = fmt.Errorf("EventDataTx was nil")
-					return
-				}
-				txResult.Return = eventDataTx.Return
-			}()
-		}
-
-		var receipt *txs.Receipt
-		receipt, err = nodeClient.Broadcast(txEnv)
-		if err != nil {
-			return nil, err
-		}
-		txResult = &TxResult{
-			Hash: receipt.TxHash,
-		}
-		// NOTE: [ben] is this consistent with the Ethereum protocol?  It should seem
-		// reasonable to get this returned from the chain directly.  Alternatively,
-		// the benefit is that the we don't need to trust the chain node
-		if tx_, ok := txEnv.Tx.Payload.(*payload.CallTx); ok {
-			if tx_.Address == nil {
-				address := crypto.NewContractAddress(tx_.Input.Address, tx_.Input.Sequence)
-				txResult.Address = &address
-			}
-		}
-	}
-	return
-}
-
-func addressFromHexString(addrString string) (crypto.Address, error) {
-	addrBytes, err := hex.DecodeString(addrString)
-	if err != nil {
-		return crypto.Address{}, err
-	}
-	return crypto.AddressFromBytes(addrBytes)
-}
diff --git a/client/rpc/client_test.go b/client/rpc/client_test.go
deleted file mode 100644
index 3a8ebc42d7d11c1f5627b360097dcdd785499d84..0000000000000000000000000000000000000000
--- a/client/rpc/client_test.go
+++ /dev/null
@@ -1,170 +0,0 @@
-// Copyright 2017 Monax Industries Limited
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//    http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package rpc
-
-import (
-	"encoding/json"
-	"fmt"
-	"testing"
-
-	// "github.com/stretchr/testify/assert"
-
-	mockclient "github.com/hyperledger/burrow/client/mock"
-	mockkeys "github.com/hyperledger/burrow/keys/mock"
-	"github.com/stretchr/testify/assert"
-	"github.com/stretchr/testify/require"
-)
-
-func TestSend(t *testing.T) {
-	mockKeyClient := mockkeys.NewKeyClient()
-	mockNodeClient := mockclient.NewMockNodeClient()
-	testSend(t, mockNodeClient, mockKeyClient)
-}
-
-func TestCall(t *testing.T) {
-	mockKeyClient := mockkeys.NewKeyClient()
-	mockNodeClient := mockclient.NewMockNodeClient()
-	testCall(t, mockNodeClient, mockKeyClient)
-}
-
-func TestName(t *testing.T) {
-	mockKeyClient := mockkeys.NewKeyClient()
-	mockNodeClient := mockclient.NewMockNodeClient()
-	testName(t, mockNodeClient, mockKeyClient)
-}
-
-func TestPermissions(t *testing.T) {
-	mockKeyClient := mockkeys.NewKeyClient()
-	mockNodeClient := mockclient.NewMockNodeClient()
-	testPermissions(t, mockNodeClient, mockKeyClient)
-}
-
-func testSend(t *testing.T,
-	nodeClient *mockclient.MockNodeClient, keyClient *mockkeys.KeyClient) {
-
-	// generate an ED25519 key and ripemd160 address
-	addressString := keyClient.NewKey("").String()
-	// Public key can be queried from mockKeyClient.PublicKey(address)
-	// but here we let the transaction factory retrieve the public key
-	// which will then also overwrite the address we provide the function.
-	// As a result we will assert whether address generated above, is identical
-	// to address in generated transation.
-	publicKeyString := ""
-	// generate an additional address to send amount to
-	toAddressString := keyClient.NewKey("").String()
-	// set an amount to transfer
-	amountString := "1000"
-	// unset sequence so that we retrieve sequence from account
-	sequenceString := ""
-
-	_, err := Send(nodeClient, keyClient, publicKeyString, addressString,
-		toAddressString, amountString, sequenceString)
-	require.NoError(t, err, "Error in Send")
-	// assert.NotEqual(t, txSend)
-	// TODO: test content of Transaction
-}
-
-func testCall(t *testing.T,
-	nodeClient *mockclient.MockNodeClient, keyClient *mockkeys.KeyClient) {
-
-	// generate an ED25519 key and ripemd160 address
-	addressString := keyClient.NewKey("").String()
-	// Public key can be queried from mockKeyClient.PublicKey(address)
-	// but here we let the transaction factory retrieve the public key
-	// which will then also overwrite the address we provide the function.
-	// As a result we will assert whether address generated above, is identical
-	// to address in generated transation.
-	publicKeyString := ""
-	// generate an additional address to send amount to
-	toAddressString := keyClient.NewKey("").String()
-	// set an amount to transfer
-	amountString := "1000"
-	// unset sequence so that we retrieve sequence from account
-	sequenceString := ""
-	// set gas
-	gasString := "1000"
-	// set fee
-	feeString := "100"
-	// set data
-	dataString := fmt.Sprintf("%X", "We are DOUG.")
-
-	_, err := Call(nodeClient, keyClient, publicKeyString, addressString,
-		toAddressString, amountString, sequenceString, gasString, feeString, dataString)
-	if err != nil {
-		t.Logf("Error in CallTx: %s", err)
-		t.Fail()
-	}
-	// TODO: test content of Transaction
-}
-
-func testName(t *testing.T,
-	nodeClient *mockclient.MockNodeClient, keyClient *mockkeys.KeyClient) {
-
-	// generate an ED25519 key and ripemd160 address
-	addressString := keyClient.NewKey("").String()
-	// Public key can be queried from mockKeyClient.PublicKey(address)
-	// but here we let the transaction factory retrieve the public key
-	// which will then also overwrite the address we provide the function.
-	// As a result we will assert whether address generated above, is identical
-	// to address in generated transation.
-	publicKeyString := ""
-	// set an amount to transfer
-	amountString := "1000"
-	// unset sequence so that we retrieve sequence from account
-	sequenceString := ""
-	// set fee
-	feeString := "100"
-	// set data
-	dataString := fmt.Sprintf("%X", "We are DOUG.")
-	// set name
-	nameString := "DOUG"
-
-	_, err := Name(nodeClient, keyClient, publicKeyString, addressString,
-		amountString, sequenceString, feeString, nameString, dataString)
-	if err != nil {
-		t.Logf("Error in NameTx: %s", err)
-		t.Fail()
-	}
-	// TODO: test content of Transaction
-}
-
-func testPermissions(t *testing.T,
-	nodeClient *mockclient.MockNodeClient, keyClient *mockkeys.KeyClient) {
-
-	// generate an ED25519 key and ripemd160 address
-	addressString := keyClient.NewKey("").String()
-	// Public key can be queried from mockKeyClient.PublicKey(address)
-	// but here we let the transaction factory retrieve the public key
-	// which will then also overwrite the address we provide the function.
-	// As a result we will assert whether address generated above, is identical
-	// to address in generated transation.
-	publicKeyString := ""
-	// generate an additional address to set permissions for
-	permAddressString := keyClient.NewKey("").String()
-	// unset sequence so that we retrieve sequence from account
-	sequenceString := ""
-
-	tx, err := Permissions(nodeClient, keyClient, publicKeyString, addressString,
-		sequenceString, "setBase", permAddressString, "root", "", "true")
-	if err != nil {
-		t.Logf("Error in PermissionsTx: %s", err)
-		t.Fail()
-	}
-
-	bs, err := json.Marshal(tx.PermArgs)
-	require.NoError(t, err)
-	expected := fmt.Sprintf(`{"PermFlag":256,"Address":"%s","Permission":1,"Value":true}`, permAddressString)
-	assert.Equal(t, expected, string(bs))
-}
diff --git a/client/rpc/client_util.go b/client/rpc/client_util.go
deleted file mode 100644
index d59453a7c2cea259c863962cc69ca311f61e719c..0000000000000000000000000000000000000000
--- a/client/rpc/client_util.go
+++ /dev/null
@@ -1,125 +0,0 @@
-// Copyright 2017 Monax Industries Limited
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//    http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package rpc
-
-import (
-	"encoding/hex"
-	"fmt"
-	"strconv"
-
-	"github.com/hyperledger/burrow/client"
-	"github.com/hyperledger/burrow/crypto"
-	"github.com/hyperledger/burrow/keys"
-	"github.com/hyperledger/burrow/txs"
-)
-
-//------------------------------------------------------------------------------------
-// sign and broadcast convenience
-
-// tx has either one input or we default to the first one (ie for send/bond)
-// TODO: better support for multisig and bonding
-func signTx(keyClient keys.KeyClient, tx *txs.Tx) (crypto.Address, *txs.Envelope, error) {
-	txEnv := tx.Enclose()
-	inputs := tx.GetInputs()
-	signer, err := keys.AddressableSigner(keyClient, inputs[0].Address)
-	if err != nil {
-		return crypto.ZeroAddress, nil, err
-	}
-	err = txEnv.Sign(signer)
-	if err != nil {
-		return crypto.ZeroAddress, nil, err
-	}
-	return signer.Address(), txEnv, nil
-}
-
-func checkCommon(nodeClient client.NodeClient, keyClient keys.KeyClient, pubkey, addr, amtS,
-	sequenceS string) (pub crypto.PublicKey, amt uint64, sequence uint64, err error) {
-
-	if amtS == "" {
-		err = fmt.Errorf("input must specify an amount with the --amt flag")
-		return
-	}
-
-	if pubkey == "" && addr == "" {
-		err = fmt.Errorf("at least one of --pubkey or --addr must be given")
-		return
-	} else if pubkey != "" {
-		if addr != "" {
-			nodeClient.Logger().InfoMsg("Both a public key and an address have been specified. The public key takes precedent.",
-				"public_key", pubkey,
-				"address", addr,
-			)
-		}
-		var pubKeyBytes []byte
-		pubKeyBytes, err = hex.DecodeString(pubkey)
-		if err != nil {
-			err = fmt.Errorf("pubkey is bad hex: %v", err)
-			return
-		}
-		pub, err = crypto.PublicKeyFromBytes(pubKeyBytes, crypto.CurveTypeEd25519)
-		if err != nil {
-			return
-		}
-	} else {
-		// grab the pubkey from monax-keys
-		addressBytes, err2 := hex.DecodeString(addr)
-		if err2 != nil {
-			err = fmt.Errorf("Bad hex string for address (%s): %v", addr, err)
-			return
-		}
-		address, err2 := crypto.AddressFromBytes(addressBytes)
-		if err2 != nil {
-			err = fmt.Errorf("Could not convert bytes (%X) to address: %v", addressBytes, err2)
-		}
-		pub, err2 = keyClient.PublicKey(address)
-		if err2 != nil {
-			err = fmt.Errorf("Failed to fetch pubkey for address (%s): %v", addr, err2)
-			return
-		}
-	}
-
-	var address crypto.Address
-	address = pub.Address()
-
-	amt, err = strconv.ParseUint(amtS, 10, 64)
-	if err != nil {
-		err = fmt.Errorf("amt is misformatted: %v", err)
-	}
-
-	if sequenceS == "" {
-		if nodeClient == nil {
-			err = fmt.Errorf("input must specify a sequence with the --sequence flag or use --node-addr (or BURROW_CLIENT_NODE_ADDR) to fetch the sequence from a node")
-			return
-		}
-		// fetch sequence from node
-		account, err2 := nodeClient.GetAccount(address)
-		if err2 != nil {
-			return pub, amt, sequence, err2
-		}
-		sequence = account.Sequence() + 1
-		nodeClient.Logger().TraceMsg("Fetch sequence from node",
-			"sequence", sequence,
-			"account address", address,
-		)
-	} else {
-		sequence, err = strconv.ParseUint(sequenceS, 10, 64)
-		if err != nil {
-			err = fmt.Errorf("sequence is misformatted: %v", err)
-			return
-		}
-	}
-
-	return
-}
diff --git a/client/websocket_client.go b/client/websocket_client.go
deleted file mode 100644
index 2580dc4bb0096e4241814fe806590727cd7aa342..0000000000000000000000000000000000000000
--- a/client/websocket_client.go
+++ /dev/null
@@ -1,210 +0,0 @@
-// Copyright 2017 Monax Industries Limited
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//    http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package client
-
-import (
-	"bytes"
-	"fmt"
-	"time"
-
-	"encoding/json"
-
-	"github.com/hyperledger/burrow/crypto"
-	"github.com/hyperledger/burrow/execution/errors"
-	exeEvents "github.com/hyperledger/burrow/execution/events"
-	"github.com/hyperledger/burrow/logging"
-	"github.com/hyperledger/burrow/logging/structure"
-	"github.com/hyperledger/burrow/rpc"
-	rpcClient "github.com/hyperledger/burrow/rpc/lib/client"
-	"github.com/hyperledger/burrow/rpc/tm/client"
-	"github.com/hyperledger/burrow/txs"
-	tmTypes "github.com/tendermint/tendermint/types"
-)
-
-const (
-	MaxCommitWaitTimeSeconds = 10
-)
-
-type Confirmation struct {
-	BlockHash   []byte
-	EventDataTx *exeEvents.EventDataTx
-	Exception   error
-	Error       error
-}
-
-// NOTE [ben] Compiler check to ensure burrowNodeClient successfully implements
-// burrow/client.NodeClient
-var _ NodeWebsocketClient = (*burrowNodeWebsocketClient)(nil)
-
-type burrowNodeWebsocketClient struct {
-	// TODO: assert no memory leak on closing with open websocket
-	tendermintWebsocket *rpcClient.WSClient
-	logger              *logging.Logger
-}
-
-// Subscribe to an eventid
-func (burrowNodeWebsocketClient *burrowNodeWebsocketClient) Subscribe(eventId string) error {
-	// TODO we can in the background listen to the subscription id and remember it to ease unsubscribing later.
-	return client.Subscribe(burrowNodeWebsocketClient.tendermintWebsocket,
-		eventId)
-}
-
-// Unsubscribe from an eventid
-func (burrowNodeWebsocketClient *burrowNodeWebsocketClient) Unsubscribe(subscriptionId string) error {
-	return client.Unsubscribe(burrowNodeWebsocketClient.tendermintWebsocket,
-		subscriptionId)
-}
-
-// Returns a channel that will receive a confirmation with a result or the exception that
-// has been confirmed; or an error is returned and the confirmation channel is nil.
-func (burrowNodeWebsocketClient *burrowNodeWebsocketClient) WaitForConfirmation(txEnv *txs.Envelope,
-	inputAddr crypto.Address) (chan Confirmation, error) {
-
-	// Setup the confirmation channel to be returned
-	confirmationChannel := make(chan Confirmation, 1)
-	var latestBlockHash []byte
-
-	eventID := exeEvents.EventStringAccountInput(inputAddr)
-	if err := burrowNodeWebsocketClient.Subscribe(eventID); err != nil {
-		return nil, fmt.Errorf("Error subscribing to AccInput event (%s): %v", eventID, err)
-	}
-	if err := burrowNodeWebsocketClient.Subscribe(tmTypes.EventNewBlock); err != nil {
-		return nil, fmt.Errorf("Error subscribing to NewBlock event: %v", err)
-	}
-	// Read the incoming events
-	go func() {
-		var err error
-
-		timeoutTimer := time.NewTimer(time.Duration(MaxCommitWaitTimeSeconds) * time.Second)
-		defer func() {
-			if !timeoutTimer.Stop() {
-				<-timeoutTimer.C
-			}
-		}()
-
-		for {
-			select {
-			case <-timeoutTimer.C:
-				confirmationChannel <- Confirmation{
-					BlockHash:   nil,
-					EventDataTx: nil,
-					Exception:   nil,
-					Error:       fmt.Errorf("timed out waiting for event"),
-				}
-				return
-
-			case response := <-burrowNodeWebsocketClient.tendermintWebsocket.ResponsesCh:
-				if response.Error != nil {
-					burrowNodeWebsocketClient.logger.InfoMsg(
-						"Error received on websocket channel", structure.ErrorKey, err)
-					continue
-				}
-
-				switch response.ID {
-				case client.SubscribeRequestID:
-					resultSubscribe := new(rpc.ResultSubscribe)
-					err = json.Unmarshal(response.Result, resultSubscribe)
-					if err != nil {
-						burrowNodeWebsocketClient.logger.InfoMsg("Unable to unmarshal ResultSubscribe",
-							structure.ErrorKey, err)
-						continue
-					}
-					// TODO: collect subscription IDs, push into channel and on completion
-					burrowNodeWebsocketClient.logger.InfoMsg("Received confirmation for event",
-						"event", resultSubscribe.EventID,
-						"subscription_id", resultSubscribe.SubscriptionID)
-
-				case client.EventResponseID(tmTypes.EventNewBlock):
-					resultEvent := new(rpc.ResultEvent)
-					err = json.Unmarshal(response.Result, resultEvent)
-					if err != nil {
-						burrowNodeWebsocketClient.logger.InfoMsg("Unable to unmarshal ResultEvent",
-							structure.ErrorKey, err)
-						continue
-					}
-					blockData := resultEvent.Tendermint.EventDataNewBlock()
-					if blockData != nil {
-						latestBlockHash = blockData.Block.Hash()
-						burrowNodeWebsocketClient.logger.TraceMsg("Registered new block",
-							"block", blockData.Block,
-							"latest_block_hash", latestBlockHash,
-						)
-					}
-
-				case client.EventResponseID(eventID):
-					resultEvent := new(rpc.ResultEvent)
-					err = json.Unmarshal(response.Result, resultEvent)
-					if err != nil {
-						burrowNodeWebsocketClient.logger.InfoMsg("Unable to unmarshal ResultEvent",
-							structure.ErrorKey, err)
-						continue
-					}
-
-					eventDataTx := resultEvent.Execution.GetTx()
-					if eventDataTx == nil {
-						// We are on the lookout for EventDataTx
-						confirmationChannel <- Confirmation{
-							BlockHash:   latestBlockHash,
-							EventDataTx: nil,
-							Exception:   fmt.Errorf("response error: expected result.Data to be *types.EventDataTx"),
-							Error:       nil,
-						}
-						return
-					}
-
-					if !bytes.Equal(eventDataTx.Tx.Hash(), txEnv.Tx.Hash()) {
-						burrowNodeWebsocketClient.logger.TraceMsg("Received different event",
-							// TODO: consider re-implementing TxID again, or other more clear debug
-							"received transaction event", eventDataTx.Tx.Hash())
-						continue
-					}
-
-					if eventDataTx.Exception != nil && eventDataTx.Exception.ErrorCode() != errors.ErrorCodeExecutionReverted {
-						confirmationChannel <- Confirmation{
-							BlockHash:   latestBlockHash,
-							EventDataTx: eventDataTx,
-							Exception: errors.Wrap(eventDataTx.Exception,
-								"transaction confirmed but execution gave exception: %v"),
-							Error: nil,
-						}
-						return
-					}
-					// success, return the full event and blockhash and exit go-routine
-					confirmationChannel <- Confirmation{
-						BlockHash:   latestBlockHash,
-						EventDataTx: eventDataTx,
-						Exception:   nil,
-						Error:       nil,
-					}
-					return
-
-				default:
-					burrowNodeWebsocketClient.logger.InfoMsg("Received unsolicited response",
-						"response_id", response.ID,
-						"expected_response_id", client.EventResponseID(eventID))
-				}
-			}
-		}
-
-	}()
-
-	return confirmationChannel, nil
-}
-
-func (burrowNodeWebsocketClient *burrowNodeWebsocketClient) Close() {
-	if burrowNodeWebsocketClient.tendermintWebsocket != nil {
-		burrowNodeWebsocketClient.tendermintWebsocket.Stop()
-	}
-}
diff --git a/client/ws_client.go b/client/ws_client.go
deleted file mode 100644
index cdcb0b570af2b87926e888d0ef009b125d89e8f5..0000000000000000000000000000000000000000
--- a/client/ws_client.go
+++ /dev/null
@@ -1,86 +0,0 @@
-// Copyright 2017 Monax Industries Limited
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//    http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package client
-
-// NOTE: this websocket client acts on rpc/v0,
-// uses github.com/gorilla/websocket
-// and will be deprecated after 0.12
-// It is recommended to use the interfaces NodeClient
-// and NodeWebsocketClient.
-// Websocket client implementation. This will be used in tests.
-
-import (
-	"fmt"
-	"net/http"
-
-	"github.com/gorilla/websocket"
-)
-
-// A websocket client subscribes and unsubscribes to events
-type WSClient struct {
-	host   string
-	closed bool
-	conn   *websocket.Conn
-}
-
-// create a new connection
-func NewWSClient(addr string) *WSClient {
-	return &WSClient{
-		host: addr,
-	}
-}
-
-func (this *WSClient) Dial() (*http.Response, error) {
-	dialer := websocket.DefaultDialer
-	rHeader := http.Header{}
-	conn, r, err := dialer.Dial(this.host, rHeader)
-	if err != nil {
-		return r, err
-	}
-	this.conn = conn
-
-	return r, nil
-}
-
-// returns a channel from which messages can be pulled
-// from a go routine that reads the socket.
-// if the ws returns an error (eg. closes), we return
-func (this *WSClient) StartRead() <-chan []byte {
-	ch := make(chan []byte)
-	go func() {
-		for {
-			_, msg, err := this.conn.ReadMessage()
-			if err != nil {
-				if !this.closed {
-					// TODO For now.
-					fmt.Println("Error: " + err.Error())
-					close(ch)
-				}
-				return
-			}
-			ch <- msg
-		}
-	}()
-	return ch
-}
-
-func (this *WSClient) WriteMsg(msg []byte) {
-	this.conn.WriteMessage(websocket.TextMessage, msg)
-}
-
-func (this *WSClient) Close() {
-	this.closed = true
-	this.conn.Close()
-}
diff --git a/cmd/burrow/commands/configure.go b/cmd/burrow/commands/configure.go
index 142309de5775e4719a72d3ea42b2ab5fb86ed66e..c64d4c72a2cb953bf901e489241060d803f1250b 100644
--- a/cmd/burrow/commands/configure.go
+++ b/cmd/burrow/commands/configure.go
@@ -17,8 +17,8 @@ import (
 	"github.com/hyperledger/burrow/logging"
 	logging_config "github.com/hyperledger/burrow/logging/config"
 	"github.com/hyperledger/burrow/logging/config/presets"
-	"github.com/jawher/mow.cli"
-	"github.com/tendermint/go-amino"
+	cli "github.com/jawher/mow.cli"
+	amino "github.com/tendermint/go-amino"
 	tm_crypto "github.com/tendermint/go-crypto"
 	"github.com/tendermint/tendermint/p2p"
 )
diff --git a/cmd/burrow/commands/keys.go b/cmd/burrow/commands/keys.go
index e8ba5d4b09221a4e741137aeccdba97baf57897d..8fcf1a8175968219a37ce372aa642adefdec94c5 100644
--- a/cmd/burrow/commands/keys.go
+++ b/cmd/burrow/commands/keys.go
@@ -7,6 +7,7 @@ import (
 	"os"
 
 	"github.com/hyperledger/burrow/deployment"
+	cli "github.com/jawher/mow.cli"
 
 	"time"
 
@@ -16,9 +17,7 @@ import (
 	"github.com/hyperledger/burrow/config"
 	"github.com/hyperledger/burrow/crypto"
 	"github.com/hyperledger/burrow/keys"
-	"github.com/hyperledger/burrow/keys/pbkeys"
 	"github.com/hyperledger/burrow/logging/lifecycle"
-	"github.com/jawher/mow.cli"
 	"google.golang.org/grpc"
 )
 
@@ -38,14 +37,14 @@ func Keys(output Output) func(cmd *cli.Cmd) {
 			EnvVar: "MONAX_KEYS_PORT",
 		})
 
-		grpcKeysClient := func(output Output) pbkeys.KeysClient {
+		grpcKeysClient := func(output Output) keys.KeysClient {
 			var opts []grpc.DialOption
 			opts = append(opts, grpc.WithInsecure())
 			conn, err := grpc.Dial(*keysHost+":"+*keysPort, opts...)
 			if err != nil {
 				output.Fatalf("Failed to connect to grpc server: %v", err)
 			}
-			return pbkeys.NewKeysClient(conn)
+			return keys.NewKeysClient(conn)
 		}
 
 		cmd.Command("server", "run keys server", func(cmd *cli.Cmd) {
@@ -108,7 +107,7 @@ func Keys(output Output) func(cmd *cli.Cmd) {
 				c := grpcKeysClient(output)
 				ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
 				defer cancel()
-				resp, err := c.GenerateKey(ctx, &pbkeys.GenRequest{Passphrase: password, Curvetype: curve.String(), Keyname: *keyName})
+				resp, err := c.GenerateKey(ctx, &keys.GenRequest{Passphrase: password, CurveType: curve.String(), KeyName: *keyName})
 				if err != nil {
 					output.Fatalf("failed to generate key: %v", err)
 				}
@@ -139,7 +138,7 @@ func Keys(output Output) func(cmd *cli.Cmd) {
 				c := grpcKeysClient(output)
 				ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
 				defer cancel()
-				resp, err := c.Hash(ctx, &pbkeys.HashRequest{Hashtype: *hashType, Message: message})
+				resp, err := c.Hash(ctx, &keys.HashRequest{Hashtype: *hashType, Message: message})
 				if err != nil {
 					output.Fatalf("failed to get public key: %v", err)
 				}
@@ -158,7 +157,7 @@ func Keys(output Output) func(cmd *cli.Cmd) {
 				c := grpcKeysClient(output)
 				ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
 				defer cancel()
-				resp, err := c.Export(ctx, &pbkeys.ExportRequest{Passphrase: *passphrase, Name: *keyName, Address: *keyAddr})
+				resp, err := c.Export(ctx, &keys.ExportRequest{Passphrase: *passphrase, Name: *keyName, Address: *keyAddr})
 				if err != nil {
 					output.Fatalf("failed to export key: %v", err)
 				}
@@ -170,7 +169,7 @@ func Keys(output Output) func(cmd *cli.Cmd) {
 
 				key := deployment.Key{
 					Name:       *keyName,
-					CurveType:  resp.GetCurvetype(),
+					CurveType:  resp.GetCurveType(),
 					Address:    addr,
 					PublicKey:  resp.GetPublickey(),
 					PrivateKey: resp.GetPrivatekey(),
@@ -212,7 +211,7 @@ func Keys(output Output) func(cmd *cli.Cmd) {
 				defer cancel()
 
 				if (*key)[:1] == "{" {
-					resp, err := c.ImportJSON(ctx, &pbkeys.ImportJSONRequest{JSON: *key})
+					resp, err := c.ImportJSON(ctx, &keys.ImportJSONRequest{JSON: *key})
 					if err != nil {
 						output.Fatalf("failed to import json key: %v", err)
 					}
@@ -223,7 +222,7 @@ func Keys(output Output) func(cmd *cli.Cmd) {
 					if err != nil {
 						output.Fatalf("failed to hex decode key: %s", *key)
 					}
-					resp, err := c.Import(ctx, &pbkeys.ImportRequest{Passphrase: password, Keybytes: privKeyBytes, Curvetype: *curveType})
+					resp, err := c.Import(ctx, &keys.ImportRequest{Passphrase: password, KeyBytes: privKeyBytes, CurveType: *curveType})
 					if err != nil {
 						output.Fatalf("failed to import json key: %v", err)
 					}
@@ -242,12 +241,12 @@ func Keys(output Output) func(cmd *cli.Cmd) {
 				c := grpcKeysClient(output)
 				ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
 				defer cancel()
-				resp, err := c.PublicKey(ctx, &pbkeys.PubRequest{Name: *name, Address: *addr})
+				resp, err := c.PublicKey(ctx, &keys.PubRequest{Name: *name, Address: *addr})
 				if err != nil {
 					output.Fatalf("failed to get public key: %v", err)
 				}
 
-				fmt.Printf("%X\n", resp.GetPub())
+				fmt.Printf("%X\n", resp.GetPublicKey())
 			}
 		})
 
@@ -266,7 +265,7 @@ func Keys(output Output) func(cmd *cli.Cmd) {
 				c := grpcKeysClient(output)
 				ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
 				defer cancel()
-				resp, err := c.Sign(ctx, &pbkeys.SignRequest{Passphrase: *passphrase, Name: *name, Address: *addr, Message: message})
+				resp, err := c.Sign(ctx, &keys.SignRequest{Passphrase: *passphrase, Name: *name, Address: *addr, Message: message})
 				if err != nil {
 					output.Fatalf("failed to get public key: %v", err)
 				}
@@ -300,7 +299,10 @@ func Keys(output Output) func(cmd *cli.Cmd) {
 				c := grpcKeysClient(output)
 				ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
 				defer cancel()
-				_, err = c.Verify(ctx, &pbkeys.VerifyRequest{Curvetype: *curveType, Pub: publickey, Signature: signature, Message: message})
+				_, err = c.Verify(ctx, &keys.VerifyRequest{
+					CurveType: *curveType,
+					PublicKey: publickey,
+					Signature: signature, Message: message})
 				if err != nil {
 					output.Fatalf("failed to verify: %v", err)
 				}
@@ -316,7 +318,7 @@ func Keys(output Output) func(cmd *cli.Cmd) {
 				c := grpcKeysClient(output)
 				ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
 				defer cancel()
-				_, err := c.AddName(ctx, &pbkeys.AddNameRequest{Keyname: *keyname, Address: *addr})
+				_, err := c.AddName(ctx, &keys.AddNameRequest{Keyname: *keyname, Address: *addr})
 				if err != nil {
 					output.Fatalf("failed to add name to addr: %v", err)
 				}
@@ -330,13 +332,13 @@ func Keys(output Output) func(cmd *cli.Cmd) {
 				c := grpcKeysClient(output)
 				ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
 				defer cancel()
-				resp, err := c.List(ctx, &pbkeys.ListRequest{})
+				resp, err := c.List(ctx, &keys.ListRequest{})
 				if err != nil {
 					output.Fatalf("failed to list key names: %v", err)
 				}
 				if *name != "" {
 					for _, k := range resp.Key {
-						if k.Keyname == *name {
+						if k.KeyName == *name {
 							output.Printf("%s\n", k.Address)
 						}
 					}
@@ -355,7 +357,7 @@ func Keys(output Output) func(cmd *cli.Cmd) {
 				c := grpcKeysClient(output)
 				ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
 				defer cancel()
-				_, err := c.RemoveName(ctx, &pbkeys.RemoveNameRequest{Keyname: *name})
+				_, err := c.RemoveName(ctx, &keys.RemoveNameRequest{KeyName: *name})
 				if err != nil {
 					output.Fatalf("failed to remove key: %v", err)
 				}
diff --git a/cmd/burrow/commands/spec.go b/cmd/burrow/commands/spec.go
index 36fad65a7fcd53b66bd6385bc133f7b3e927db79..1110d869e52d816dec4b905cb0bfed4305954077 100644
--- a/cmd/burrow/commands/spec.go
+++ b/cmd/burrow/commands/spec.go
@@ -5,7 +5,7 @@ import (
 
 	"github.com/hyperledger/burrow/config/source"
 	"github.com/hyperledger/burrow/genesis/spec"
-	"github.com/jawher/mow.cli"
+	cli "github.com/jawher/mow.cli"
 )
 
 func Spec(output Output) func(cmd *cli.Cmd) {
diff --git a/cmd/burrow/commands/start.go b/cmd/burrow/commands/start.go
index e3d11c1309f25bcdefce95a73de4a76be745b1a3..e6b56f09beaf4e003772e572bf957306dc6df808 100644
--- a/cmd/burrow/commands/start.go
+++ b/cmd/burrow/commands/start.go
@@ -4,7 +4,7 @@ import (
 	"context"
 
 	"github.com/hyperledger/burrow/crypto"
-	"github.com/jawher/mow.cli"
+	cli "github.com/jawher/mow.cli"
 )
 
 func Start(output Output) func(cmd *cli.Cmd) {
diff --git a/cmd/burrow/main.go b/cmd/burrow/main.go
index 0bc40136364d7fcf5b66de2c3c394cf43745f2ef..38c17d59fffbe6bc08eba6f48b81b258d26dcc8e 100644
--- a/cmd/burrow/main.go
+++ b/cmd/burrow/main.go
@@ -6,7 +6,7 @@ import (
 
 	"github.com/hyperledger/burrow/cmd/burrow/commands"
 	"github.com/hyperledger/burrow/project"
-	"github.com/jawher/mow.cli"
+	cli "github.com/jawher/mow.cli"
 )
 
 func main() {
diff --git a/config/config.go b/config/config.go
index c9958d56df2cccc1ddcbfc233db4f81bef7681fd..c22ddbb1194d883ff262431a62c7fa4663e1620e 100644
--- a/config/config.go
+++ b/config/config.go
@@ -40,6 +40,7 @@ func DefaultBurrowConfig() *BurrowConfig {
 		Tendermint: tendermint.DefaultBurrowTendermintConfig(),
 		Keys:       keys.DefaultKeysConfig(),
 		RPC:        rpc.DefaultRPCConfig(),
+		Execution:  execution.DefaultExecutionConfig(),
 		Logging:    logging_config.DefaultNodeLoggingConfig(),
 	}
 }
diff --git a/consensus/tendermint/abci/app.go b/consensus/tendermint/abci/app.go
index ba7fec9f55324e640ec2f24b0ccf6a440f5c97b9..6c5247481b86a1e59fd3a7d71ee61efb66d0a9dd 100644
--- a/consensus/tendermint/abci/app.go
+++ b/consensus/tendermint/abci/app.go
@@ -5,7 +5,7 @@ import (
 	"sync"
 	"time"
 
-	"encoding/json"
+	"runtime/debug"
 
 	bcm "github.com/hyperledger/burrow/blockchain"
 	"github.com/hyperledger/burrow/consensus/tendermint/codes"
@@ -26,11 +26,13 @@ type App struct {
 	blockchain    *bcm.Blockchain
 	checker       execution.BatchExecutor
 	committer     execution.BatchCommitter
+	checkTx       func(txBytes []byte) abciTypes.ResponseCheckTx
+	deliverTx     func(txBytes []byte) abciTypes.ResponseCheckTx
 	mempoolLocker sync.Locker
 	// We need to cache these from BeginBlock for when we need actually need it in Commit
 	block *abciTypes.RequestBeginBlock
-	// Utility
-	txDecoder txs.Decoder
+	// Function to use to fail gracefully from panic rather than letting Tendermint make us a zombie
+	panicFunc func(error)
 	// Logging
 	logger *logging.Logger
 }
@@ -38,12 +40,14 @@ type App struct {
 var _ abciTypes.Application = &App{}
 
 func NewApp(blockchain *bcm.Blockchain, checker execution.BatchExecutor, committer execution.BatchCommitter,
-	txDecoder txs.Decoder, logger *logging.Logger) *App {
+	txDecoder txs.Decoder, panicFunc func(error), logger *logging.Logger) *App {
 	return &App{
 		blockchain: blockchain,
 		checker:    checker,
 		committer:  committer,
-		txDecoder:  txDecoder,
+		checkTx:    txExecutor(checker, txDecoder, logger.WithScope("CheckTx")),
+		deliverTx:  txExecutor(committer, txDecoder, logger.WithScope("DeliverTx")),
+		panicFunc:  panicFunc,
 		logger:     logger.WithScope("abci.NewApp").With(structure.ComponentKey, "ABCI_App"),
 	}
 }
@@ -77,50 +81,6 @@ func (app *App) Query(reqQuery abciTypes.RequestQuery) (respQuery abciTypes.Resp
 	return
 }
 
-func (app *App) CheckTx(txBytes []byte) abciTypes.ResponseCheckTx {
-	txEnv, err := app.txDecoder.DecodeTx(txBytes)
-	if err != nil {
-		app.logger.TraceMsg("CheckTx decoding error",
-			"tag", "CheckTx",
-			structure.ErrorKey, err)
-		return abciTypes.ResponseCheckTx{
-			Code: codes.EncodingErrorCode,
-			Log:  fmt.Sprintf("Encoding error: %s", err),
-		}
-	}
-	receipt := txEnv.Tx.GenerateReceipt()
-
-	err = app.checker.Execute(txEnv)
-	if err != nil {
-		app.logger.TraceMsg("CheckTx execution error",
-			structure.ErrorKey, err,
-			"tag", "CheckTx",
-			"tx_hash", receipt.TxHash,
-			"creates_contract", receipt.CreatesContract)
-		return abciTypes.ResponseCheckTx{
-			Code: codes.EncodingErrorCode,
-			Log:  fmt.Sprintf("CheckTx could not execute transaction: %s, error: %v", txEnv, err),
-		}
-	}
-
-	receiptBytes, err := json.Marshal(receipt)
-	if err != nil {
-		return abciTypes.ResponseCheckTx{
-			Code: codes.TxExecutionErrorCode,
-			Log:  fmt.Sprintf("CheckTx could not serialise receipt: %s", err),
-		}
-	}
-	app.logger.TraceMsg("CheckTx success",
-		"tag", "CheckTx",
-		"tx_hash", receipt.TxHash,
-		"creates_contract", receipt.CreatesContract)
-	return abciTypes.ResponseCheckTx{
-		Code: codes.TxExecutionSuccessCode,
-		Log:  "CheckTx success - receipt in data",
-		Data: receiptBytes,
-	}
-}
-
 func (app *App) InitChain(chain abciTypes.RequestInitChain) (respInitChain abciTypes.ResponseInitChain) {
 	// Could verify agreement on initial validator set here
 	return
@@ -131,47 +91,74 @@ func (app *App) BeginBlock(block abciTypes.RequestBeginBlock) (respBeginBlock ab
 	return
 }
 
+func (app *App) CheckTx(txBytes []byte) abciTypes.ResponseCheckTx {
+	defer func() {
+		if r := recover(); r != nil {
+			app.panicFunc(fmt.Errorf("panic occurred in abci.App/CheckTx: %v\n%s", r, debug.Stack()))
+		}
+	}()
+	return app.checkTx(txBytes)
+}
+
 func (app *App) DeliverTx(txBytes []byte) abciTypes.ResponseDeliverTx {
-	txEnv, err := app.txDecoder.DecodeTx(txBytes)
-	if err != nil {
-		app.logger.TraceMsg("DeliverTx decoding error",
-			"tag", "DeliverTx",
-			structure.ErrorKey, err)
-		return abciTypes.ResponseDeliverTx{
-			Code: codes.EncodingErrorCode,
-			Log:  fmt.Sprintf("Encoding error: %s", err),
+	defer func() {
+		if r := recover(); r != nil {
+			app.panicFunc(fmt.Errorf("panic occurred in abci.App/DeliverTx: %v\n%s", r, debug.Stack()))
 		}
+	}()
+	ctr := app.deliverTx(txBytes)
+	// Currently these message types are identical, if they are ever different can map between
+	return abciTypes.ResponseDeliverTx{
+		Code:      ctr.Code,
+		Log:       ctr.Log,
+		Data:      ctr.Data,
+		Tags:      ctr.Tags,
+		Fee:       ctr.Fee,
+		GasUsed:   ctr.GasUsed,
+		GasWanted: ctr.GasWanted,
+		Info:      ctr.Info,
 	}
+}
 
-	receipt := txEnv.Tx.GenerateReceipt()
-	err = app.committer.Execute(txEnv)
-	if err != nil {
-		app.logger.TraceMsg("DeliverTx execution error",
-			structure.ErrorKey, err,
-			"tag", "DeliverTx",
-			"tx_hash", receipt.TxHash,
-			"creates_contract", receipt.CreatesContract)
-		return abciTypes.ResponseDeliverTx{
-			Code: codes.TxExecutionErrorCode,
-			Log:  fmt.Sprintf("DeliverTx could not execute transaction: %s, error: %s", txEnv, err),
+func txExecutor(executor execution.BatchExecutor, txDecoder txs.Decoder, logger *logging.Logger) func(txBytes []byte) abciTypes.ResponseCheckTx {
+	return func(txBytes []byte) abciTypes.ResponseCheckTx {
+		txEnv, err := txDecoder.DecodeTx(txBytes)
+		if err != nil {
+			logger.TraceMsg("Decoding error",
+				structure.ErrorKey, err)
+			return abciTypes.ResponseCheckTx{
+				Code: codes.EncodingErrorCode,
+				Log:  fmt.Sprintf("Encoding error: %s", err),
+			}
 		}
-	}
 
-	app.logger.TraceMsg("DeliverTx success",
-		"tag", "DeliverTx",
-		"tx_hash", receipt.TxHash,
-		"creates_contract", receipt.CreatesContract)
-	receiptBytes, err := json.Marshal(receipt)
-	if err != nil {
-		return abciTypes.ResponseDeliverTx{
-			Code: codes.TxExecutionErrorCode,
-			Log:  fmt.Sprintf("DeliverTx could not serialise receipt: %s", err),
+		txe, err := executor.Execute(txEnv)
+		if err != nil {
+			logger.TraceMsg("Execution error",
+				structure.ErrorKey, err,
+				"tx_hash", txEnv.Tx.Hash())
+			return abciTypes.ResponseCheckTx{
+				Code: codes.EncodingErrorCode,
+				Log:  fmt.Sprintf("Could not execute transaction: %s, error: %v", txEnv, err),
+			}
+		}
+
+		bs, err := txe.Receipt.Encode()
+		if err != nil {
+			return abciTypes.ResponseCheckTx{
+				Code: codes.TxExecutionErrorCode,
+				Log:  fmt.Sprintf("Could not serialise receipt: %s", err),
+			}
+		}
+		logger.TraceMsg("Execution success",
+			"tx_hash", txe.TxHash,
+			"contract_address", txe.Receipt.ContractAddress,
+			"creates_contract", txe.Receipt.CreatesContract)
+		return abciTypes.ResponseCheckTx{
+			Code: codes.TxExecutionSuccessCode,
+			Log:  "Execution success - TxExecution in data",
+			Data: bs,
 		}
-	}
-	return abciTypes.ResponseDeliverTx{
-		Code: codes.TxExecutionSuccessCode,
-		Log:  "DeliverTx success - receipt in data",
-		Data: receiptBytes,
 	}
 }
 
@@ -192,6 +179,11 @@ func (app *App) EndBlock(reqEndBlock abciTypes.RequestEndBlock) abciTypes.Respon
 }
 
 func (app *App) Commit() abciTypes.ResponseCommit {
+	defer func() {
+		if r := recover(); r != nil {
+			app.panicFunc(fmt.Errorf("panic occurred in abci.App/Commit: %v\n%s", r, debug.Stack()))
+		}
+	}()
 	app.logger.InfoMsg("Committing block",
 		"tag", "Commit",
 		structure.ScopeKey, "Commit()",
@@ -229,7 +221,8 @@ func (app *App) Commit() abciTypes.ResponseCommit {
 
 	// First commit the app start, this app hash will not get checkpointed until the next block when we are sure
 	// that nothing in the downstream commit process could have failed. At worst we go back one block.
-	appHash, err := app.committer.Commit()
+	blockHeader := app.block.Header
+	appHash, err := app.committer.Commit(&blockHeader)
 	if err != nil {
 		panic(errors.Wrap(err, "Could not commit transactions in block to execution state"))
 	}
diff --git a/consensus/tendermint/events.go b/consensus/tendermint/events.go
deleted file mode 100644
index c85f976c0d20cad99722976c4393e9d0d261df41..0000000000000000000000000000000000000000
--- a/consensus/tendermint/events.go
+++ /dev/null
@@ -1,103 +0,0 @@
-package tendermint
-
-import (
-	"context"
-
-	"github.com/hyperledger/burrow/event"
-	"github.com/hyperledger/burrow/event/query"
-	"github.com/hyperledger/burrow/logging/structure"
-	"github.com/tendermint/tendermint/libs/pubsub"
-	tm_types "github.com/tendermint/tendermint/types"
-)
-
-// Publishes all tendermint events available on subscribable to publisher
-func PublishAllEvents(ctx context.Context, fromSubscribable event.Subscribable, subscriber string,
-	toPublisher event.Publisher) error {
-
-	var err error
-
-	// This is a work-around for the fact we cannot access a message's tags and need a separate query for each event type
-	tendermintEventTypes := []string{
-		tm_types.EventBond,
-		tm_types.EventCompleteProposal,
-		tm_types.EventDupeout,
-		tm_types.EventFork,
-		tm_types.EventLock,
-		tm_types.EventNewBlock,
-		tm_types.EventNewBlockHeader,
-		tm_types.EventNewRound,
-		tm_types.EventNewRoundStep,
-		tm_types.EventPolka,
-		tm_types.EventRebond,
-		tm_types.EventRelock,
-		tm_types.EventTimeoutPropose,
-		tm_types.EventTimeoutWait,
-		tm_types.EventTx,
-		tm_types.EventUnbond,
-		tm_types.EventUnlock,
-		tm_types.EventVote,
-		tm_types.EventProposalHeartbeat,
-	}
-
-	for _, eventType := range tendermintEventTypes {
-		publishErr := PublishEvent(ctx, fromSubscribable, subscriber, eventType, toPublisher)
-		if publishErr != nil && err == nil {
-			err = publishErr
-		}
-	}
-
-	return err
-}
-
-func PublishEvent(ctx context.Context, fromSubscribable event.Subscribable, subscriber string, eventType string,
-	toPublisher event.Publisher) error {
-	tags := map[string]interface{}{
-		structure.ComponentKey: "Tendermint",
-		tm_types.EventTypeKey:  eventType,
-		event.EventIDKey:       eventType,
-	}
-	return event.PublishAll(ctx, fromSubscribable, subscriber, query.WrapQuery(tm_types.QueryForEvent(eventType)),
-		toPublisher, tags)
-}
-
-type eventBusSubscriber struct {
-	tm_types.EventBusSubscriber
-}
-
-func EventBusAsSubscribable(eventBus tm_types.EventBusSubscriber) event.Subscribable {
-	return eventBusSubscriber{eventBus}
-}
-
-func (ebs eventBusSubscriber) Subscribe(ctx context.Context, subscriber string, queryable query.Queryable,
-	out chan<- interface{}) error {
-	qry, err := queryable.Query()
-	if err != nil {
-		return err
-	}
-	return ebs.EventBusSubscriber.Subscribe(ctx, subscriber, qry, out)
-}
-
-func (ebs eventBusSubscriber) Unsubscribe(ctx context.Context, subscriber string, queryable query.Queryable) error {
-	qry, err := queryable.Query()
-	if err != nil {
-		return err
-	}
-	return ebs.EventBusSubscriber.Unsubscribe(ctx, subscriber, qry)
-}
-
-type subscribableEventBus struct {
-	event.Subscribable
-}
-
-func SubscribableAsEventBus(subscribable event.Subscribable) tm_types.EventBusSubscriber {
-	return subscribableEventBus{subscribable}
-}
-
-func (seb subscribableEventBus) Subscribe(ctx context.Context, subscriber string, qry pubsub.Query,
-	out chan<- interface{}) error {
-	return seb.Subscribable.Subscribe(ctx, subscriber, query.WrapQuery(qry), out)
-}
-
-func (seb subscribableEventBus) Unsubscribe(ctx context.Context, subscriber string, qry pubsub.Query) error {
-	return seb.Subscribable.Unsubscribe(ctx, subscriber, query.WrapQuery(qry))
-}
diff --git a/consensus/tendermint/logger.go b/consensus/tendermint/logger.go
index 6022f47307eade096ddbd9e92c492cda12c9ae85..2a73c22fb234525dd95d3abd0ae5602e91ce3443 100644
--- a/consensus/tendermint/logger.go
+++ b/consensus/tendermint/logger.go
@@ -9,7 +9,7 @@ type tendermintLogger struct {
 	logger *logging.Logger
 }
 
-func NewLogger(logger *logging.Logger) *tendermintLogger {
+func NewLogger(logger *logging.Logger) log.Logger {
 	return &tendermintLogger{
 		logger: logger,
 	}
diff --git a/consensus/tendermint/tendermint.go b/consensus/tendermint/tendermint.go
index e7ddf260b6622e13cdf1e30d0e9a2ec739963c59..3ada43cf2c49f6fd915e3de4b6342593cbf854e0 100644
--- a/consensus/tendermint/tendermint.go
+++ b/consensus/tendermint/tendermint.go
@@ -1,25 +1,22 @@
 package tendermint
 
 import (
-	"context"
-
 	"os"
 	"path"
 
 	bcm "github.com/hyperledger/burrow/blockchain"
 	"github.com/hyperledger/burrow/consensus/tendermint/abci"
 	"github.com/hyperledger/burrow/event"
-	"github.com/hyperledger/burrow/event/query"
 	"github.com/hyperledger/burrow/execution"
 	"github.com/hyperledger/burrow/genesis"
 	"github.com/hyperledger/burrow/logging"
 	"github.com/hyperledger/burrow/logging/structure"
 	"github.com/hyperledger/burrow/txs"
-	tm_crypto "github.com/tendermint/go-crypto"
+	tmCrypto "github.com/tendermint/go-crypto"
 	"github.com/tendermint/tendermint/config"
 	"github.com/tendermint/tendermint/node"
 	"github.com/tendermint/tendermint/proxy"
-	tm_types "github.com/tendermint/tendermint/types"
+	tmTypes "github.com/tendermint/tendermint/types"
 	dbm "github.com/tendermint/tmlibs/db"
 )
 
@@ -31,7 +28,7 @@ type Node struct {
 	}
 }
 
-var NewBlockQuery = query.Must(event.QueryForEventID(tm_types.EventNewBlock).Query())
+var NewBlockQuery = event.QueryForEventID(tmTypes.EventNewBlock)
 
 func DBProvider(ID string, backendType dbm.DBBackendType, dbDir string) dbm.DB {
 	return dbm.NewDB(ID, backendType, dbDir)
@@ -50,9 +47,9 @@ func (n *Node) Close() {
 	}
 }
 
-func NewNode(conf *config.Config, privValidator tm_types.PrivValidator, genesisDoc *tm_types.GenesisDoc,
+func NewNode(conf *config.Config, privValidator tmTypes.PrivValidator, genesisDoc *tmTypes.GenesisDoc,
 	blockchain *bcm.Blockchain, checker execution.BatchExecutor, committer execution.BatchCommitter,
-	txDecoder txs.Decoder, logger *logging.Logger) (*Node, error) {
+	txDecoder txs.Decoder, panicFunc func(error), logger *logging.Logger) (*Node, error) {
 
 	var err error
 	// disable Tendermint's RPC
@@ -64,11 +61,11 @@ func NewNode(conf *config.Config, privValidator tm_types.PrivValidator, genesisD
 	}
 
 	nde := &Node{}
-	app := abci.NewApp(blockchain, checker, committer, txDecoder, logger)
+	app := abci.NewApp(blockchain, checker, committer, txDecoder, panicFunc, logger)
 	conf.NodeKeyFile()
 	nde.Node, err = node.NewNode(conf, privValidator,
 		proxy.NewLocalClientCreator(app),
-		func() (*tm_types.GenesisDoc, error) {
+		func() (*tmTypes.GenesisDoc, error) {
 			return genesisDoc, nil
 		},
 		nde.DBProvider,
@@ -81,56 +78,33 @@ func NewNode(conf *config.Config, privValidator tm_types.PrivValidator, genesisD
 	return nde, nil
 }
 
-func DeriveGenesisDoc(burrowGenesisDoc *genesis.GenesisDoc) *tm_types.GenesisDoc {
-	validators := make([]tm_types.GenesisValidator, len(burrowGenesisDoc.Validators))
+func DeriveGenesisDoc(burrowGenesisDoc *genesis.GenesisDoc) *tmTypes.GenesisDoc {
+	validators := make([]tmTypes.GenesisValidator, len(burrowGenesisDoc.Validators))
 	for i, validator := range burrowGenesisDoc.Validators {
-		tm := tm_crypto.PubKeyEd25519{}
+		tm := tmCrypto.PubKeyEd25519{}
 		copy(tm[:], validator.PublicKey.RawBytes())
-		validators[i] = tm_types.GenesisValidator{
+		validators[i] = tmTypes.GenesisValidator{
 			PubKey: tm,
 			Name:   validator.Name,
 			Power:  int64(validator.Amount),
 		}
 	}
-	return &tm_types.GenesisDoc{
+	return &tmTypes.GenesisDoc{
 		ChainID:         burrowGenesisDoc.ChainID(),
 		GenesisTime:     burrowGenesisDoc.GenesisTime,
 		Validators:      validators,
 		AppHash:         burrowGenesisDoc.Hash(),
-		ConsensusParams: tm_types.DefaultConsensusParams(),
+		ConsensusParams: tmTypes.DefaultConsensusParams(),
 	}
 }
 
-func NewBlockEvent(message interface{}) *tm_types.EventDataNewBlock {
-	tmEventData, ok := message.(tm_types.TMEventData)
+func NewBlockEvent(message interface{}) *tmTypes.EventDataNewBlock {
+	tmEventData, ok := message.(tmTypes.TMEventData)
 	if ok {
-		eventDataNewBlock, ok := tmEventData.(tm_types.EventDataNewBlock)
+		eventDataNewBlock, ok := tmEventData.(tmTypes.EventDataNewBlock)
 		if ok {
 			return &eventDataNewBlock
 		}
 	}
 	return nil
 }
-
-// Subscribe to NewBlock event safely that ensures progress by a non-blocking receive as well as handling unsubscribe
-func SubscribeNewBlock(ctx context.Context, subscribable event.Subscribable) (<-chan *tm_types.EventDataNewBlock, error) {
-	subID, err := event.GenerateSubscriptionID()
-	if err != nil {
-		return nil, err
-	}
-	const unconsumedBlocksBeforeUnsubscribe = 3
-	ch := make(chan *tm_types.EventDataNewBlock, unconsumedBlocksBeforeUnsubscribe)
-	return ch, event.SubscribeCallback(ctx, subscribable, subID, NewBlockQuery, func(message interface{}) (stop bool) {
-		eventDataNewBlock := NewBlockEvent(message)
-		if eventDataNewBlock != nil {
-			select {
-			case ch <- eventDataNewBlock:
-				return false
-			default:
-				// If we can't send shut down the channel
-				return true
-			}
-		}
-		return
-	})
-}
diff --git a/consensus/tendermint/validator/priv_validator_memory.go b/consensus/tendermint/validator/priv_validator_memory.go
index 7f5077c1f10fa89200f23e7f0b941d021d76eae7..05455cba2ab81ec8ef4a256d33d5b46836a65136 100644
--- a/consensus/tendermint/validator/priv_validator_memory.go
+++ b/consensus/tendermint/validator/priv_validator_memory.go
@@ -1,7 +1,7 @@
 package validator
 
 import (
-	acm "github.com/hyperledger/burrow/account"
+	"github.com/hyperledger/burrow/acm"
 	"github.com/hyperledger/burrow/crypto"
 	tm_crypto "github.com/tendermint/go-crypto"
 	tm_types "github.com/tendermint/tendermint/types"
diff --git a/core/kernel.go b/core/kernel.go
index 1ea5f95b9791405126d2659c4bb5ce3e27084613..fee805da88c4770fe9bfd719330f711607627428 100644
--- a/core/kernel.go
+++ b/core/kernel.go
@@ -32,32 +32,28 @@ import (
 	"github.com/hyperledger/burrow/consensus/tendermint/query"
 	"github.com/hyperledger/burrow/event"
 	"github.com/hyperledger/burrow/execution"
-	"github.com/hyperledger/burrow/execution/events/pbevents"
-	"github.com/hyperledger/burrow/execution/pbtransactor"
 	"github.com/hyperledger/burrow/genesis"
 	"github.com/hyperledger/burrow/keys"
-	"github.com/hyperledger/burrow/keys/pbkeys"
 	"github.com/hyperledger/burrow/logging"
 	"github.com/hyperledger/burrow/logging/structure"
 	"github.com/hyperledger/burrow/process"
 	"github.com/hyperledger/burrow/rpc"
 	"github.com/hyperledger/burrow/rpc/metrics"
 	"github.com/hyperledger/burrow/rpc/rpcevents"
-	"github.com/hyperledger/burrow/rpc/rpctransactor"
+	"github.com/hyperledger/burrow/rpc/rpcquery"
+	"github.com/hyperledger/burrow/rpc/rpctransact"
 	"github.com/hyperledger/burrow/rpc/tm"
-	"github.com/hyperledger/burrow/rpc/v0"
-	v0_server "github.com/hyperledger/burrow/rpc/v0/server"
 	"github.com/hyperledger/burrow/txs"
-	tm_config "github.com/tendermint/tendermint/config"
-	tm_types "github.com/tendermint/tendermint/types"
+	tmConfig "github.com/tendermint/tendermint/config"
+	tmTypes "github.com/tendermint/tendermint/types"
 	dbm "github.com/tendermint/tmlibs/db"
-	"google.golang.org/grpc/reflection"
 )
 
 const (
 	CooldownMilliseconds              = 1000
 	ServerShutdownTimeoutMilliseconds = 1000
 	LoggingCallerDepth                = 5
+	AccountsRingMutexCount            = 100
 )
 
 // Kernel is the root structure of Burrow
@@ -74,10 +70,14 @@ type Kernel struct {
 	shutdownOnce   sync.Once
 }
 
-func NewKernel(ctx context.Context, keyClient keys.KeyClient, privValidator tm_types.PrivValidator,
-	genesisDoc *genesis.GenesisDoc, tmConf *tm_config.Config, rpcConfig *rpc.RPCConfig, keyConfig *keys.KeysConfig,
+func NewKernel(ctx context.Context, keyClient keys.KeyClient, privValidator tmTypes.PrivValidator,
+	genesisDoc *genesis.GenesisDoc, tmConf *tmConfig.Config, rpcConfig *rpc.RPCConfig, keyConfig *keys.KeysConfig,
 	keyStore *keys.KeyStore, exeOptions []execution.ExecutionOption, logger *logging.Logger) (*Kernel, error) {
 
+	kern := &Kernel{
+		processes:      make(map[string]process.Process),
+		shutdownNotify: make(chan struct{}),
+	}
 	logger = logger.WithScope("NewKernel()").With(structure.TimeKey, kitlog.DefaultTimestampUTC)
 	tmLogger := logger.With(structure.CallerKey, kitlog.Caller(LoggingCallerDepth+1))
 	logger = logger.WithInfo(structure.CallerKey, kitlog.Caller(LoggingCallerDepth))
@@ -107,16 +107,17 @@ func NewKernel(ctx context.Context, keyClient keys.KeyClient, privValidator tm_t
 	emitter := event.NewEmitter(logger)
 	committer := execution.NewBatchCommitter(state, blockchain.Tip, emitter, logger, exeOptions...)
 	tmNode, err := tendermint.NewNode(tmConf, privValidator, tmGenesisDoc, blockchain, checker, committer, txCodec,
-		tmLogger)
+		kern.Panic, tmLogger)
 	if err != nil {
 		return nil, err
 	}
-	transactor := execution.NewTransactor(blockchain.Tip, emitter, tmNode.MempoolReactor().BroadcastTx, txCodec,
-		logger)
+
+	transactor := execution.NewTransactor(blockchain.Tip, emitter, execution.NewAccounts(checker, keyClient, AccountsRingMutexCount),
+		tmNode.MempoolReactor().BroadcastTx, txCodec, logger)
 
 	nameRegState := state
 	accountState := state
-	service := rpc.NewService(ctx, accountState, nameRegState, checker, emitter, blockchain, keyClient, transactor,
+	service := rpc.NewService(accountState, nameRegState, blockchain, transactor,
 		query.NewNodeView(tmNode, txCodec), logger)
 
 	launchers := []process.Launcher{
@@ -155,14 +156,6 @@ func NewKernel(ctx context.Context, keyClient keys.KeyClient, privValidator tm_t
 				if err != nil {
 					return nil, fmt.Errorf("error starting Tendermint node: %v", err)
 				}
-				subscriber := fmt.Sprintf("TendermintFireHose-%s-%s", genesisDoc.ChainName, genesisDoc.ChainID())
-				// Multiplex Tendermint and EVM events
-
-				err = tendermint.PublishAllEvents(ctx, tendermint.EventBusAsSubscribable(tmNode.EventBus()), subscriber,
-					emitter)
-				if err != nil {
-					return nil, fmt.Errorf("could not subscribe to Tendermint events: %v", err)
-				}
 				return process.ShutdownFunc(func(ctx context.Context) error {
 					err := tmNode.Stop()
 					// Close tendermint database connections using our wrapper
@@ -185,7 +178,7 @@ func NewKernel(ctx context.Context, keyClient keys.KeyClient, privValidator tm_t
 			Name:    "RPC/tm",
 			Enabled: rpcConfig.TM.Enabled,
 			Launch: func() (process.Process, error) {
-				server, err := tm.StartServer(service, "/websocket", rpcConfig.TM.ListenAddress, emitter, logger)
+				server, err := tm.StartServer(service, "/websocket", rpcConfig.TM.ListenAddress, logger)
 				if err != nil {
 					return nil, err
 				}
@@ -203,26 +196,6 @@ func NewKernel(ctx context.Context, keyClient keys.KeyClient, privValidator tm_t
 				return server, nil
 			},
 		},
-		{
-			Name:    "RPC/V0",
-			Enabled: rpcConfig.V0.Enabled,
-			Launch: func() (process.Process, error) {
-				codec := v0.NewTCodec()
-				jsonServer := v0.NewJSONServer(v0.NewJSONService(codec, service, logger))
-				websocketServer := v0_server.NewWebSocketServer(rpcConfig.V0.Server.WebSocket.MaxWebSocketSessions,
-					v0.NewWebsocketService(codec, service, logger), logger)
-
-				serveProcess, err := v0_server.NewServeProcess(rpcConfig.V0.Server, logger, jsonServer, websocketServer)
-				if err != nil {
-					return nil, err
-				}
-				err = serveProcess.Start()
-				if err != nil {
-					return nil, err
-				}
-				return serveProcess, nil
-			},
-		},
 		{
 			Name:    "RPC/GRPC",
 			Enabled: rpcConfig.GRPC.Enabled,
@@ -231,6 +204,7 @@ func NewKernel(ctx context.Context, keyClient keys.KeyClient, privValidator tm_t
 				if err != nil {
 					return nil, err
 				}
+				listen.Addr()
 
 				grpcServer := rpc.NewGRPCServer(logger)
 				var ks *keys.KeyStore
@@ -242,19 +216,18 @@ func NewKernel(ctx context.Context, keyClient keys.KeyClient, privValidator tm_t
 					if keyStore == nil {
 						ks = keys.NewKeyStore(keyConfig.KeysDirectory, keyConfig.AllowBadFilePermissions, logger)
 					}
-					pbkeys.RegisterKeysServer(grpcServer, ks)
+					keys.RegisterKeysServer(grpcServer, ks)
 				}
 
-				pbtransactor.RegisterTransactorServer(grpcServer, rpctransactor.NewTransactorServer(service.Transactor(),
-					service.MempoolAccounts(), state, txCodec))
+				rpcquery.RegisterQueryServer(grpcServer, rpcquery.NewQueryServer(state, nameRegState))
 
-				pbevents.RegisterEventsServer(grpcServer, rpcevents.NewEventsServer(rpc.NewSubscriptions(service)))
+				rpctransact.RegisterTransactServer(grpcServer, rpctransact.NewTransactServer(transactor, txCodec))
 
-				pbevents.RegisterExecutionEventsServer(grpcServer, rpcevents.NewExecutionEventsServer(state, emitter,
-					blockchain.Tip))
+				rpcevents.RegisterExecutionEventsServer(grpcServer, rpcevents.NewExecutionEventsServer(state, emitter,
+					blockchain.Tip, logger))
 
 				// Provides metadata about services registered
-				reflection.Register(grpcServer)
+				//reflection.Register(grpcServer)
 
 				go grpcServer.Serve(listen)
 
@@ -267,16 +240,13 @@ func NewKernel(ctx context.Context, keyClient keys.KeyClient, privValidator tm_t
 		},
 	}
 
-	return &Kernel{
-		Emitter:        emitter,
-		Service:        service,
-		Launchers:      launchers,
-		State:          state,
-		Blockchain:     blockchain,
-		Logger:         logger,
-		processes:      make(map[string]process.Process),
-		shutdownNotify: make(chan struct{}),
-	}, nil
+	kern.Emitter = emitter
+	kern.Service = service
+	kern.Launchers = launchers
+	kern.State = state
+	kern.Blockchain = blockchain
+	kern.Logger = logger
+	return kern, nil
 }
 
 // Boot the kernel starting Tendermint and RPC layers
@@ -295,6 +265,12 @@ func (kern *Kernel) Boot() error {
 	return nil
 }
 
+func (kern *Kernel) Panic(err error) {
+	fmt.Fprintf(os.Stderr, "Kernel shutting down due to panic: %v", err)
+	kern.Shutdown(context.Background())
+	os.Exit(1)
+}
+
 // Wait for a graceful shutdown
 func (kern *Kernel) WaitForShutdown() {
 	// Supports multiple goroutines waiting for shutdown since channel is closed
diff --git a/crypto/address.go b/crypto/address.go
index a72f8c02d9d4456d4e638780d902c0e3ecc09123..9dab201555b8262b792bcfc3328ba81100c7ae3b 100644
--- a/crypto/address.go
+++ b/crypto/address.go
@@ -120,6 +120,35 @@ func (address *Address) UnmarshalText(text []byte) error {
 
 func (address Address) MarshalText() ([]byte, error) {
 	return ([]byte)(hex.EncodeUpperToString(address[:])), nil
+
+}
+
+// Gogo proto support
+func (address *Address) Marshal() ([]byte, error) {
+	if address == nil {
+		return nil, nil
+	}
+	return address.Bytes(), nil
+}
+
+func (address *Address) Unmarshal(data []byte) error {
+	if len(data) == 0 {
+		return nil
+	}
+	if len(data) != binary.Word160Length {
+		return fmt.Errorf("error unmarshallling address '%X' from bytes: %d bytes but should have %d bytes",
+			data, len(data), binary.Word160Length)
+	}
+	copy(address[:], data)
+	return nil
+}
+
+func (address *Address) MarshalTo(data []byte) (int, error) {
+	return copy(data, address[:]), nil
+}
+
+func (address *Address) Size() int {
+	return binary.Word160Length
 }
 
 func NewContractAddress(caller Address, sequence uint64) (newAddr Address) {
diff --git a/crypto/crypto.go b/crypto/crypto.go
index a1d588e9094571333c531b9d53bb0490112b3cbf..e5f62db1024847f61d3e239ce7322be26cc6ec75 100644
--- a/crypto/crypto.go
+++ b/crypto/crypto.go
@@ -4,7 +4,7 @@ import (
 	"fmt"
 )
 
-type CurveType int8
+type CurveType uint32
 
 const (
 	CurveTypeSecp256k1 CurveType = iota
diff --git a/crypto/crypto.pb.go b/crypto/crypto.pb.go
new file mode 100644
index 0000000000000000000000000000000000000000..230f0f5e5efe55c40feffe0ac493737355a061e3
--- /dev/null
+++ b/crypto/crypto.pb.go
@@ -0,0 +1,555 @@
+// Code generated by protoc-gen-gogo. DO NOT EDIT.
+// source: crypto.proto
+
+/*
+	Package crypto is a generated protocol buffer package.
+
+	It is generated from these files:
+		crypto.proto
+
+	It has these top-level messages:
+		PublicKey
+		PrivateKey
+*/
+package crypto
+
+import proto "github.com/gogo/protobuf/proto"
+import golang_proto "github.com/golang/protobuf/proto"
+import fmt "fmt"
+import math "math"
+import _ "github.com/gogo/protobuf/gogoproto"
+
+import io "io"
+
+// Reference imports to suppress errors if they are not otherwise used.
+var _ = proto.Marshal
+var _ = golang_proto.Marshal
+var _ = fmt.Errorf
+var _ = math.Inf
+
+// This is a compile-time assertion to ensure that this generated file
+// is compatible with the proto package it is being compiled against.
+// A compilation error at this line likely means your copy of the
+// proto package needs to be updated.
+const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package
+
+// PublicKey
+type PublicKey struct {
+	CurveType CurveType `protobuf:"varint,1,opt,name=CurveType,proto3,casttype=CurveType" json:"CurveType,omitempty"`
+	PublicKey []byte    `protobuf:"bytes,2,opt,name=PublicKey,proto3" json:"PublicKey,omitempty"`
+}
+
+func (m *PublicKey) Reset()                    { *m = PublicKey{} }
+func (*PublicKey) ProtoMessage()               {}
+func (*PublicKey) Descriptor() ([]byte, []int) { return fileDescriptorCrypto, []int{0} }
+
+func (m *PublicKey) GetCurveType() CurveType {
+	if m != nil {
+		return m.CurveType
+	}
+	return 0
+}
+
+func (m *PublicKey) GetPublicKey() []byte {
+	if m != nil {
+		return m.PublicKey
+	}
+	return nil
+}
+
+func (*PublicKey) XXX_MessageName() string {
+	return "crypto.PublicKey"
+}
+
+type PrivateKey struct {
+	CurveType CurveType `protobuf:"varint,1,opt,name=CurveType,proto3,casttype=CurveType" json:"CurveType,omitempty"`
+	// Note may need initialisation
+	PublicKey  []byte `protobuf:"bytes,2,opt,name=PublicKey,proto3" json:"PublicKey,omitempty"`
+	PrivateKey []byte `protobuf:"bytes,3,opt,name=PrivateKey,proto3" json:"PrivateKey,omitempty"`
+}
+
+func (m *PrivateKey) Reset()                    { *m = PrivateKey{} }
+func (*PrivateKey) ProtoMessage()               {}
+func (*PrivateKey) Descriptor() ([]byte, []int) { return fileDescriptorCrypto, []int{1} }
+
+func (*PrivateKey) XXX_MessageName() string {
+	return "crypto.PrivateKey"
+}
+func init() {
+	proto.RegisterType((*PublicKey)(nil), "crypto.PublicKey")
+	golang_proto.RegisterType((*PublicKey)(nil), "crypto.PublicKey")
+	proto.RegisterType((*PrivateKey)(nil), "crypto.PrivateKey")
+	golang_proto.RegisterType((*PrivateKey)(nil), "crypto.PrivateKey")
+}
+func (m *PublicKey) Marshal() (dAtA []byte, err error) {
+	size := m.Size()
+	dAtA = make([]byte, size)
+	n, err := m.MarshalTo(dAtA)
+	if err != nil {
+		return nil, err
+	}
+	return dAtA[:n], nil
+}
+
+func (m *PublicKey) MarshalTo(dAtA []byte) (int, error) {
+	var i int
+	_ = i
+	var l int
+	_ = l
+	if m.CurveType != 0 {
+		dAtA[i] = 0x8
+		i++
+		i = encodeVarintCrypto(dAtA, i, uint64(m.CurveType))
+	}
+	if len(m.PublicKey) > 0 {
+		dAtA[i] = 0x12
+		i++
+		i = encodeVarintCrypto(dAtA, i, uint64(len(m.PublicKey)))
+		i += copy(dAtA[i:], m.PublicKey)
+	}
+	return i, nil
+}
+
+func (m *PrivateKey) Marshal() (dAtA []byte, err error) {
+	size := m.Size()
+	dAtA = make([]byte, size)
+	n, err := m.MarshalTo(dAtA)
+	if err != nil {
+		return nil, err
+	}
+	return dAtA[:n], nil
+}
+
+func (m *PrivateKey) MarshalTo(dAtA []byte) (int, error) {
+	var i int
+	_ = i
+	var l int
+	_ = l
+	if m.CurveType != 0 {
+		dAtA[i] = 0x8
+		i++
+		i = encodeVarintCrypto(dAtA, i, uint64(m.CurveType))
+	}
+	if len(m.PublicKey) > 0 {
+		dAtA[i] = 0x12
+		i++
+		i = encodeVarintCrypto(dAtA, i, uint64(len(m.PublicKey)))
+		i += copy(dAtA[i:], m.PublicKey)
+	}
+	if len(m.PrivateKey) > 0 {
+		dAtA[i] = 0x1a
+		i++
+		i = encodeVarintCrypto(dAtA, i, uint64(len(m.PrivateKey)))
+		i += copy(dAtA[i:], m.PrivateKey)
+	}
+	return i, nil
+}
+
+func encodeVarintCrypto(dAtA []byte, offset int, v uint64) int {
+	for v >= 1<<7 {
+		dAtA[offset] = uint8(v&0x7f | 0x80)
+		v >>= 7
+		offset++
+	}
+	dAtA[offset] = uint8(v)
+	return offset + 1
+}
+func (m *PublicKey) Size() (n int) {
+	var l int
+	_ = l
+	if m.CurveType != 0 {
+		n += 1 + sovCrypto(uint64(m.CurveType))
+	}
+	l = len(m.PublicKey)
+	if l > 0 {
+		n += 1 + l + sovCrypto(uint64(l))
+	}
+	return n
+}
+
+func (m *PrivateKey) Size() (n int) {
+	var l int
+	_ = l
+	if m.CurveType != 0 {
+		n += 1 + sovCrypto(uint64(m.CurveType))
+	}
+	l = len(m.PublicKey)
+	if l > 0 {
+		n += 1 + l + sovCrypto(uint64(l))
+	}
+	l = len(m.PrivateKey)
+	if l > 0 {
+		n += 1 + l + sovCrypto(uint64(l))
+	}
+	return n
+}
+
+func sovCrypto(x uint64) (n int) {
+	for {
+		n++
+		x >>= 7
+		if x == 0 {
+			break
+		}
+	}
+	return n
+}
+func sozCrypto(x uint64) (n int) {
+	return sovCrypto(uint64((x << 1) ^ uint64((int64(x) >> 63))))
+}
+func (m *PublicKey) Unmarshal(dAtA []byte) error {
+	l := len(dAtA)
+	iNdEx := 0
+	for iNdEx < l {
+		preIndex := iNdEx
+		var wire uint64
+		for shift := uint(0); ; shift += 7 {
+			if shift >= 64 {
+				return ErrIntOverflowCrypto
+			}
+			if iNdEx >= l {
+				return io.ErrUnexpectedEOF
+			}
+			b := dAtA[iNdEx]
+			iNdEx++
+			wire |= (uint64(b) & 0x7F) << shift
+			if b < 0x80 {
+				break
+			}
+		}
+		fieldNum := int32(wire >> 3)
+		wireType := int(wire & 0x7)
+		if wireType == 4 {
+			return fmt.Errorf("proto: PublicKey: wiretype end group for non-group")
+		}
+		if fieldNum <= 0 {
+			return fmt.Errorf("proto: PublicKey: illegal tag %d (wire type %d)", fieldNum, wire)
+		}
+		switch fieldNum {
+		case 1:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field CurveType", wireType)
+			}
+			m.CurveType = 0
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowCrypto
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				m.CurveType |= (CurveType(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+		case 2:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field PublicKey", wireType)
+			}
+			var byteLen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowCrypto
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				byteLen |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if byteLen < 0 {
+				return ErrInvalidLengthCrypto
+			}
+			postIndex := iNdEx + byteLen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			m.PublicKey = append(m.PublicKey[:0], dAtA[iNdEx:postIndex]...)
+			if m.PublicKey == nil {
+				m.PublicKey = []byte{}
+			}
+			iNdEx = postIndex
+		default:
+			iNdEx = preIndex
+			skippy, err := skipCrypto(dAtA[iNdEx:])
+			if err != nil {
+				return err
+			}
+			if skippy < 0 {
+				return ErrInvalidLengthCrypto
+			}
+			if (iNdEx + skippy) > l {
+				return io.ErrUnexpectedEOF
+			}
+			iNdEx += skippy
+		}
+	}
+
+	if iNdEx > l {
+		return io.ErrUnexpectedEOF
+	}
+	return nil
+}
+func (m *PrivateKey) Unmarshal(dAtA []byte) error {
+	l := len(dAtA)
+	iNdEx := 0
+	for iNdEx < l {
+		preIndex := iNdEx
+		var wire uint64
+		for shift := uint(0); ; shift += 7 {
+			if shift >= 64 {
+				return ErrIntOverflowCrypto
+			}
+			if iNdEx >= l {
+				return io.ErrUnexpectedEOF
+			}
+			b := dAtA[iNdEx]
+			iNdEx++
+			wire |= (uint64(b) & 0x7F) << shift
+			if b < 0x80 {
+				break
+			}
+		}
+		fieldNum := int32(wire >> 3)
+		wireType := int(wire & 0x7)
+		if wireType == 4 {
+			return fmt.Errorf("proto: PrivateKey: wiretype end group for non-group")
+		}
+		if fieldNum <= 0 {
+			return fmt.Errorf("proto: PrivateKey: illegal tag %d (wire type %d)", fieldNum, wire)
+		}
+		switch fieldNum {
+		case 1:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field CurveType", wireType)
+			}
+			m.CurveType = 0
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowCrypto
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				m.CurveType |= (CurveType(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+		case 2:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field PublicKey", wireType)
+			}
+			var byteLen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowCrypto
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				byteLen |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if byteLen < 0 {
+				return ErrInvalidLengthCrypto
+			}
+			postIndex := iNdEx + byteLen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			m.PublicKey = append(m.PublicKey[:0], dAtA[iNdEx:postIndex]...)
+			if m.PublicKey == nil {
+				m.PublicKey = []byte{}
+			}
+			iNdEx = postIndex
+		case 3:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field PrivateKey", wireType)
+			}
+			var byteLen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowCrypto
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				byteLen |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if byteLen < 0 {
+				return ErrInvalidLengthCrypto
+			}
+			postIndex := iNdEx + byteLen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			m.PrivateKey = append(m.PrivateKey[:0], dAtA[iNdEx:postIndex]...)
+			if m.PrivateKey == nil {
+				m.PrivateKey = []byte{}
+			}
+			iNdEx = postIndex
+		default:
+			iNdEx = preIndex
+			skippy, err := skipCrypto(dAtA[iNdEx:])
+			if err != nil {
+				return err
+			}
+			if skippy < 0 {
+				return ErrInvalidLengthCrypto
+			}
+			if (iNdEx + skippy) > l {
+				return io.ErrUnexpectedEOF
+			}
+			iNdEx += skippy
+		}
+	}
+
+	if iNdEx > l {
+		return io.ErrUnexpectedEOF
+	}
+	return nil
+}
+func skipCrypto(dAtA []byte) (n int, err error) {
+	l := len(dAtA)
+	iNdEx := 0
+	for iNdEx < l {
+		var wire uint64
+		for shift := uint(0); ; shift += 7 {
+			if shift >= 64 {
+				return 0, ErrIntOverflowCrypto
+			}
+			if iNdEx >= l {
+				return 0, io.ErrUnexpectedEOF
+			}
+			b := dAtA[iNdEx]
+			iNdEx++
+			wire |= (uint64(b) & 0x7F) << shift
+			if b < 0x80 {
+				break
+			}
+		}
+		wireType := int(wire & 0x7)
+		switch wireType {
+		case 0:
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return 0, ErrIntOverflowCrypto
+				}
+				if iNdEx >= l {
+					return 0, io.ErrUnexpectedEOF
+				}
+				iNdEx++
+				if dAtA[iNdEx-1] < 0x80 {
+					break
+				}
+			}
+			return iNdEx, nil
+		case 1:
+			iNdEx += 8
+			return iNdEx, nil
+		case 2:
+			var length int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return 0, ErrIntOverflowCrypto
+				}
+				if iNdEx >= l {
+					return 0, io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				length |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			iNdEx += length
+			if length < 0 {
+				return 0, ErrInvalidLengthCrypto
+			}
+			return iNdEx, nil
+		case 3:
+			for {
+				var innerWire uint64
+				var start int = iNdEx
+				for shift := uint(0); ; shift += 7 {
+					if shift >= 64 {
+						return 0, ErrIntOverflowCrypto
+					}
+					if iNdEx >= l {
+						return 0, io.ErrUnexpectedEOF
+					}
+					b := dAtA[iNdEx]
+					iNdEx++
+					innerWire |= (uint64(b) & 0x7F) << shift
+					if b < 0x80 {
+						break
+					}
+				}
+				innerWireType := int(innerWire & 0x7)
+				if innerWireType == 4 {
+					break
+				}
+				next, err := skipCrypto(dAtA[start:])
+				if err != nil {
+					return 0, err
+				}
+				iNdEx = start + next
+			}
+			return iNdEx, nil
+		case 4:
+			return iNdEx, nil
+		case 5:
+			iNdEx += 4
+			return iNdEx, nil
+		default:
+			return 0, fmt.Errorf("proto: illegal wireType %d", wireType)
+		}
+	}
+	panic("unreachable")
+}
+
+var (
+	ErrInvalidLengthCrypto = fmt.Errorf("proto: negative length found during unmarshaling")
+	ErrIntOverflowCrypto   = fmt.Errorf("proto: integer overflow")
+)
+
+func init() { proto.RegisterFile("crypto.proto", fileDescriptorCrypto) }
+func init() { golang_proto.RegisterFile("crypto.proto", fileDescriptorCrypto) }
+
+var fileDescriptorCrypto = []byte{
+	// 221 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0x49, 0x2e, 0xaa, 0x2c,
+	0x28, 0xc9, 0xd7, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, 0x83, 0xf0, 0xa4, 0x74, 0xd3, 0x33,
+	0x4b, 0x32, 0x4a, 0x93, 0xf4, 0x92, 0xf3, 0x73, 0xf5, 0xd3, 0xf3, 0xd3, 0xf3, 0xf5, 0xc1, 0xd2,
+	0x49, 0xa5, 0x69, 0x60, 0x1e, 0x98, 0x03, 0x66, 0x41, 0xb4, 0x29, 0xc5, 0x70, 0x71, 0x06, 0x94,
+	0x26, 0xe5, 0x64, 0x26, 0x7b, 0xa7, 0x56, 0x0a, 0x69, 0x73, 0x71, 0x3a, 0x97, 0x16, 0x95, 0xa5,
+	0x86, 0x54, 0x16, 0xa4, 0x4a, 0x30, 0x2a, 0x30, 0x6a, 0xf0, 0x3a, 0xf1, 0xfe, 0xba, 0x27, 0x8f,
+	0x10, 0x0c, 0x42, 0x30, 0x85, 0x64, 0x90, 0x74, 0x4a, 0x30, 0x29, 0x30, 0x6a, 0xf0, 0x04, 0x21,
+	0x04, 0xac, 0x58, 0x66, 0x2c, 0x90, 0x67, 0x50, 0x6a, 0x64, 0xe4, 0xe2, 0x0a, 0x28, 0xca, 0x2c,
+	0x4b, 0x2c, 0x49, 0xa5, 0xae, 0xf9, 0x42, 0x72, 0xc8, 0x06, 0x4b, 0x30, 0x83, 0xa5, 0x91, 0x44,
+	0xac, 0x38, 0x3a, 0x16, 0xc8, 0x33, 0x80, 0xdc, 0xe0, 0x64, 0x75, 0xe2, 0x91, 0x1c, 0xe3, 0x85,
+	0x47, 0x72, 0x8c, 0x0f, 0x1e, 0xc9, 0x31, 0x1e, 0x78, 0x2c, 0xc7, 0x78, 0xe2, 0xb1, 0x1c, 0x63,
+	0x94, 0x0a, 0x52, 0x30, 0x65, 0x54, 0x16, 0xa4, 0x16, 0xe5, 0xa4, 0xa6, 0xa4, 0xa7, 0x16, 0xe9,
+	0x27, 0x95, 0x16, 0x15, 0xe5, 0x97, 0xeb, 0x43, 0x02, 0x33, 0x89, 0x0d, 0x1c, 0x48, 0xc6, 0x80,
+	0x00, 0x00, 0x00, 0xff, 0xff, 0x5f, 0x49, 0x55, 0xc8, 0x6b, 0x01, 0x00, 0x00,
+}
diff --git a/crypto/private_key.go b/crypto/private_key.go
index f1bad18969e89de0d4882a293e6f2b0117a19709..91252e09f1e1543921e108962db1291d7cd820af 100644
--- a/crypto/private_key.go
+++ b/crypto/private_key.go
@@ -11,12 +11,6 @@ import (
 	"golang.org/x/crypto/ed25519"
 )
 
-type PrivateKey struct {
-	CurveType  CurveType
-	PublicKey  []byte
-	PrivateKey []byte
-}
-
 // Currently this is a stub that reads the raw bytes returned by key_client and returns
 // an ed25519 public key.
 func PublicKeyFromBytes(bs []byte, curveType CurveType) (PublicKey, error) {
@@ -46,25 +40,25 @@ func (p PrivateKey) Sign(msg []byte) (Signature, error) {
 	switch p.CurveType {
 	case CurveTypeEd25519:
 		if len(p.PrivateKey) != ed25519.PrivateKeySize {
-			return Signature{}, fmt.Errorf("bytes passed have length %v but ed25519 private keys have %v bytes",
+			return nil, fmt.Errorf("bytes passed have length %v but ed25519 private keys have %v bytes",
 				len(p.PrivateKey), ed25519.PrivateKeySize)
 		}
 		privKey := ed25519.PrivateKey(p.PrivateKey)
-		return Signature{ed25519.Sign(privKey, msg)}, nil
+		return ed25519.Sign(privKey, msg), nil
 	case CurveTypeSecp256k1:
 		if len(p.PrivateKey) != btcec.PrivKeyBytesLen {
-			return Signature{}, fmt.Errorf("bytes passed have length %v but secp256k1 private keys have %v bytes",
+			return nil, fmt.Errorf("bytes passed have length %v but secp256k1 private keys have %v bytes",
 				len(p.PrivateKey), btcec.PrivKeyBytesLen)
 		}
 		privKey, _ := btcec.PrivKeyFromBytes(btcec.S256(), p.PrivateKey)
 
 		sig, err := privKey.Sign(msg)
 		if err != nil {
-			return Signature{}, err
+			return nil, err
 		}
-		return Signature{Signature: sig.Serialize()}, nil
+		return sig.Serialize(), nil
 	default:
-		return Signature{}, ErrInvalidCurve(p.CurveType)
+		return nil, ErrInvalidCurve(p.CurveType)
 	}
 }
 
@@ -72,6 +66,20 @@ func (p PrivateKey) GetPublicKey() PublicKey {
 	return PublicKey{CurveType: p.CurveType, PublicKey: p.PublicKey}
 }
 
+// Reinitialise after serialisation
+func (p *PrivateKey) Reinitialise() error {
+	initP, err := PrivateKeyFromRawBytes(p.RawBytes(), p.CurveType)
+	if err != nil {
+		return err
+	}
+	*p = initP
+	return nil
+}
+
+func (p PrivateKey) String() string {
+	return fmt.Sprintf("PrivateKey<PublicKey:%X>", p.PublicKey)
+}
+
 func PrivateKeyFromRawBytes(privKeyBytes []byte, curveType CurveType) (PrivateKey, error) {
 	switch curveType {
 	case CurveTypeEd25519:
@@ -86,7 +94,10 @@ func PrivateKeyFromRawBytes(privKeyBytes []byte, curveType CurveType) (PrivateKe
 				len(privKeyBytes), btcec.PrivKeyBytesLen)
 		}
 		privKey, pubKey := btcec.PrivKeyFromBytes(btcec.S256(), privKeyBytes)
-		return PrivateKey{PrivateKey: privKey.Serialize(), PublicKey: pubKey.SerializeCompressed(), CurveType: CurveTypeSecp256k1}, nil
+		if !bytes.Equal(privKey.Serialize(), privKeyBytes) {
+			return PrivateKey{}, fmt.Errorf("serialisation of Secp256k1 private key bytes does not equal")
+		}
+		return PrivateKey{PrivateKey: privKeyBytes, PublicKey: pubKey.SerializeCompressed(), CurveType: CurveTypeSecp256k1}, nil
 	default:
 		return PrivateKey{}, ErrInvalidCurve(curveType)
 	}
diff --git a/crypto/public_key.go b/crypto/public_key.go
index b3281c61fceaae826678264145a6ec7aa830e7ea..f837b38d1a27a201b4c5affe1101b9dc0bf78b0b 100644
--- a/crypto/public_key.go
+++ b/crypto/public_key.go
@@ -13,14 +13,6 @@ import (
 	"golang.org/x/crypto/ripemd160"
 )
 
-// PublicKey
-type PublicKey struct {
-	CurveType CurveType
-	PublicKey []byte
-	// memoised address
-	address *Address
-}
-
 type PublicKeyJSON struct {
 	CurveType string
 	PublicKey string
@@ -83,13 +75,13 @@ func (p PublicKey) IsValid() bool {
 func (p PublicKey) Verify(msg []byte, signature Signature) bool {
 	switch p.CurveType {
 	case CurveTypeEd25519:
-		return ed25519.Verify(p.PublicKey, msg, signature.Signature[:])
+		return ed25519.Verify(p.PublicKey, msg, signature)
 	case CurveTypeSecp256k1:
 		pub, err := btcec.ParsePubKey(p.PublicKey, btcec.S256())
 		if err != nil {
 			return false
 		}
-		sig, err := btcec.ParseDERSignature(signature.Signature, btcec.S256())
+		sig, err := btcec.ParseDERSignature(signature, btcec.S256())
 		if err != nil {
 			return false
 		}
@@ -100,14 +92,6 @@ func (p PublicKey) Verify(msg []byte, signature Signature) bool {
 }
 
 func (p PublicKey) Address() Address {
-	if p.address == nil {
-		address := p.computeAddress()
-		p.address = &address
-	}
-	return *p.address
-}
-
-func (p PublicKey) computeAddress() Address {
 	switch p.CurveType {
 	case CurveTypeEd25519:
 		// FIMXE: tendermint go-crypto-0.5.0 uses weird scheme, this is fixed in 0.6.0
diff --git a/crypto/public_key_test.go b/crypto/public_key_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..f6c211a35d2c64de9050ab75a689fb85881bdf33
--- /dev/null
+++ b/crypto/public_key_test.go
@@ -0,0 +1,30 @@
+package crypto
+
+import (
+	"encoding/json"
+	"testing"
+
+	"github.com/gogo/protobuf/proto"
+	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/require"
+)
+
+func TestPublicKeySerialisation(t *testing.T) {
+	priv := PrivateKeyFromSecret("foo", CurveTypeEd25519)
+	pub := priv.GetPublicKey()
+	expectedAddress := Address{
+		0x83, 0x20, 0x78, 0x17, 0xdc, 0x38, 0x14, 0xb9, 0x6f, 0x57,
+		0xef, 0xf9, 0x25, 0xf4, 0x67, 0xe0, 0x7c, 0xaa, 0x91, 0x38,
+	}
+	assert.Equal(t, expectedAddress, pub.Address())
+	bs, err := proto.Marshal(&pub)
+	require.NoError(t, err)
+	var pubOut PublicKey
+	err = proto.Unmarshal(bs, &pubOut)
+	assert.Equal(t, pub, pubOut)
+
+	bs, err = json.Marshal(pub)
+	require.NoError(t, err)
+	assert.Equal(t, `{"CurveType":"ed25519","PublicKey":"34D26579DBB456693E540672CF922F52DDE0D6532E35BF06BE013A7C532F20E0"}`,
+		string(bs))
+}
diff --git a/crypto/signature.go b/crypto/signature.go
index 0ef84f4619ec6f63f7e69159549b143275f994f5..be11336ee7bd2c8052dcb9834c8d33b47f15ccf3 100644
--- a/crypto/signature.go
+++ b/crypto/signature.go
@@ -3,37 +3,64 @@ package crypto
 import (
 	"fmt"
 
-	"github.com/hyperledger/burrow/binary"
+	"github.com/tmthrgd/go-hex"
 	"golang.org/x/crypto/ed25519"
 )
 
-type Signature struct {
-	Signature binary.HexBytes
-}
+type Signature []byte
 
-// Currently this is a stub that reads the raw bytes returned by key_client and returns
-// an ed25519 signature.
 func SignatureFromBytes(bs []byte, curveType CurveType) (Signature, error) {
 	switch curveType {
 	case CurveTypeEd25519:
-		signatureEd25519 := Signature{}
+		var signatureEd25519 Signature
 		if len(bs) != ed25519.SignatureSize {
-			return Signature{}, fmt.Errorf("bytes passed have length %v by ed25519 signatures have %v bytes",
+			return nil, fmt.Errorf("bytes passed have length %v by ed25519 signatures have %v bytes",
 				len(bs), ed25519.SignatureSize)
 		}
-		copy(signatureEd25519.Signature[:], bs)
-		return Signature{
-			Signature: bs,
-		}, nil
+		copy(signatureEd25519, bs)
+		return bs, nil
 	case CurveTypeSecp256k1:
-		return Signature{
-			Signature: bs,
-		}, nil
+		return bs, nil
 	default:
-		return Signature{}, nil
+		return nil, nil
 	}
 }
 
 func (sig Signature) RawBytes() []byte {
-	return sig.Signature
+	return sig
+}
+
+func (sig *Signature) UnmarshalText(hexBytes []byte) error {
+	bs, err := hex.DecodeString(string(hexBytes))
+	if err != nil {
+		return err
+	}
+	*sig = bs
+	return nil
+}
+
+func (sig Signature) MarshalText() ([]byte, error) {
+	return []byte(sig.String()), nil
+}
+
+func (sig Signature) String() string {
+	return hex.EncodeUpperToString(sig)
+}
+
+// Protobuf support
+func (sig Signature) Marshal() ([]byte, error) {
+	return sig, nil
+}
+
+func (sig *Signature) Unmarshal(data []byte) error {
+	*sig = data
+	return nil
+}
+
+func (sig Signature) MarshalTo(data []byte) (int, error) {
+	return copy(data, sig), nil
+}
+
+func (sig Signature) Size() int {
+	return len(sig)
 }
diff --git a/deployment/config.go b/deployment/config.go
index dc70796d6595948bfc62268b2274163e1a045e2e..ff935f05d2af150d174b35d94866477a5157d6f3 100644
--- a/deployment/config.go
+++ b/deployment/config.go
@@ -11,8 +11,8 @@ import (
 	"github.com/hyperledger/burrow/crypto"
 	"github.com/hyperledger/burrow/genesis"
 	"github.com/pkg/errors"
-	"github.com/tmthrgd/go-hex"
-	"gopkg.in/yaml.v2"
+	hex "github.com/tmthrgd/go-hex"
+	yaml "gopkg.in/yaml.v2"
 )
 
 type Validator struct {
diff --git a/event/cache.go b/event/cache.go
deleted file mode 100644
index 75f676cfc1333daaabd7520f5a69b68e43b68cea..0000000000000000000000000000000000000000
--- a/event/cache.go
+++ /dev/null
@@ -1,88 +0,0 @@
-package event
-
-import (
-	"context"
-)
-
-// When exceeded we will trim the buffer's backing array capacity to avoid excessive
-// allocation
-const maximumBufferCapacityToLengthRatio = 2
-
-// A Cache buffers events for a Publisher.
-type Cache struct {
-	events []messageInfo
-}
-
-// If message implement this interface we will provide them with an index in the cache
-type Indexable interface {
-	ProvideIndex(index uint64)
-}
-
-var _ Publisher = &Cache{}
-
-// Create a new Cache with an EventSwitch as backend
-func NewCache() *Cache {
-	return &Cache{}
-}
-
-// a cached event
-type messageInfo struct {
-	// Hmm... might be unintended interactions with pushing a deadline into a cache - though usually we publish with an
-	// empty context
-	ctx     context.Context
-	message interface{}
-	tags    Tags
-}
-
-// Cache an event to be fired upon finality.
-func (evc *Cache) Publish(ctx context.Context, message interface{}, tags Tags) error {
-	// append to list (go will grow our backing array exponentially)
-	evc.events = append(evc.events, messageInfo{
-		ctx:     ctx,
-		message: evc.provideIndex(message),
-		tags:    tags,
-	})
-	return nil
-}
-
-func (evc *Cache) Flush(publisher Publisher) error {
-	err := evc.Sync(publisher)
-	if err != nil {
-		return err
-	}
-	evc.Reset()
-	return nil
-}
-
-// Clears cached events by flushing them to Publisher
-func (evc *Cache) Sync(publisher Publisher) error {
-	var err error
-	for _, mi := range evc.events {
-		publishErr := publisher.Publish(mi.ctx, mi.message, mi.tags)
-		// Capture first by try to sync the rest
-		if publishErr != nil && err == nil {
-			err = publishErr
-		}
-	}
-	return err
-}
-
-func (evc *Cache) Reset() {
-	// Clear the buffer by re-slicing its length to zero
-	if cap(evc.events) > len(evc.events)*maximumBufferCapacityToLengthRatio {
-		// Trim the backing array capacity when it is more than double the length of the slice to avoid tying up memory
-		// after a spike in the number of events to buffer
-		evc.events = evc.events[:0:len(evc.events)]
-	} else {
-		// Re-slice the length to 0 to clear buffer but hang on to spare capacity in backing array that has been added
-		// in previous cache round
-		evc.events = evc.events[:0]
-	}
-}
-
-func (evc *Cache) provideIndex(message interface{}) interface{} {
-	if im, ok := message.(Indexable); ok {
-		im.ProvideIndex(uint64(len(evc.events)))
-	}
-	return message
-}
diff --git a/event/cache_test.go b/event/cache_test.go
deleted file mode 100644
index 52bcbd6640a0f7008caf061cc504eb6cdfec00d6..0000000000000000000000000000000000000000
--- a/event/cache_test.go
+++ /dev/null
@@ -1,98 +0,0 @@
-package event
-
-import (
-	"context"
-	"fmt"
-	"testing"
-	"time"
-
-	"github.com/hyperledger/burrow/event/query"
-	"github.com/hyperledger/burrow/logging"
-	"github.com/stretchr/testify/assert"
-)
-
-func TestEventCache_Flush(t *testing.T) {
-	//ctx, cancel := context.WithTimeout(context.Background(), 5 * time.Second)
-	//defer cancel()
-	ctx := context.Background()
-	errCh := make(chan error)
-	flushed := false
-
-	em := NewEmitter(logging.NewNoopLogger())
-	SubscribeCallback(ctx, em, "nothingness", query.NewBuilder(), func(message interface{}) (stop bool) {
-		// Check against sending a buffer of zeroed messages
-		if message == nil {
-			errCh <- fmt.Errorf("recevied empty message but none sent")
-		}
-		return true
-	})
-	evc := NewCache()
-	evc.Flush(em)
-	// Check after reset
-	evc.Flush(em)
-	SubscribeCallback(ctx, em, "somethingness", query.NewBuilder().AndEquals("foo", "bar"),
-		func(interface{}) (stop bool) {
-			if flushed {
-				errCh <- nil
-				return false
-			} else {
-				errCh <- fmt.Errorf("callback was run before messages were flushed")
-				return true
-			}
-		})
-
-	numMessages := 3
-	tags := TagMap{"foo": "bar"}
-	for i := 0; i < numMessages; i++ {
-		evc.Publish(ctx, fmt.Sprintf("something_%v", i), tags)
-	}
-	flushed = true
-	evc.Flush(em)
-	for i := 0; i < numMessages; i++ {
-		select {
-		case <-time.After(2 * time.Second):
-			t.Fatalf("callback did not run before timeout after messages were sent")
-		case err := <-errCh:
-			if err != nil {
-				t.Error(err)
-			}
-		}
-	}
-}
-
-func TestEventCacheGrowth(t *testing.T) {
-	em := NewEmitter(logging.NewNoopLogger())
-	evc := NewCache()
-
-	fireNEvents(evc, 100)
-	c := cap(evc.events)
-	evc.Flush(em)
-	assert.Equal(t, c, cap(evc.events), "cache cap should remain the same after flushing events")
-
-	fireNEvents(evc, c/maximumBufferCapacityToLengthRatio+1)
-	evc.Flush(em)
-	assert.Equal(t, c, cap(evc.events), "cache cap should remain the same after flushing more than half "+
-		"the number of events as last time")
-
-	fireNEvents(evc, c/maximumBufferCapacityToLengthRatio-1)
-	evc.Flush(em)
-	assert.True(t, c > cap(evc.events), "cache cap should drop after flushing fewer than half "+
-		"the number of events as last time")
-
-	fireNEvents(evc, c*2*maximumBufferCapacityToLengthRatio)
-	evc.Flush(em)
-	assert.True(t, c < cap(evc.events), "cache cap should grow after flushing more events than seen before")
-
-	for numEvents := 100; numEvents >= 0; numEvents-- {
-		fireNEvents(evc, numEvents)
-		evc.Flush(em)
-		assert.True(t, cap(evc.events) <= maximumBufferCapacityToLengthRatio*numEvents,
-			"cap (%v) should be at most twice numEvents (%v)", cap(evc.events), numEvents)
-	}
-}
-
-func fireNEvents(evc *Cache, n int) {
-	for i := 0; i < n; i++ {
-		evc.Publish(context.Background(), "something", nil)
-	}
-}
diff --git a/event/convention.go b/event/convention.go
index dede8493bbc98eba5ada4947d3e0816d857f8714..4f586c152b847c8d46672256d7ed06865f0b1471 100644
--- a/event/convention.go
+++ b/event/convention.go
@@ -1,12 +1,6 @@
 package event
 
 import (
-	"context"
-
-	"time"
-
-	"fmt"
-
 	"github.com/hyperledger/burrow/event/query"
 )
 
@@ -14,88 +8,15 @@ const (
 	EventTypeKey   = "EventType"
 	EventIDKey     = "EventID"
 	MessageTypeKey = "MessageType"
-	TxTypeKey      = "TxType"
 	TxHashKey      = "TxHash"
 	HeightKey      = "Height"
 	IndexKey       = "Index"
-	NameKey        = "Name"
-	PermissionKey  = "Permission"
 	StackDepthKey  = "StackDepth"
 	AddressKey     = "Address"
-	OriginKey      = "Origin"
-	CalleeKey      = "Callee"
-	CallerKey      = "Caller"
-	ValueKey       = "Value"
-	GasKey         = "Gas"
-	ExceptionKey   = "Exception"
-	LogNKeyPrefix  = "Log"
 )
 
-func LogNKey(topic int) string {
-	return fmt.Sprintf("%s%d", LogNKeyPrefix, topic)
-}
-
-func LogNTextKey(topic int) string {
-	return fmt.Sprintf("%s%dText", LogNKeyPrefix, topic)
-}
-
-const SubscribeCallbackTimeout = 2 * time.Second
-
 // Get a query that matches events with a specific eventID
 func QueryForEventID(eventID string) *query.Builder {
 	// Since we're accepting external output here there is a chance it won't parse...
 	return query.NewBuilder().AndEquals(EventIDKey, eventID)
 }
-
-// Subscribe to messages matching query and launch a goroutine to run a callback for each one. The goroutine will exit
-// if the callback returns true for 'stop' and clean up the subscription and channel.
-func SubscribeCallback(ctx context.Context, subscribable Subscribable, subscriber string, queryable query.Queryable,
-	callback func(message interface{}) (stop bool)) error {
-
-	out := make(chan interface{}, 1)
-	stopCh := make(chan bool)
-
-	go func() {
-		for msg := range out {
-			go func() {
-				stopCh <- callback(msg)
-			}()
-
-			// Stop unless the callback returns
-			stop := true
-			select {
-			case stop = <-stopCh:
-			case <-time.After(SubscribeCallbackTimeout):
-			}
-
-			if stop {
-				// Callback is requesting stop so unsubscribe and drain channel
-				subscribable.Unsubscribe(context.Background(), subscriber, queryable)
-				// Not draining channel can starve other subscribers
-				for range out {
-				}
-				return
-			}
-		}
-	}()
-	err := subscribable.Subscribe(ctx, subscriber, queryable, out)
-	if err != nil {
-		// To clean up goroutine - otherwise subscribable should close channel for us
-		close(out)
-	}
-	return err
-}
-
-func PublishAll(ctx context.Context, subscribable Subscribable, subscriber string, queryable query.Queryable,
-	publisher Publisher, extraTags map[string]interface{}) error {
-
-	return SubscribeCallback(ctx, subscribable, subscriber, queryable, func(message interface{}) (stop bool) {
-		tags := make(map[string]interface{})
-		for k, v := range extraTags {
-			tags[k] = v
-		}
-		// Help! I can't tell which tags the original publisher used - so I can't forward them on
-		publisher.Publish(ctx, message, TagMap(tags))
-		return
-	})
-}
diff --git a/event/convention_test.go b/event/convention_test.go
deleted file mode 100644
index 2fd0202dee11da929840814755b45e4f87e57842..0000000000000000000000000000000000000000
--- a/event/convention_test.go
+++ /dev/null
@@ -1,39 +0,0 @@
-package event
-
-import (
-	"context"
-	"testing"
-	"time"
-
-	"github.com/hyperledger/burrow/event/query"
-	"github.com/hyperledger/burrow/logging"
-	"github.com/stretchr/testify/assert"
-)
-
-func TestSubscribeCallback(t *testing.T) {
-	ctx := context.Background()
-	em := NewEmitter(logging.NewNoopLogger())
-	ch := make(chan interface{})
-	SubscribeCallback(ctx, em, "TestSubscribeCallback", query.MatchAllQueryable(),
-		func(msg interface{}) (stop bool) {
-			ch <- msg
-			return
-		})
-
-	sent := "FROTHY"
-
-	n := 10
-	for i := 0; i < n; i++ {
-
-		em.Publish(ctx, sent, nil)
-	}
-
-	for i := 0; i < n; i++ {
-		select {
-		case <-time.After(2 * time.Second):
-			t.Fatalf("Timed out waiting for event")
-		case msg := <-ch:
-			assert.Equal(t, sent, msg)
-		}
-	}
-}
diff --git a/event/emitter.go b/event/emitter.go
index 1fd09e81a4a0fb5afb61bbc33b57410f4c82ddf4..c4d1fd413aba16c811aa7be9fdb0fa37d269c627 100644
--- a/event/emitter.go
+++ b/event/emitter.go
@@ -16,17 +16,15 @@ package event
 
 import (
 	"context"
-	"crypto/rand"
-	"encoding/hex"
-	"fmt"
-	"strings"
+	"math/rand"
 
+	"github.com/hyperledger/burrow/event/pubsub"
 	"github.com/hyperledger/burrow/event/query"
 	"github.com/hyperledger/burrow/logging"
 	"github.com/hyperledger/burrow/logging/structure"
 	"github.com/hyperledger/burrow/process"
-	"github.com/tendermint/tendermint/libs/pubsub"
 	"github.com/tendermint/tmlibs/common"
+	"github.com/tmthrgd/go-hex"
 )
 
 const DefaultEventBufferCapacity = 2 << 10
@@ -36,21 +34,21 @@ const DefaultEventBufferCapacity = 2 << 10
 type Subscribable interface {
 	// Subscribe to all events matching query, which is a valid tmlibs Query. Blocking the out channel blocks the entire
 	// pubsub.
-	Subscribe(ctx context.Context, subscriber string, queryable query.Queryable, out chan<- interface{}) error
+	Subscribe(ctx context.Context, subscriber string, queryable query.Queryable, bufferSize int) (out <-chan interface{}, err error)
 	// Unsubscribe subscriber from a specific query string. Note the subscribe channel must be drained.
 	Unsubscribe(ctx context.Context, subscriber string, queryable query.Queryable) error
 	UnsubscribeAll(ctx context.Context, subscriber string) error
 }
 
 type Publisher interface {
-	Publish(ctx context.Context, message interface{}, tag Tags) error
+	Publish(ctx context.Context, message interface{}, tag query.Tagged) error
 }
 
 var _ Publisher = PublisherFunc(nil)
 
-type PublisherFunc func(ctx context.Context, message interface{}, tags Tags) error
+type PublisherFunc func(ctx context.Context, message interface{}, tags query.Tagged) error
 
-func (pf PublisherFunc) Publish(ctx context.Context, message interface{}, tags Tags) error {
+func (pf PublisherFunc) Publish(ctx context.Context, message interface{}, tags query.Tagged) error {
 	return pf(ctx, message, tags)
 }
 
@@ -83,17 +81,17 @@ func (em *emitter) Shutdown(ctx context.Context) error {
 }
 
 // Publisher
-func (em *emitter) Publish(ctx context.Context, message interface{}, tags Tags) error {
+func (em *emitter) Publish(ctx context.Context, message interface{}, tags query.Tagged) error {
 	return em.pubsubServer.PublishWithTags(ctx, message, tags)
 }
 
 // Subscribable
-func (em *emitter) Subscribe(ctx context.Context, subscriber string, queryable query.Queryable, out chan<- interface{}) error {
-	pubsubQuery, err := queryable.Query()
+func (em *emitter) Subscribe(ctx context.Context, subscriber string, queryable query.Queryable, bufferSize int) (<-chan interface{}, error) {
+	qry, err := queryable.Query()
 	if err != nil {
-		return nil
+		return nil, err
 	}
-	return em.pubsubServer.Subscribe(ctx, subscriber, pubsubQuery, out)
+	return em.pubsubServer.Subscribe(ctx, subscriber, qry, bufferSize)
 }
 
 func (em *emitter) Unsubscribe(ctx context.Context, subscriber string, queryable query.Queryable) error {
@@ -116,20 +114,15 @@ func NewNoOpPublisher() Publisher {
 type noOpPublisher struct {
 }
 
-func (nop *noOpPublisher) Publish(ctx context.Context, message interface{}, tags Tags) error {
+func (nop *noOpPublisher) Publish(ctx context.Context, message interface{}, tags query.Tagged) error {
 	return nil
 }
 
 // **************************************************************************************
 // Helper function
 
-func GenerateSubscriptionID() (string, error) {
-	b := make([]byte, 32)
-	_, err := rand.Read(b)
-	if err != nil {
-		return "", fmt.Errorf("could not generate random bytes for a subscription"+
-			" id: %v", err)
-	}
-	rStr := hex.EncodeToString(b)
-	return strings.ToUpper(rStr), nil
+func GenSubID() string {
+	bs := make([]byte, 32)
+	rand.Read(bs)
+	return hex.EncodeUpperToString(bs)
 }
diff --git a/event/emitter_test.go b/event/emitter_test.go
index 8325456db81515e406e6705e962ce362b1b110d1..99d8fc76030a2fed7e2c63f3112f695a152a6c95 100644
--- a/event/emitter_test.go
+++ b/event/emitter_test.go
@@ -5,6 +5,8 @@ import (
 	"testing"
 	"time"
 
+	"strings"
+
 	"github.com/hyperledger/burrow/event/query"
 	"github.com/hyperledger/burrow/logging"
 	"github.com/stretchr/testify/assert"
@@ -14,17 +16,16 @@ import (
 func TestEmitter(t *testing.T) {
 	em := NewEmitter(logging.NewNoopLogger())
 	ctx := context.Background()
-	out := make(chan interface{})
 
-	err := em.Subscribe(ctx, "TestEmitter", query.NewBuilder().AndStrictlyGreaterThan("foo", 10), out)
+	out, err := em.Subscribe(ctx, "TestEmitter", query.NewBuilder().AndStrictlyGreaterThan("foo", 10), 1)
 	require.NoError(t, err)
 
 	msgMiss := struct{ flob string }{"flib"}
-	err = em.Publish(ctx, msgMiss, TagMap(map[string]interface{}{"foo": 10}))
+	err = em.Publish(ctx, msgMiss, query.TagMap{"foo": 10})
 	assert.NoError(t, err)
 
 	msgHit := struct{ blib string }{"blab"}
-	err = em.Publish(ctx, msgHit, TagMap(map[string]interface{}{"foo": 11}))
+	err = em.Publish(ctx, msgHit, query.TagMap{"foo": 11})
 	assert.NoError(t, err)
 
 	select {
@@ -38,16 +39,15 @@ func TestEmitter(t *testing.T) {
 func TestOrdering(t *testing.T) {
 	em := NewEmitter(logging.NewNoopLogger())
 	ctx := context.Background()
-	out := make(chan interface{})
 
-	err := em.Subscribe(ctx, "TestOrdering1", query.NewBuilder().AndEquals("foo", "bar"), out)
+	out1, err := em.Subscribe(ctx, "TestOrdering1", query.NewBuilder().AndEquals("foo", "bar"), 10)
 	require.NoError(t, err)
 
-	err = em.Subscribe(ctx, "TestOrdering2", query.NewBuilder().AndEquals("foo", "baz"), out)
+	out2, err := em.Subscribe(ctx, "TestOrdering2", query.NewBuilder().AndEquals("foo", "baz"), 10)
 	require.NoError(t, err)
 
-	barTag := TagMap{"foo": "bar"}
-	bazTag := TagMap{"foo": "baz"}
+	barTag := query.TagMap{"foo": "bar"}
+	bazTag := query.TagMap{"foo": "baz"}
 
 	msgs := [][]interface{}{
 		{"baz1", bazTag},
@@ -61,12 +61,17 @@ func TestOrdering(t *testing.T) {
 
 	go func() {
 		for _, msg := range msgs {
-			em.Publish(ctx, msg[0], msg[1].(TagMap))
+			em.Publish(ctx, msg[0], msg[1].(query.TagMap))
 		}
 		em.Publish(ctx, "stop", bazTag)
 	}()
 
 	for _, msg := range msgs {
-		assert.Equal(t, msg[0], <-out)
+		str := msg[0].(string)
+		if strings.HasPrefix(str, "bar") {
+			assert.Equal(t, str, <-out1)
+		} else {
+			assert.Equal(t, str, <-out2)
+		}
 	}
 }
diff --git a/event/pubsub/example_test.go b/event/pubsub/example_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..68772bd14117be7409f12ecdcb5f87051776d249
--- /dev/null
+++ b/event/pubsub/example_test.go
@@ -0,0 +1,23 @@
+package pubsub_test
+
+import (
+	"context"
+	"testing"
+
+	"github.com/hyperledger/burrow/event/pubsub"
+	"github.com/hyperledger/burrow/event/query"
+	"github.com/stretchr/testify/require"
+)
+
+func TestExample(t *testing.T) {
+	s := pubsub.NewServer()
+	s.Start()
+	defer s.Stop()
+
+	ctx := context.Background()
+	ch, err := s.Subscribe(ctx, "example-client", query.MustParse("abci.account.name='John'"), 1)
+	require.NoError(t, err)
+	err = s.PublishWithTags(ctx, "Tombstone", query.TagMap(map[string]interface{}{"abci.account.name": "John"}))
+	require.NoError(t, err)
+	assertReceive(t, "Tombstone", ch)
+}
diff --git a/event/pubsub/pubsub.go b/event/pubsub/pubsub.go
new file mode 100644
index 0000000000000000000000000000000000000000..8d710773036e6cc828b870c76c83e9be5b69a5a6
--- /dev/null
+++ b/event/pubsub/pubsub.go
@@ -0,0 +1,330 @@
+// This package was extracted from Tendermint
+//
+// Package pubsub implements a pub-sub model with a single publisher (Server)
+// and multiple subscribers (clients).
+//
+// Though you can have multiple publishers by sharing a pointer to a server or
+// by giving the same channel to each publisher and publishing messages from
+// that channel (fan-in).
+//
+// Clients subscribe for messages, which could be of any type, using a query.
+// When some message is published, we match it with all queries. If there is a
+// match, this message will be pushed to all clients, subscribed to that query.
+// See query subpackage for our implementation.
+package pubsub
+
+import (
+	"context"
+	"errors"
+	"sync"
+
+	"github.com/hyperledger/burrow/event/query"
+	"github.com/tendermint/tmlibs/common"
+)
+
+type operation int
+
+const (
+	sub operation = iota
+	pub
+	unsub
+	shutdown
+)
+
+var (
+	// ErrSubscriptionNotFound is returned when a client tries to unsubscribe
+	// from not existing subscription.
+	ErrSubscriptionNotFound = errors.New("subscription not found")
+
+	// ErrAlreadySubscribed is returned when a client tries to subscribe twice or
+	// more using the same query.
+	ErrAlreadySubscribed = errors.New("already subscribed")
+)
+
+type cmd struct {
+	op       operation
+	query    query.Query
+	ch       chan interface{}
+	clientID string
+	msg      interface{}
+	tags     query.Tagged
+}
+
+// Server allows clients to subscribe/unsubscribe for messages, publishing
+// messages with or without tags, and manages internal state.
+type Server struct {
+	common.BaseService
+
+	cmds    chan cmd
+	cmdsCap int
+
+	mtx           sync.RWMutex
+	subscriptions map[string]map[string]query.Query // subscriber -> query (string) -> query.Query
+}
+
+// Option sets a parameter for the server.
+type Option func(*Server)
+
+// NewServer returns a new server. See the commentary on the Option functions
+// for a detailed description of how to configure buffering. If no options are
+// provided, the resulting server's queue is unbuffered.
+func NewServer(options ...Option) *Server {
+	s := &Server{
+		subscriptions: make(map[string]map[string]query.Query),
+	}
+	s.BaseService = *common.NewBaseService(nil, "PubSub", s)
+
+	for _, option := range options {
+		option(s)
+	}
+
+	// if BufferCapacity option was not set, the channel is unbuffered
+	s.cmds = make(chan cmd, s.cmdsCap)
+
+	return s
+}
+
+// BufferCapacity allows you to specify capacity for the internal server's
+// queue. Since the server, given Y subscribers, could only process X messages,
+// this option could be used to survive spikes (e.g. high amount of
+// transactions during peak hours).
+func BufferCapacity(cap int) Option {
+	return func(s *Server) {
+		if cap > 0 {
+			s.cmdsCap = cap
+		}
+	}
+}
+
+// BufferCapacity returns capacity of the internal server's queue.
+func (s *Server) BufferCapacity() int {
+	return s.cmdsCap
+}
+
+// Subscribe creates a subscription for the given client. It accepts a channel
+// on which messages matching the given query can be received. An error will be
+// returned to the caller if the context is canceled or if subscription already
+// exist for pair clientID and query.
+func (s *Server) Subscribe(ctx context.Context, clientID string, qry query.Query, outBuffer int) (<-chan interface{}, error) {
+	s.mtx.RLock()
+	clientSubscriptions, ok := s.subscriptions[clientID]
+	if ok {
+		_, ok = clientSubscriptions[qry.String()]
+	}
+	s.mtx.RUnlock()
+	if ok {
+		return nil, ErrAlreadySubscribed
+	}
+	// We are responsible for closing this channel so we create it
+	out := make(chan interface{}, outBuffer)
+	select {
+	case s.cmds <- cmd{op: sub, clientID: clientID, query: qry, ch: out}:
+		s.mtx.Lock()
+		if _, ok = s.subscriptions[clientID]; !ok {
+			s.subscriptions[clientID] = make(map[string]query.Query)
+		}
+		// preserve original query
+		// see Unsubscribe
+		s.subscriptions[clientID][qry.String()] = qry
+		s.mtx.Unlock()
+		return out, nil
+	case <-ctx.Done():
+		return nil, ctx.Err()
+	}
+}
+
+// Unsubscribe removes the subscription on the given query. An error will be
+// returned to the caller if the context is canceled or if subscription does
+// not exist.
+func (s *Server) Unsubscribe(ctx context.Context, clientID string, qry query.Query) error {
+	var origQuery query.Query
+	s.mtx.RLock()
+	clientSubscriptions, ok := s.subscriptions[clientID]
+	if ok {
+		origQuery, ok = clientSubscriptions[qry.String()]
+	}
+	s.mtx.RUnlock()
+	if !ok {
+		return ErrSubscriptionNotFound
+	}
+
+	// original query is used here because we're using pointers as map keys
+	select {
+	case s.cmds <- cmd{op: unsub, clientID: clientID, query: origQuery}:
+		s.mtx.Lock()
+		delete(clientSubscriptions, qry.String())
+		s.mtx.Unlock()
+		return nil
+	case <-ctx.Done():
+		return ctx.Err()
+	}
+}
+
+// UnsubscribeAll removes all client subscriptions. An error will be returned
+// to the caller if the context is canceled or if subscription does not exist.
+func (s *Server) UnsubscribeAll(ctx context.Context, clientID string) error {
+	s.mtx.RLock()
+	_, ok := s.subscriptions[clientID]
+	s.mtx.RUnlock()
+	if !ok {
+		return ErrSubscriptionNotFound
+	}
+
+	select {
+	case s.cmds <- cmd{op: unsub, clientID: clientID}:
+		s.mtx.Lock()
+		delete(s.subscriptions, clientID)
+		s.mtx.Unlock()
+		return nil
+	case <-ctx.Done():
+		return ctx.Err()
+	}
+}
+
+// Publish publishes the given message. An error will be returned to the caller
+// if the context is canceled.
+func (s *Server) Publish(ctx context.Context, msg interface{}) error {
+	return s.PublishWithTags(ctx, msg, query.TagMap(make(map[string]interface{})))
+}
+
+// PublishWithTags publishes the given message with the set of tags. The set is
+// matched with clients queries. If there is a match, the message is sent to
+// the client.
+func (s *Server) PublishWithTags(ctx context.Context, msg interface{}, tags query.Tagged) error {
+	select {
+	case s.cmds <- cmd{op: pub, msg: msg, tags: tags}:
+		return nil
+	case <-ctx.Done():
+		return ctx.Err()
+	}
+}
+
+// OnStop implements Service.OnStop by shutting down the server.
+func (s *Server) OnStop() {
+	s.cmds <- cmd{op: shutdown}
+}
+
+// NOTE: not goroutine safe
+type state struct {
+	// query -> client -> ch
+	queries map[query.Query]map[string]chan interface{}
+	// client -> query -> struct{}
+	clients map[string]map[query.Query]struct{}
+}
+
+// OnStart implements Service.OnStart by starting the server.
+func (s *Server) OnStart() error {
+	go s.loop(state{
+		queries: make(map[query.Query]map[string]chan interface{}),
+		clients: make(map[string]map[query.Query]struct{}),
+	})
+	return nil
+}
+
+// OnReset implements Service.OnReset
+func (s *Server) OnReset() error {
+	return nil
+}
+
+func (s *Server) loop(state state) {
+loop:
+	for cmd := range s.cmds {
+		switch cmd.op {
+		case unsub:
+			if cmd.query != nil {
+				state.remove(cmd.clientID, cmd.query)
+			} else {
+				state.removeAll(cmd.clientID)
+			}
+		case shutdown:
+			for clientID := range state.clients {
+				state.removeAll(clientID)
+			}
+			break loop
+		case sub:
+			state.add(cmd.clientID, cmd.query, cmd.ch)
+		case pub:
+			state.send(cmd.msg, cmd.tags)
+		}
+	}
+}
+
+func (state *state) add(clientID string, q query.Query, ch chan interface{}) {
+	// add query if needed
+	if _, ok := state.queries[q]; !ok {
+		state.queries[q] = make(map[string]chan interface{})
+	}
+
+	// create subscription
+	state.queries[q][clientID] = ch
+
+	// add client if needed
+	if _, ok := state.clients[clientID]; !ok {
+		state.clients[clientID] = make(map[query.Query]struct{})
+	}
+	state.clients[clientID][q] = struct{}{}
+}
+
+func (state *state) remove(clientID string, q query.Query) {
+	clientToChannelMap, ok := state.queries[q]
+	if !ok {
+		return
+	}
+
+	ch, ok := clientToChannelMap[clientID]
+	if ok {
+		closeAndDrain(ch)
+
+		delete(state.clients[clientID], q)
+
+		// if it not subscribed to anything else, remove the client
+		if len(state.clients[clientID]) == 0 {
+			delete(state.clients, clientID)
+		}
+
+		delete(state.queries[q], clientID)
+		if len(state.queries[q]) == 0 {
+			delete(state.queries, q)
+		}
+	}
+}
+
+func (state *state) removeAll(clientID string) {
+	queryMap, ok := state.clients[clientID]
+	if !ok {
+		return
+	}
+
+	for q := range queryMap {
+		ch := state.queries[q][clientID]
+		closeAndDrain(ch)
+
+		delete(state.queries[q], clientID)
+		if len(state.queries[q]) == 0 {
+			delete(state.queries, q)
+		}
+	}
+	delete(state.clients, clientID)
+}
+
+func closeAndDrain(ch chan interface{}) {
+	close(ch)
+	for range ch {
+	}
+}
+
+func (state *state) send(msg interface{}, tags query.Tagged) {
+	for q, clientToChannelMap := range state.queries {
+		if q.Matches(tags) {
+			for _, ch := range clientToChannelMap {
+				select {
+				case ch <- msg:
+				default:
+					// It's difficult to do anything sensible here with retries/times outs since we may reorder a client's
+					// view of events by sending a later message before an earlier message we retry. If per-client order
+					// matters then we need a queue per client. Possible for us it does not...
+				}
+			}
+		}
+	}
+}
diff --git a/event/pubsub/pubsub_test.go b/event/pubsub/pubsub_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..ec777450c165be1bfe133e967641f6c3a44b5dde
--- /dev/null
+++ b/event/pubsub/pubsub_test.go
@@ -0,0 +1,237 @@
+package pubsub_test
+
+import (
+	"context"
+	"fmt"
+	"runtime/debug"
+	"testing"
+	"time"
+
+	"github.com/hyperledger/burrow/event/pubsub"
+	"github.com/hyperledger/burrow/event/query"
+	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/require"
+)
+
+const (
+	clientID = "test-client"
+)
+
+func TestSubscribe(t *testing.T) {
+	s := pubsub.NewServer()
+	s.Start()
+	defer s.Stop()
+
+	ctx := context.Background()
+	ch, err := s.Subscribe(ctx, clientID, query.Empty{}, 1)
+	require.NoError(t, err)
+	err = s.Publish(ctx, "Ka-Zar")
+	require.NoError(t, err)
+	assertReceive(t, "Ka-Zar", ch)
+
+	err = s.Publish(ctx, "Quicksilver")
+	require.NoError(t, err)
+	assertReceive(t, "Quicksilver", ch)
+}
+
+func TestDifferentClients(t *testing.T) {
+	s := pubsub.NewServer()
+	s.Start()
+	defer s.Stop()
+
+	ctx := context.Background()
+	ch1, err := s.Subscribe(ctx, "client-1", query.MustParse("tm.events.type='NewBlock'"), 1)
+	require.NoError(t, err)
+	err = s.PublishWithTags(ctx, "Iceman", query.TagMap{"tm.events.type": "NewBlock"})
+	require.NoError(t, err)
+	assertReceive(t, "Iceman", ch1)
+
+	ch2, err := s.Subscribe(ctx, "client-2", query.MustParse("tm.events.type='NewBlock' AND abci.account.name='Igor'"), 1)
+	require.NoError(t, err)
+	err = s.PublishWithTags(ctx, "Ultimo", query.TagMap{"tm.events.type": "NewBlock", "abci.account.name": "Igor"})
+	require.NoError(t, err)
+	assertReceive(t, "Ultimo", ch1)
+	assertReceive(t, "Ultimo", ch2)
+
+	ch3, err := s.Subscribe(ctx, "client-3", query.MustParse("tm.events.type='NewRoundStep' AND abci.account.name='Igor' AND abci.invoice.number = 10"), 1)
+	require.NoError(t, err)
+	err = s.PublishWithTags(ctx, "Valeria Richards", query.TagMap{"tm.events.type": "NewRoundStep"})
+	require.NoError(t, err)
+	assert.Zero(t, len(ch3))
+}
+
+func TestClientSubscribesTwice(t *testing.T) {
+	s := pubsub.NewServer()
+
+	s.Start()
+	defer s.Stop()
+
+	ctx := context.Background()
+	q := query.MustParse("tm.events.type='NewBlock'")
+
+	ch1, err := s.Subscribe(ctx, clientID, q, 1)
+	require.NoError(t, err)
+	err = s.PublishWithTags(ctx, "Goblin Queen", query.TagMap{"tm.events.type": "NewBlock"})
+	require.NoError(t, err)
+	assertReceive(t, "Goblin Queen", ch1)
+
+	_, err = s.Subscribe(ctx, clientID, q, 1)
+	require.Error(t, err)
+
+	err = s.PublishWithTags(ctx, "Spider-Man", query.TagMap{"tm.events.type": "NewBlock"})
+	require.NoError(t, err)
+	assertReceive(t, "Spider-Man", ch1)
+}
+
+func TestUnsubscribe(t *testing.T) {
+	s := pubsub.NewServer()
+
+	s.Start()
+	defer s.Stop()
+
+	ctx := context.Background()
+	ch, err := s.Subscribe(ctx, clientID, query.MustParse("tm.events.type='NewBlock'"), 0)
+	require.NoError(t, err)
+	err = s.Unsubscribe(ctx, clientID, query.MustParse("tm.events.type='NewBlock'"))
+	require.NoError(t, err)
+
+	err = s.Publish(ctx, "Nick Fury")
+	require.NoError(t, err)
+	assert.Zero(t, len(ch), "Should not receive anything after Unsubscribe")
+
+	_, ok := <-ch
+	assert.False(t, ok)
+}
+
+func TestResubscribe(t *testing.T) {
+	s := pubsub.NewServer()
+
+	s.Start()
+	defer s.Stop()
+
+	ctx := context.Background()
+	ch, err := s.Subscribe(ctx, clientID, query.Empty{}, 0)
+	require.NoError(t, err)
+	err = s.Unsubscribe(ctx, clientID, query.Empty{})
+	require.NoError(t, err)
+	ch, err = s.Subscribe(ctx, clientID, query.Empty{}, 0)
+	require.NoError(t, err)
+
+	err = s.Publish(ctx, "Cable")
+	require.NoError(t, err)
+	assertReceive(t, "Cable", ch)
+}
+
+func TestUnsubscribeAll(t *testing.T) {
+	s := pubsub.NewServer()
+
+	s.Start()
+	defer s.Stop()
+
+	ctx := context.Background()
+	ch1, err := s.Subscribe(ctx, clientID, query.MustParse("tm.events.type='NewBlock'"), 1)
+	require.NoError(t, err)
+	ch2, err := s.Subscribe(ctx, clientID, query.MustParse("tm.events.type='NewBlockHeader'"), 1)
+	require.NoError(t, err)
+
+	err = s.UnsubscribeAll(ctx, clientID)
+	require.NoError(t, err)
+
+	err = s.Publish(ctx, "Nick Fury")
+	require.NoError(t, err)
+	assert.Zero(t, len(ch1), "Should not receive anything after UnsubscribeAll")
+	assert.Zero(t, len(ch2), "Should not receive anything after UnsubscribeAll")
+
+	_, ok := <-ch1
+	assert.False(t, ok)
+	_, ok = <-ch2
+	assert.False(t, ok)
+}
+
+func TestBufferCapacity(t *testing.T) {
+	s := pubsub.NewServer(pubsub.BufferCapacity(2))
+
+	assert.Equal(t, 2, s.BufferCapacity())
+
+	ctx := context.Background()
+	err := s.Publish(ctx, "Nighthawk")
+	require.NoError(t, err)
+	err = s.Publish(ctx, "Sage")
+	require.NoError(t, err)
+
+	ctx, cancel := context.WithTimeout(ctx, 10*time.Millisecond)
+	defer cancel()
+	err = s.Publish(ctx, "Ironclad")
+	if assert.Error(t, err) {
+		assert.Equal(t, context.DeadlineExceeded, err)
+	}
+}
+
+func Benchmark10Clients(b *testing.B)   { benchmarkNClients(10, b) }
+func Benchmark100Clients(b *testing.B)  { benchmarkNClients(100, b) }
+func Benchmark1000Clients(b *testing.B) { benchmarkNClients(1000, b) }
+
+func Benchmark10ClientsOneQuery(b *testing.B)   { benchmarkNClientsOneQuery(10, b) }
+func Benchmark100ClientsOneQuery(b *testing.B)  { benchmarkNClientsOneQuery(100, b) }
+func Benchmark1000ClientsOneQuery(b *testing.B) { benchmarkNClientsOneQuery(1000, b) }
+
+func benchmarkNClients(n int, b *testing.B) {
+	s := pubsub.NewServer()
+	s.Start()
+	defer s.Stop()
+
+	ctx := context.Background()
+	for i := 0; i < n; i++ {
+		ch, err := s.Subscribe(ctx, clientID, query.MustParse(fmt.Sprintf("abci.Account.Owner = 'Ivan' AND abci.Invoices.Number = %d", i)), 0)
+		require.NoError(b, err)
+		go func() {
+			for range ch {
+			}
+		}()
+	}
+
+	b.ReportAllocs()
+	b.ResetTimer()
+	for i := 0; i < b.N; i++ {
+		s.PublishWithTags(ctx, "Gamora", query.TagMap{"abci.Account.Owner": "Ivan", "abci.Invoices.Number": string(i)})
+	}
+}
+
+func benchmarkNClientsOneQuery(n int, b *testing.B) {
+	s := pubsub.NewServer()
+	s.Start()
+	defer s.Stop()
+
+	ctx := context.Background()
+	q := query.MustParse("abci.Account.Owner = 'Ivan' AND abci.Invoices.Number = 1")
+	for i := 0; i < n; i++ {
+		ch, err := s.Subscribe(ctx, clientID, q, 0)
+		require.NoError(b, err)
+		go func() {
+			for range ch {
+			}
+		}()
+	}
+
+	b.ReportAllocs()
+	b.ResetTimer()
+	for i := 0; i < b.N; i++ {
+		s.PublishWithTags(ctx, "Gamora", query.TagMap{"abci.Account.Owner": "Ivan", "abci.Invoices.Number": "1"})
+	}
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/// HELPERS
+///////////////////////////////////////////////////////////////////////////////
+
+func assertReceive(t *testing.T, expected interface{}, ch <-chan interface{}, msgAndArgs ...interface{}) {
+	select {
+	case actual := <-ch:
+		if actual != nil {
+			assert.Equal(t, expected, actual, msgAndArgs...)
+		}
+	case <-time.After(1 * time.Second):
+		t.Errorf("Expected to receive %v from the channel, got nothing after 1s", expected)
+		debug.PrintStack()
+	}
+}
diff --git a/event/query/Makefile b/event/query/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..91030ef098b4fc74a3728c5e62b8c78df2838532
--- /dev/null
+++ b/event/query/Makefile
@@ -0,0 +1,11 @@
+gen_query_parser:
+	@go get github.com/pointlander/peg
+	peg -inline -switch query.peg
+
+fuzzy_test:
+	@go get github.com/dvyukov/go-fuzz/go-fuzz
+	@go get github.com/dvyukov/go-fuzz/go-fuzz-build
+	go-fuzz-build github.com/tendermint/tendermint/libs/pubsub/query/fuzz_test
+	go-fuzz -bin=./fuzz_test-fuzz.zip -workdir=./fuzz_test/output
+
+.PHONY: gen_query_parser fuzzy_test
diff --git a/event/query/builder.go b/event/query/builder.go
new file mode 100644
index 0000000000000000000000000000000000000000..1395a39aa1d34fcf0c74e23660f515e388b2e81c
--- /dev/null
+++ b/event/query/builder.go
@@ -0,0 +1,263 @@
+package query
+
+import (
+	"bytes"
+	"fmt"
+	"reflect"
+	"strconv"
+	"strings"
+	"text/template"
+	"time"
+)
+
+const (
+	MultipleValueTagSeparator = ";"
+
+	// Operators
+	equalString          = "="
+	greaterThanString    = ">"
+	lessThanString       = "<"
+	greaterOrEqualString = ">="
+	lessOrEqualString    = "<="
+	containsString       = "CONTAINS"
+	andString            = "AND"
+
+	// Values
+	trueString  = "true"
+	falseString = "false"
+	emptyString = "empty"
+	timeString  = "TIME"
+	dateString  = "DATE"
+)
+
+type Query interface {
+	Matches(tags Tagged) bool
+	String() string
+}
+
+type Queryable interface {
+	Query() (Query, error)
+}
+
+type parsedQuery struct {
+	query Query
+}
+
+func AsQueryable(query Query) parsedQuery {
+	return parsedQuery{query: query}
+}
+
+func (pq parsedQuery) Query() (Query, error) {
+	return pq.query, nil
+}
+
+// A yet-to-parsed query
+type String string
+
+func Must(qry Query, err error) Query {
+	if err != nil {
+		panic(fmt.Errorf("could not compile: %v", qry))
+	}
+	return qry
+}
+
+func (qs String) Query() (Query, error) {
+	if isEmpty(string(qs)) {
+		return Empty{}, nil
+	}
+	return New(string(qs))
+}
+
+func MatchAllQueryable() Queryable {
+	return Empty{}
+}
+
+// A fluent query builder
+type Builder struct {
+	queryString string
+	condition
+	// reusable buffer for building queryString
+	bytes.Buffer
+	error
+}
+
+// Templates
+type condition struct {
+	Tag     string
+	Op      string
+	Operand string
+}
+
+var conditionTemplate = template.Must(template.New("condition").Parse("{{.Tag}} {{.Op}} {{.Operand}}"))
+
+// Creates a new query builder with a base query that is the conjunction of all queries passed
+func NewBuilder(queries ...string) *Builder {
+	qb := new(Builder)
+	qb.queryString = qb.and(stringIterator(queries...))
+	return qb
+}
+
+func (qb *Builder) String() string {
+	return qb.queryString
+}
+
+func (qb *Builder) Query() (Query, error) {
+	if qb.error != nil {
+		return nil, qb.error
+	}
+	if isEmpty(qb.queryString) {
+		return Empty{}, nil
+	}
+	return New(qb.String())
+}
+
+// Creates the conjunction of Builder and rightQuery
+func (qb *Builder) And(queryBuilders ...*Builder) *Builder {
+	return NewBuilder(qb.and(queryBuilderIterator(queryBuilders...)))
+}
+
+// Creates the conjunction of Builder and tag = operand
+func (qb *Builder) AndEquals(tag string, operand interface{}) *Builder {
+	qb.condition.Tag = tag
+	qb.condition.Op = equalString
+	qb.condition.Operand = operandString(operand)
+	return NewBuilder(qb.and(stringIterator(qb.conditionString())))
+}
+
+func (qb *Builder) AndGreaterThanOrEqual(tag string, operand interface{}) *Builder {
+	qb.condition.Tag = tag
+	qb.condition.Op = greaterOrEqualString
+	qb.condition.Operand = operandString(operand)
+	return NewBuilder(qb.and(stringIterator(qb.conditionString())))
+}
+
+func (qb *Builder) AndLessThanOrEqual(tag string, operand interface{}) *Builder {
+	qb.condition.Tag = tag
+	qb.condition.Op = lessOrEqualString
+	qb.condition.Operand = operandString(operand)
+	return NewBuilder(qb.and(stringIterator(qb.conditionString())))
+}
+
+func (qb *Builder) AndStrictlyGreaterThan(tag string, operand interface{}) *Builder {
+	qb.condition.Tag = tag
+	qb.condition.Op = greaterThanString
+	qb.condition.Operand = operandString(operand)
+	return NewBuilder(qb.and(stringIterator(qb.conditionString())))
+}
+
+func (qb *Builder) AndStrictlyLessThan(tag string, operand interface{}) *Builder {
+	qb.condition.Tag = tag
+	qb.condition.Op = lessThanString
+	qb.condition.Operand = operandString(operand)
+	return NewBuilder(qb.and(stringIterator(qb.conditionString())))
+}
+
+func (qb *Builder) AndContains(tag string, operand interface{}) *Builder {
+	qb.condition.Tag = tag
+	qb.condition.Op = containsString
+	qb.condition.Operand = operandString(operand)
+	return NewBuilder(qb.and(stringIterator(qb.conditionString())))
+}
+
+func (qb *Builder) and(queryIterator func(func(string))) string {
+	defer qb.Buffer.Reset()
+	qb.Buffer.WriteString(qb.queryString)
+	queryIterator(func(q string) {
+		if !isEmpty(q) {
+			if qb.Buffer.Len() > 0 {
+				qb.Buffer.WriteByte(' ')
+				qb.Buffer.WriteString(andString)
+				qb.Buffer.WriteByte(' ')
+			}
+			qb.Buffer.WriteString(q)
+		}
+	})
+	return qb.Buffer.String()
+}
+
+func operandString(value interface{}) string {
+	buf := new(bytes.Buffer)
+	switch v := value.(type) {
+	case string:
+		buf.WriteByte('\'')
+		buf.WriteString(v)
+		buf.WriteByte('\'')
+		return buf.String()
+	case fmt.Stringer:
+		return operandString(v.String())
+	default:
+		return StringFromValue(v)
+	}
+}
+
+func StringFromValue(value interface{}) string {
+	switch v := value.(type) {
+	case string:
+		return v
+	case fmt.Stringer:
+		return v.String()
+	case bool:
+		if v {
+			return trueString
+		}
+		return falseString
+	case int:
+		return strconv.FormatInt(int64(v), 10)
+	case int32:
+		return strconv.FormatInt(int64(v), 10)
+	case int64:
+		return strconv.FormatInt(v, 10)
+	case uint:
+		return strconv.FormatUint(uint64(v), 10)
+	case uint32:
+		return strconv.FormatUint(uint64(v), 10)
+	case uint64:
+		return strconv.FormatUint(v, 10)
+	case float32:
+		return strconv.FormatFloat(float64(v), 'f', -1, 32)
+	case float64:
+		return strconv.FormatFloat(float64(v), 'f', -1, 64)
+	case time.Time:
+		return timeString + " " + v.Format(time.RFC3339)
+	default:
+		rv := reflect.ValueOf(v)
+		if rv.Kind() == reflect.Slice {
+			values := make([]string, rv.Len())
+			for i := 0; i < rv.Len(); i++ {
+				values[i] = StringFromValue(rv.Index(i).Interface())
+			}
+			return strings.Join(values, MultipleValueTagSeparator)
+		}
+		return fmt.Sprintf("%v", v)
+	}
+}
+
+func (qb *Builder) conditionString() string {
+	defer qb.Buffer.Reset()
+	err := conditionTemplate.Execute(&qb.Buffer, qb.condition)
+	if err != nil && qb.error == nil {
+		qb.error = err
+	}
+	return qb.Buffer.String()
+}
+
+func isEmpty(queryString string) bool {
+	return queryString == "" || queryString == emptyString
+}
+
+// Iterators over some strings
+func stringIterator(strs ...string) func(func(string)) {
+	return func(callback func(string)) {
+		for _, s := range strs {
+			callback(s)
+		}
+	}
+}
+
+func queryBuilderIterator(qbs ...*Builder) func(func(string)) {
+	return func(callback func(string)) {
+		for _, qb := range qbs {
+			callback(qb.String())
+		}
+	}
+}
diff --git a/event/query/builder_test.go b/event/query/builder_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..15da502d01c440179e27b72595470fffcba04828
--- /dev/null
+++ b/event/query/builder_test.go
@@ -0,0 +1,52 @@
+package query
+
+import (
+	"testing"
+
+	"github.com/hyperledger/burrow/logging/structure"
+	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/require"
+)
+
+func TestQueryBuilder(t *testing.T) {
+	qb := NewBuilder()
+	qry, err := qb.Query()
+	require.NoError(t, err)
+	assert.Equal(t, emptyString, qry.String())
+
+	qb = qb.AndGreaterThanOrEqual("foo.size", 45)
+	qry, err = qb.Query()
+	require.NoError(t, err)
+	assert.Equal(t, "foo.size >= 45", qry.String())
+
+	qb = qb.AndEquals("bar.name", "marmot")
+	qry, err = qb.Query()
+	require.NoError(t, err)
+	assert.Equal(t, "foo.size >= 45 AND bar.name = 'marmot'", qry.String())
+
+	assert.True(t, qry.Matches(makeTagMap("foo.size", 80, "bar.name", "marmot")))
+	assert.False(t, qry.Matches(makeTagMap("foo.size", 8, "bar.name", "marmot")))
+	assert.False(t, qry.Matches(makeTagMap("foo.size", 80, "bar.name", "marot")))
+
+	qb = qb.AndContains("bar.desc", "burrow")
+	qry, err = qb.Query()
+	require.NoError(t, err)
+	assert.Equal(t, "foo.size >= 45 AND bar.name = 'marmot' AND bar.desc CONTAINS 'burrow'", qry.String())
+
+	assert.True(t, qry.Matches(makeTagMap("foo.size", 80, "bar.name", "marmot", "bar.desc", "lives in a burrow")))
+	assert.False(t, qry.Matches(makeTagMap("foo.size", 80, "bar.name", "marmot", "bar.desc", "lives in a shoe")))
+
+	qb = NewBuilder().AndEquals("foo", "bar")
+	qb = qb.And(NewBuilder().AndGreaterThanOrEqual("frogs", 4))
+	qry, err = qb.Query()
+	require.NoError(t, err)
+	assert.Equal(t, "foo = 'bar' AND frogs >= 4", qry.String())
+}
+
+func makeTagMap(keyvals ...interface{}) TagMap {
+	tmap := make(TagMap)
+	for i := 0; i < len(keyvals); i += 2 {
+		tmap[keyvals[i].(string)] = structure.StringifyKey(keyvals[i+1])
+	}
+	return tmap
+}
diff --git a/event/query/empty.go b/event/query/empty.go
index c83169e18b5224a178d6812439393bac69231dd2..5d10ce4c7a29401ecb6f3696702fe1ec11b03a25 100644
--- a/event/query/empty.go
+++ b/event/query/empty.go
@@ -1,13 +1,21 @@
 package query
 
-import (
-	"github.com/tendermint/tendermint/libs/pubsub"
-	"github.com/tendermint/tendermint/libs/pubsub/query"
-)
+// Empty query matches any set of tags.
+type Empty struct {
+}
+
+var _ Query = Empty{}
+var _ Queryable = Empty{}
 
-// Matches everything
-type Empty query.Empty
+// Matches always returns true.
+func (Empty) Matches(tags Tagged) bool {
+	return true
+}
+
+func (Empty) String() string {
+	return "empty"
+}
 
-func (Empty) Query() (pubsub.Query, error) {
-	return query.Empty{}, nil
+func (Empty) Query() (Query, error) {
+	return Empty{}, nil
 }
diff --git a/event/query/empty_test.go b/event/query/empty_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..d7237112f536fe56ae9bb0cc0454e9dff11dc4f9
--- /dev/null
+++ b/event/query/empty_test.go
@@ -0,0 +1,15 @@
+package query
+
+import (
+	"testing"
+
+	"github.com/stretchr/testify/assert"
+)
+
+func TestEmptyQueryMatchesAnything(t *testing.T) {
+	q := Empty{}
+	assert.True(t, q.Matches(TagMap{}))
+	assert.True(t, q.Matches(TagMap{"Asher": "Roth"}))
+	assert.True(t, q.Matches(TagMap{"Route": "66"}))
+	assert.True(t, q.Matches(TagMap{"Route": "66", "Billy": "Blue"}))
+}
diff --git a/event/query/parser_test.go b/event/query/parser_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..dca8b1ed2c370e19b6c67e896b34fbfa164681e1
--- /dev/null
+++ b/event/query/parser_test.go
@@ -0,0 +1,90 @@
+package query
+
+import (
+	"testing"
+
+	"github.com/stretchr/testify/assert"
+)
+
+// TODO: fuzzy testing?
+func TestParser(t *testing.T) {
+	cases := []struct {
+		query string
+		valid bool
+	}{
+		{"tm.events.type='NewBlock'", true},
+		{"tm.events.type = 'NewBlock'", true},
+		{"tm.events.name = ''", true},
+		{"tm.events.type='TIME'", true},
+		{"tm.events.type='DATE'", true},
+		{"tm.events.type='='", true},
+		{"tm.events.type='TIME", false},
+		{"tm.events.type=TIME'", false},
+		{"tm.events.type==", false},
+		{"tm.events.type=NewBlock", false},
+		{">==", false},
+		{"tm.events.type 'NewBlock' =", false},
+		{"tm.events.type>'NewBlock'", false},
+		{"", false},
+		{"=", false},
+		{"='NewBlock'", false},
+		{"tm.events.type=", false},
+
+		{"tm.events.typeNewBlock", false},
+		{"tm.events.type'NewBlock'", false},
+		{"'NewBlock'", false},
+		{"NewBlock", false},
+		{"", false},
+
+		{"tm.events.type='NewBlock' AND abci.account.name='Igor'", true},
+		{"tm.events.type='NewBlock' AND", false},
+		{"tm.events.type='NewBlock' AN", false},
+		{"tm.events.type='NewBlock' AN tm.events.type='NewBlockHeader'", false},
+		{"AND tm.events.type='NewBlock' ", false},
+
+		{"abci.account.name CONTAINS 'Igor'", true},
+
+		{"tx.date > DATE 2013-05-03", true},
+		{"tx.date < DATE 2013-05-03", true},
+		{"tx.date <= DATE 2013-05-03", true},
+		{"tx.date >= DATE 2013-05-03", true},
+		{"tx.date >= DAT 2013-05-03", false},
+		{"tx.date <= DATE2013-05-03", false},
+		{"tx.date <= DATE -05-03", false},
+		{"tx.date >= DATE 20130503", false},
+		{"tx.date >= DATE 2013+01-03", false},
+		// incorrect year, month, day
+		{"tx.date >= DATE 0013-01-03", false},
+		{"tx.date >= DATE 2013-31-03", false},
+		{"tx.date >= DATE 2013-01-83", false},
+
+		{"tx.date > TIME 2013-05-03T14:45:00+07:00", true},
+		{"tx.date < TIME 2013-05-03T14:45:00-02:00", true},
+		{"tx.date <= TIME 2013-05-03T14:45:00Z", true},
+		{"tx.date >= TIME 2013-05-03T14:45:00Z", true},
+		{"tx.date >= TIME2013-05-03T14:45:00Z", false},
+		{"tx.date = IME 2013-05-03T14:45:00Z", false},
+		{"tx.date = TIME 2013-05-:45:00Z", false},
+		{"tx.date >= TIME 2013-05-03T14:45:00", false},
+		{"tx.date >= TIME 0013-00-00T14:45:00Z", false},
+		{"tx.date >= TIME 2013+05=03T14:45:00Z", false},
+
+		{"account.balance=100", true},
+		{"account.balance >= 200", true},
+		{"account.balance >= -300", false},
+		{"account.balance >>= 400", false},
+		{"account.balance=33.22.1", false},
+
+		{"hash='136E18F7E4C348B780CF873A0BF43922E5BAFA63'", true},
+		{"hash=136E18F7E4C348B780CF873A0BF43922E5BAFA63", false},
+	}
+
+	for _, c := range cases {
+		_, err := New(c.query)
+		if c.valid {
+			assert.NoErrorf(t, err, "Query was '%s'", c.query)
+		} else {
+			assert.Errorf(t, err, "Query was '%s'", c.query)
+		}
+	}
+}
diff --git a/event/query/query.go b/event/query/query.go
index fc107968b1541927f0c1a9f7e9edb1f9f9f9a4ae..17946b7704e197b09f5145e93cfdc1ffe4a60d4f 100644
--- a/event/query/query.go
+++ b/event/query/query.go
@@ -1,250 +1,344 @@
+// Package query provides a parser for a custom query format:
+//
+//		abci.invoice.number=22 AND abci.invoice.owner=Ivan
+//
+// See query.peg for the grammar, which is a https://en.wikipedia.org/wiki/Parsing_expression_grammar.
+// More: https://github.com/PhilippeSigaud/Pegged/wiki/PEG-Basics
+//
+// It has a support for numbers (integer and floating point), dates and times.
 package query
 
 import (
-	"bytes"
 	"fmt"
+	"reflect"
 	"strconv"
-	"text/template"
+	"strings"
 	"time"
-
-	"github.com/tendermint/tendermint/libs/pubsub"
-	"github.com/tendermint/tendermint/libs/pubsub/query"
 )
 
-const (
-	// Operators
-	equalString          = "="
-	greaterThanString    = ">"
-	lessThanString       = "<"
-	greaterOrEqualString = ">="
-	lessOrEqualString    = "<="
-	containsString       = "CONTAINS"
-	andString            = "AND"
-
-	// Values
-	trueString  = "true"
-	falseString = "false"
-	emptyString = "empty"
-	timeString  = "TIME"
-	dateString  = "DATE"
-)
-
-type Queryable interface {
-	Query() (pubsub.Query, error)
-}
-
-// A yet-to-parsed query
-type String string
-
-func Must(qry pubsub.Query, err error) Query {
-	if err != nil {
-		panic(fmt.Errorf("could not compile: %v", qry))
-	}
-	return WrapQuery(qry)
-}
-
-func (qs String) Query() (pubsub.Query, error) {
-	if isEmpty(string(qs)) {
-		return query.Empty{}, nil
-	}
-	return query.New(string(qs))
-}
+var _ Query = &query{}
+var _ Queryable = &query{}
 
-func MatchAllQueryable() Queryable {
-	return WrapQuery(query.Empty{})
+// Query holds the query string and the query parser.
+type query struct {
+	str    string
+	parser *QueryParser
 }
 
-// A pre-parsed query
-type Query struct {
-	query pubsub.Query
-}
-
-func WrapQuery(qry pubsub.Query) Query {
-	return Query{qry}
-}
-
-func (q Query) Query() (pubsub.Query, error) {
-	return q.query, nil
-}
-
-// A fluent query builder
-type Builder struct {
-	queryString string
-	condition
-	// reusable buffer for building queryString
-	bytes.Buffer
-	error
-}
-
-// Templates
-type condition struct {
+// Condition represents a single condition within a query and consists of tag
+// (e.g. "tx.gas"), operator (e.g. "=") and operand (e.g. "7").
+type Condition struct {
 	Tag     string
-	Op      string
-	Operand string
+	Op      Operator
+	Operand interface{}
 }
 
-var conditionTemplate = template.Must(template.New("condition").Parse("{{.Tag}} {{.Op}} {{.Operand}}"))
-
-// Creates a new query builder with a base query that is the conjunction of all queries passed
-func NewBuilder(queries ...string) *Builder {
-	qb := new(Builder)
-	qb.queryString = qb.and(stringIterator(queries...))
-	return qb
-}
-
-func (qb *Builder) String() string {
-	return qb.queryString
-}
-
-func (qb *Builder) Query() (pubsub.Query, error) {
-	if qb.error != nil {
-		return nil, qb.error
-	}
-	if isEmpty(qb.queryString) {
-		return query.Empty{}, nil
+// New parses the given string and returns a query or error if the string is
+// invalid.
+func New(s string) (*query, error) {
+	p := &QueryParser{Buffer: fmt.Sprintf(`"%s"`, s)}
+	p.Init()
+	if err := p.Parse(); err != nil {
+		return nil, err
 	}
-	return query.New(qb.String())
+	return &query{str: s, parser: p}, nil
 }
 
-// Creates the conjunction of Builder and rightQuery
-func (qb *Builder) And(queryBuilders ...*Builder) *Builder {
-	return NewBuilder(qb.and(queryBuilderIterator(queryBuilders...)))
-}
-
-// Creates the conjunction of Builder and tag = operand
-func (qb *Builder) AndEquals(tag string, operand interface{}) *Builder {
-	qb.condition.Tag = tag
-	qb.condition.Op = equalString
-	qb.condition.Operand = operandString(operand)
-	return NewBuilder(qb.and(stringIterator(qb.conditionString())))
+// MustParse turns the given string into a query or panics; for tests or others
+// cases where you know the string is valid.
+func MustParse(s string) *query {
+	q, err := New(s)
+	if err != nil {
+		panic(fmt.Sprintf("failed to parse %s: %v", s, err))
+	}
+	return q
 }
 
-func (qb *Builder) AndGreaterThanOrEqual(tag string, operand interface{}) *Builder {
-	qb.condition.Tag = tag
-	qb.condition.Op = greaterOrEqualString
-	qb.condition.Operand = operandString(operand)
-	return NewBuilder(qb.and(stringIterator(qb.conditionString())))
+// String returns the original string.
+func (q *query) String() string {
+	return q.str
 }
 
-func (qb *Builder) AndLessThanOrEqual(tag string, operand interface{}) *Builder {
-	qb.condition.Tag = tag
-	qb.condition.Op = lessOrEqualString
-	qb.condition.Operand = operandString(operand)
-	return NewBuilder(qb.and(stringIterator(qb.conditionString())))
+func (q *query) Query() (Query, error) {
+	return q, nil
 }
 
-func (qb *Builder) AndStrictlyGreaterThan(tag string, operand interface{}) *Builder {
-	qb.condition.Tag = tag
-	qb.condition.Op = greaterThanString
-	qb.condition.Operand = operandString(operand)
-	return NewBuilder(qb.and(stringIterator(qb.conditionString())))
-}
+// Operator is an operator that defines some kind of relation between tag and
+// operand (equality, etc.).
+type Operator uint8
 
-func (qb *Builder) AndStrictlyLessThan(tag string, operand interface{}) *Builder {
-	qb.condition.Tag = tag
-	qb.condition.Op = lessThanString
-	qb.condition.Operand = operandString(operand)
-	return NewBuilder(qb.and(stringIterator(qb.conditionString())))
-}
+const (
+	// "<="
+	OpLessEqual Operator = iota
+	// ">="
+	OpGreaterEqual
+	// "<"
+	OpLess
+	// ">"
+	OpGreater
+	// "="
+	OpEqual
+	// "CONTAINS"; used to check if a string contains a certain sub string.
+	OpContains
+)
 
-func (qb *Builder) AndContains(tag string, operand interface{}) *Builder {
-	qb.condition.Tag = tag
-	qb.condition.Op = containsString
-	qb.condition.Operand = operandString(operand)
-	return NewBuilder(qb.and(stringIterator(qb.conditionString())))
-}
+const (
+	// DateLayout defines a layout for all dates (`DATE date`)
+	DateLayout = "2006-01-02"
+	// TimeLayout defines a layout for all times (`TIME time`)
+	TimeLayout = time.RFC3339
+)
 
-func (qb *Builder) and(queryIterator func(func(string))) string {
-	defer qb.Buffer.Reset()
-	qb.Buffer.WriteString(qb.queryString)
-	queryIterator(func(q string) {
-		if !isEmpty(q) {
-			if qb.Buffer.Len() > 0 {
-				qb.Buffer.WriteByte(' ')
-				qb.Buffer.WriteString(andString)
-				qb.Buffer.WriteByte(' ')
+// Conditions returns a list of conditions.
+func (q *query) Conditions() []Condition {
+	conditions := make([]Condition, 0)
+
+	buffer, begin, end := q.parser.Buffer, 0, 0
+
+	var tag string
+	var op Operator
+
+	// tokens must be in the following order: tag ("tx.gas") -> operator ("=") -> operand ("7")
+	for _, token := range q.parser.Tokens() {
+		switch token.pegRule {
+
+		case rulePegText:
+			begin, end = int(token.begin), int(token.end)
+		case ruletag:
+			tag = buffer[begin:end]
+		case rulele:
+			op = OpLessEqual
+		case rulege:
+			op = OpGreaterEqual
+		case rulel:
+			op = OpLess
+		case ruleg:
+			op = OpGreater
+		case ruleequal:
+			op = OpEqual
+		case rulecontains:
+			op = OpContains
+		case rulevalue:
+			// strip single quotes from value (i.e. "'NewBlock'" -> "NewBlock")
+			valueWithoutSingleQuotes := buffer[begin+1 : end-1]
+			conditions = append(conditions, Condition{tag, op, valueWithoutSingleQuotes})
+		case rulenumber:
+			number := buffer[begin:end]
+			if strings.ContainsAny(number, ".") { // if it looks like a floating-point number
+				value, err := strconv.ParseFloat(number, 64)
+				if err != nil {
+					panic(fmt.Sprintf("got %v while trying to parse %s as float64 (should never happen if the grammar is correct)", err, number))
+				}
+				conditions = append(conditions, Condition{tag, op, value})
+			} else {
+				value, err := strconv.ParseInt(number, 10, 64)
+				if err != nil {
+					panic(fmt.Sprintf("got %v while trying to parse %s as int64 (should never happen if the grammar is correct)", err, number))
+				}
+				conditions = append(conditions, Condition{tag, op, value})
+			}
+		case ruletime:
+			value, err := time.Parse(TimeLayout, buffer[begin:end])
+			if err != nil {
+				panic(fmt.Sprintf("got %v while trying to parse %s as time.Time / RFC3339 (should never happen if the grammar is correct)", err, buffer[begin:end]))
+			}
+			conditions = append(conditions, Condition{tag, op, value})
+		case ruledate:
+			value, err := time.Parse("2006-01-02", buffer[begin:end])
+			if err != nil {
+				panic(fmt.Sprintf("got %v while trying to parse %s as time.Time / '2006-01-02' (should never happen if the grammar is correct)", err, buffer[begin:end]))
 			}
-			qb.Buffer.WriteString(q)
+			conditions = append(conditions, Condition{tag, op, value})
 		}
-	})
-	return qb.Buffer.String()
-}
-
-func operandString(value interface{}) string {
-	buf := new(bytes.Buffer)
-	switch v := value.(type) {
-	case string:
-		buf.WriteByte('\'')
-		buf.WriteString(v)
-		buf.WriteByte('\'')
-		return buf.String()
-	case fmt.Stringer:
-		return operandString(v.String())
-	default:
-		return StringFromValue(v)
 	}
-}
 
-func StringFromValue(value interface{}) string {
-	switch v := value.(type) {
-	case string:
-		return v
-	case fmt.Stringer:
-		return v.String()
-	case bool:
-		if v {
-			return trueString
-		}
-		return falseString
-	case int:
-		return strconv.FormatInt(int64(v), 10)
-	case int32:
-		return strconv.FormatInt(int64(v), 10)
-	case int64:
-		return strconv.FormatInt(v, 10)
-	case uint:
-		return strconv.FormatUint(uint64(v), 10)
-	case uint32:
-		return strconv.FormatUint(uint64(v), 10)
-	case uint64:
-		return strconv.FormatUint(v, 10)
-	case float32:
-		return strconv.FormatFloat(float64(v), 'f', -1, 32)
-	case float64:
-		return strconv.FormatFloat(float64(v), 'f', -1, 64)
-	case time.Time:
-		return timeString + " " + v.Format(time.RFC3339)
-	default:
-		return fmt.Sprintf("%v", v)
-	}
+	return conditions
 }
 
-func (qb *Builder) conditionString() string {
-	defer qb.Buffer.Reset()
-	err := conditionTemplate.Execute(&qb.Buffer, qb.condition)
-	if err != nil && qb.error == nil {
-		qb.error = err
+// Matches returns true if the query matches the given set of tags, false otherwise.
+//
+// For example, query "name=John" matches tags = {"name": "John"}. More
+// examples could be found in parser_test.go and query_test.go.
+func (q *query) Matches(tags Tagged) bool {
+	if tags.Len() == 0 {
+		return false
 	}
-	return qb.Buffer.String()
-}
 
-func isEmpty(queryString string) bool {
-	return queryString == "" || queryString == emptyString
-}
-
-// Iterators over some strings
-func stringIterator(strs ...string) func(func(string)) {
-	return func(callback func(string)) {
-		for _, s := range strs {
-			callback(s)
+	buffer, begin, end := q.parser.Buffer, 0, 0
+
+	var tag string
+	var op Operator
+
+	// tokens must be in the following order: tag ("tx.gas") -> operator ("=") -> operand ("7")
+	for _, token := range q.parser.Tokens() {
+		switch token.pegRule {
+
+		case rulePegText:
+			begin, end = int(token.begin), int(token.end)
+		case ruletag:
+			tag = buffer[begin:end]
+		case rulele:
+			op = OpLessEqual
+		case rulege:
+			op = OpGreaterEqual
+		case rulel:
+			op = OpLess
+		case ruleg:
+			op = OpGreater
+		case ruleequal:
+			op = OpEqual
+		case rulecontains:
+			op = OpContains
+		case rulevalue:
+			// strip single quotes from value (i.e. "'NewBlock'" -> "NewBlock")
+			valueWithoutSingleQuotes := buffer[begin+1 : end-1]
+
+			// see if the triplet (tag, operator, operand) matches any tag
+			// "tx.gas", "=", "7", { "tx.gas": 7, "tx.ID": "4AE393495334" }
+			if !match(tag, op, reflect.ValueOf(valueWithoutSingleQuotes), tags) {
+				return false
+			}
+		case rulenumber:
+			number := buffer[begin:end]
+			if strings.ContainsAny(number, ".") { // if it looks like a floating-point number
+				value, err := strconv.ParseFloat(number, 64)
+				if err != nil {
+					panic(fmt.Sprintf("got %v while trying to parse %s as float64 (should never happen if the grammar is correct)", err, number))
+				}
+				if !match(tag, op, reflect.ValueOf(value), tags) {
+					return false
+				}
+			} else {
+				value, err := strconv.ParseInt(number, 10, 64)
+				if err != nil {
+					panic(fmt.Sprintf("got %v while trying to parse %s as int64 (should never happen if the grammar is correct)", err, number))
+				}
+				if !match(tag, op, reflect.ValueOf(value), tags) {
+					return false
+				}
+			}
+		case ruletime:
+			value, err := time.Parse(TimeLayout, buffer[begin:end])
+			if err != nil {
+				panic(fmt.Sprintf("got %v while trying to parse %s as time.Time / RFC3339 (should never happen if the grammar is correct)", err, buffer[begin:end]))
+			}
+			if !match(tag, op, reflect.ValueOf(value), tags) {
+				return false
+			}
+		case ruledate:
+			value, err := time.Parse("2006-01-02", buffer[begin:end])
+			if err != nil {
+				panic(fmt.Sprintf("got %v while trying to parse %s as time.Time / '2006-01-02' (should never happen if the grammar is correct)", err, buffer[begin:end]))
+			}
+			if !match(tag, op, reflect.ValueOf(value), tags) {
+				return false
+			}
 		}
 	}
+
+	return true
 }
 
-func queryBuilderIterator(qbs ...*Builder) func(func(string)) {
-	return func(callback func(string)) {
-		for _, qb := range qbs {
-			callback(qb.String())
+// match returns true if the given triplet (tag, operator, operand) matches any tag.
+//
+// First, it looks up the tag in tags and if it finds one, tries to compare the
+// value from it to the operand using the operator.
+//
+// "tx.gas", "=", "7", { "tx.gas": 7, "tx.ID": "4AE393495334" }
+func match(tag string, op Operator, operand reflect.Value, tags Tagged) bool {
+	// look up the tag from the query in tags
+	value, ok := tags.Get(tag)
+	if !ok {
+		return false
+	}
+	switch operand.Kind() {
+	case reflect.Struct: // time
+		operandAsTime := operand.Interface().(time.Time)
+		// try our best to convert value from tags to time.Time
+		var (
+			v   time.Time
+			err error
+		)
+		if strings.ContainsAny(value, "T") {
+			v, err = time.Parse(TimeLayout, value)
+		} else {
+			v, err = time.Parse(DateLayout, value)
+		}
+		if err != nil {
+			panic(fmt.Sprintf("Failed to convert value %v from tag to time.Time: %v", value, err))
+		}
+		switch op {
+		case OpLessEqual:
+			return v.Before(operandAsTime) || v.Equal(operandAsTime)
+		case OpGreaterEqual:
+			return v.Equal(operandAsTime) || v.After(operandAsTime)
+		case OpLess:
+			return v.Before(operandAsTime)
+		case OpGreater:
+			return v.After(operandAsTime)
+		case OpEqual:
+			return v.Equal(operandAsTime)
+		}
+	case reflect.Float64:
+		operandFloat64 := operand.Interface().(float64)
+		var v float64
+		// try our best to convert value from tags to float64
+		v, err := strconv.ParseFloat(value, 64)
+		if err != nil {
+			panic(fmt.Sprintf("Failed to convert value %v from tag to float64: %v", value, err))
 		}
+		switch op {
+		case OpLessEqual:
+			return v <= operandFloat64
+		case OpGreaterEqual:
+			return v >= operandFloat64
+		case OpLess:
+			return v < operandFloat64
+		case OpGreater:
+			return v > operandFloat64
+		case OpEqual:
+			return v == operandFloat64
+		}
+	case reflect.Int64:
+		operandInt := operand.Interface().(int64)
+		var v int64
+		// if value looks like float, we try to parse it as float
+		if strings.ContainsAny(value, ".") {
+			v1, err := strconv.ParseFloat(value, 64)
+			if err != nil {
+				panic(fmt.Sprintf("Failed to convert value %v from tag to float64: %v", value, err))
+			}
+			v = int64(v1)
+		} else {
+			var err error
+			// try our best to convert value from tags to int64
+			v, err = strconv.ParseInt(value, 10, 64)
+			if err != nil {
+				panic(fmt.Sprintf("Failed to convert value %v from tag to int64: %v", value, err))
+			}
+		}
+		switch op {
+		case OpLessEqual:
+			return v <= operandInt
+		case OpGreaterEqual:
+			return v >= operandInt
+		case OpLess:
+			return v < operandInt
+		case OpGreater:
+			return v > operandInt
+		case OpEqual:
+			return v == operandInt
+		}
+	case reflect.String:
+		switch op {
+		case OpEqual:
+			return value == operand.String()
+		case OpContains:
+			return strings.Contains(value, operand.String())
+		}
+	default:
+		panic(fmt.Sprintf("Unknown kind of operand %v", operand.Kind()))
 	}
+
+	return false
 }
diff --git a/event/query/query.peg b/event/query/query.peg
new file mode 100644
index 0000000000000000000000000000000000000000..739892e4f704db4221676f0b84da3ca63889bb44
--- /dev/null
+++ b/event/query/query.peg
@@ -0,0 +1,33 @@
+package query
+
+type QueryParser Peg {
+}
+
+e <- '\"' condition ( ' '+ and ' '+ condition )* '\"' !.
+
+condition <- tag ' '* (le ' '* (number / time / date)
+                      / ge ' '* (number / time / date)
+                      / l ' '* (number / time / date)
+                      / g ' '* (number / time / date)
+                      / equal ' '* (number / time / date / value)
+                      / contains ' '* value
+                      )
+
+tag <- < (![ \t\n\r\\()"'=><] .)+ >
+value <- < '\'' (!["'] .)* '\''>
+number <- < ('0'
+           / [1-9] digit* ('.' digit*)?) >
+digit <- [0-9]
+time <- "TIME " < year '-' month '-' day 'T' digit digit ':' digit digit ':' digit digit (('-' / '+') digit digit ':' digit digit / 'Z') >
+date <- "DATE " < year '-' month '-' day >
+year <- ('1' / '2') digit digit digit
+month <- ('0' / '1') digit
+day <- ('0' / '1' / '2' / '3') digit
+and <- "AND"
+
+equal <- "="
+contains <- "CONTAINS"
+le <- "<="
+ge <- ">="
+l <- "<"
+g <- ">"
diff --git a/event/query/query.peg.go b/event/query/query.peg.go
new file mode 100644
index 0000000000000000000000000000000000000000..c86e4a47fb41be45336dfc7717d5a3703dfaee01
--- /dev/null
+++ b/event/query/query.peg.go
@@ -0,0 +1,1553 @@
+// nolint
+package query
+
+import (
+	"fmt"
+	"math"
+	"sort"
+	"strconv"
+)
+
+const endSymbol rune = 1114112
+
+/* The rule types inferred from the grammar are below. */
+type pegRule uint8
+
+const (
+	ruleUnknown pegRule = iota
+	rulee
+	rulecondition
+	ruletag
+	rulevalue
+	rulenumber
+	ruledigit
+	ruletime
+	ruledate
+	ruleyear
+	rulemonth
+	ruleday
+	ruleand
+	ruleequal
+	rulecontains
+	rulele
+	rulege
+	rulel
+	ruleg
+	rulePegText
+)
+
+var rul3s = [...]string{
+	"Unknown",
+	"e",
+	"condition",
+	"tag",
+	"value",
+	"number",
+	"digit",
+	"time",
+	"date",
+	"year",
+	"month",
+	"day",
+	"and",
+	"equal",
+	"contains",
+	"le",
+	"ge",
+	"l",
+	"g",
+	"PegText",
+}
+
+type token32 struct {
+	pegRule
+	begin, end uint32
+}
+
+func (t *token32) String() string {
+	return fmt.Sprintf("\x1B[34m%v\x1B[m %v %v", rul3s[t.pegRule], t.begin, t.end)
+}
+
+type node32 struct {
+	token32
+	up, next *node32
+}
+
+func (node *node32) print(pretty bool, buffer string) {
+	var print func(node *node32, depth int)
+	print = func(node *node32, depth int) {
+		for node != nil {
+			for c := 0; c < depth; c++ {
+				fmt.Printf(" ")
+			}
+			rule := rul3s[node.pegRule]
+			quote := strconv.Quote(string(([]rune(buffer)[node.begin:node.end])))
+			if !pretty {
+				fmt.Printf("%v %v\n", rule, quote)
+			} else {
+				fmt.Printf("\x1B[34m%v\x1B[m %v\n", rule, quote)
+			}
+			if node.up != nil {
+				print(node.up, depth+1)
+			}
+			node = node.next
+		}
+	}
+	print(node, 0)
+}
+
+func (node *node32) Print(buffer string) {
+	node.print(false, buffer)
+}
+
+func (node *node32) PrettyPrint(buffer string) {
+	node.print(true, buffer)
+}
+
+type tokens32 struct {
+	tree []token32
+}
+
+func (t *tokens32) Trim(length uint32) {
+	t.tree = t.tree[:length]
+}
+
+func (t *tokens32) Print() {
+	for _, token := range t.tree {
+		fmt.Println(token.String())
+	}
+}
+
+func (t *tokens32) AST() *node32 {
+	type element struct {
+		node *node32
+		down *element
+	}
+	tokens := t.Tokens()
+	var stack *element
+	for _, token := range tokens {
+		if token.begin == token.end {
+			continue
+		}
+		node := &node32{token32: token}
+		for stack != nil && stack.node.begin >= token.begin && stack.node.end <= token.end {
+			stack.node.next = node.up
+			node.up = stack.node
+			stack = stack.down
+		}
+		stack = &element{node: node, down: stack}
+	}
+	if stack != nil {
+		return stack.node
+	}
+	return nil
+}
+
+func (t *tokens32) PrintSyntaxTree(buffer string) {
+	t.AST().Print(buffer)
+}
+
+func (t *tokens32) PrettyPrintSyntaxTree(buffer string) {
+	t.AST().PrettyPrint(buffer)
+}
+
+func (t *tokens32) Add(rule pegRule, begin, end, index uint32) {
+	if tree := t.tree; int(index) >= len(tree) {
+		expanded := make([]token32, 2*len(tree))
+		copy(expanded, tree)
+		t.tree = expanded
+	}
+	t.tree[index] = token32{
+		pegRule: rule,
+		begin:   begin,
+		end:     end,
+	}
+}
+
+func (t *tokens32) Tokens() []token32 {
+	return t.tree
+}
+
+type QueryParser struct {
+	Buffer string
+	buffer []rune
+	rules  [20]func() bool
+	parse  func(rule ...int) error
+	reset  func()
+	Pretty bool
+	tokens32
+}
+
+func (p *QueryParser) Parse(rule ...int) error {
+	return p.parse(rule...)
+}
+
+func (p *QueryParser) Reset() {
+	p.reset()
+}
+
+type textPosition struct {
+	line, symbol int
+}
+
+type textPositionMap map[int]textPosition
+
+func translatePositions(buffer []rune, positions []int) textPositionMap {
+	length, translations, j, line, symbol := len(positions), make(textPositionMap, len(positions)), 0, 1, 0
+	sort.Ints(positions)
+
+search:
+	for i, c := range buffer {
+		if c == '\n' {
+			line, symbol = line+1, 0
+		} else {
+			symbol++
+		}
+		if i == positions[j] {
+			translations[positions[j]] = textPosition{line, symbol}
+			for j++; j < length; j++ {
+				if i != positions[j] {
+					continue search
+				}
+			}
+			break search
+		}
+	}
+
+	return translations
+}
+
+type parseError struct {
+	p   *QueryParser
+	max token32
+}
+
+func (e *parseError) Error() string {
+	tokens, error := []token32{e.max}, "\n"
+	positions, p := make([]int, 2*len(tokens)), 0
+	for _, token := range tokens {
+		positions[p], p = int(token.begin), p+1
+		positions[p], p = int(token.end), p+1
+	}
+	translations := translatePositions(e.p.buffer, positions)
+	format := "parse error near %v (line %v symbol %v - line %v symbol %v):\n%v\n"
+	if e.p.Pretty {
+		format = "parse error near \x1B[34m%v\x1B[m (line %v symbol %v - line %v symbol %v):\n%v\n"
+	}
+	for _, token := range tokens {
+		begin, end := int(token.begin), int(token.end)
+		error += fmt.Sprintf(format,
+			rul3s[token.pegRule],
+			translations[begin].line, translations[begin].symbol,
+			translations[end].line, translations[end].symbol,
+			strconv.Quote(string(e.p.buffer[begin:end])))
+	}
+
+	return error
+}
+
+func (p *QueryParser) PrintSyntaxTree() {
+	if p.Pretty {
+		p.tokens32.PrettyPrintSyntaxTree(p.Buffer)
+	} else {
+		p.tokens32.PrintSyntaxTree(p.Buffer)
+	}
+}
+
+func (p *QueryParser) Init() {
+	var (
+		max                  token32
+		position, tokenIndex uint32
+		buffer               []rune
+	)
+	p.reset = func() {
+		max = token32{}
+		position, tokenIndex = 0, 0
+
+		p.buffer = []rune(p.Buffer)
+		if len(p.buffer) == 0 || p.buffer[len(p.buffer)-1] != endSymbol {
+			p.buffer = append(p.buffer, endSymbol)
+		}
+		buffer = p.buffer
+	}
+	p.reset()
+
+	_rules := p.rules
+	tree := tokens32{tree: make([]token32, math.MaxInt16)}
+	p.parse = func(rule ...int) error {
+		r := 1
+		if len(rule) > 0 {
+			r = rule[0]
+		}
+		matches := p.rules[r]()
+		p.tokens32 = tree
+		if matches {
+			p.Trim(tokenIndex)
+			return nil
+		}
+		return &parseError{p, max}
+	}
+
+	add := func(rule pegRule, begin uint32) {
+		tree.Add(rule, begin, position, tokenIndex)
+		tokenIndex++
+		if begin != position && position > max.end {
+			max = token32{rule, begin, position}
+		}
+	}
+
+	matchDot := func() bool {
+		if buffer[position] != endSymbol {
+			position++
+			return true
+		}
+		return false
+	}
+
+	/*matchChar := func(c byte) bool {
+		if buffer[position] == c {
+			position++
+			return true
+		}
+		return false
+	}*/
+
+	/*matchRange := func(lower byte, upper byte) bool {
+		if c := buffer[position]; c >= lower && c <= upper {
+			position++
+			return true
+		}
+		return false
+	}*/
+
+	_rules = [...]func() bool{
+		nil,
+		/* 0 e <- <('"' condition (' '+ and ' '+ condition)* '"' !.)> */
+		func() bool {
+			position0, tokenIndex0 := position, tokenIndex
+			{
+				position1 := position
+				if buffer[position] != rune('"') {
+					goto l0
+				}
+				position++
+				if !_rules[rulecondition]() {
+					goto l0
+				}
+			l2:
+				{
+					position3, tokenIndex3 := position, tokenIndex
+					if buffer[position] != rune(' ') {
+						goto l3
+					}
+					position++
+				l4:
+					{
+						position5, tokenIndex5 := position, tokenIndex
+						if buffer[position] != rune(' ') {
+							goto l5
+						}
+						position++
+						goto l4
+					l5:
+						position, tokenIndex = position5, tokenIndex5
+					}
+					{
+						position6 := position
+						{
+							position7, tokenIndex7 := position, tokenIndex
+							if buffer[position] != rune('a') {
+								goto l8
+							}
+							position++
+							goto l7
+						l8:
+							position, tokenIndex = position7, tokenIndex7
+							if buffer[position] != rune('A') {
+								goto l3
+							}
+							position++
+						}
+					l7:
+						{
+							position9, tokenIndex9 := position, tokenIndex
+							if buffer[position] != rune('n') {
+								goto l10
+							}
+							position++
+							goto l9
+						l10:
+							position, tokenIndex = position9, tokenIndex9
+							if buffer[position] != rune('N') {
+								goto l3
+							}
+							position++
+						}
+					l9:
+						{
+							position11, tokenIndex11 := position, tokenIndex
+							if buffer[position] != rune('d') {
+								goto l12
+							}
+							position++
+							goto l11
+						l12:
+							position, tokenIndex = position11, tokenIndex11
+							if buffer[position] != rune('D') {
+								goto l3
+							}
+							position++
+						}
+					l11:
+						add(ruleand, position6)
+					}
+					if buffer[position] != rune(' ') {
+						goto l3
+					}
+					position++
+				l13:
+					{
+						position14, tokenIndex14 := position, tokenIndex
+						if buffer[position] != rune(' ') {
+							goto l14
+						}
+						position++
+						goto l13
+					l14:
+						position, tokenIndex = position14, tokenIndex14
+					}
+					if !_rules[rulecondition]() {
+						goto l3
+					}
+					goto l2
+				l3:
+					position, tokenIndex = position3, tokenIndex3
+				}
+				if buffer[position] != rune('"') {
+					goto l0
+				}
+				position++
+				{
+					position15, tokenIndex15 := position, tokenIndex
+					if !matchDot() {
+						goto l15
+					}
+					goto l0
+				l15:
+					position, tokenIndex = position15, tokenIndex15
+				}
+				add(rulee, position1)
+			}
+			return true
+		l0:
+			position, tokenIndex = position0, tokenIndex0
+			return false
+		},
+		/* 1 condition <- <(tag ' '* ((le ' '* ((&('D' | 'd') date) | (&('T' | 't') time) | (&('0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9') number))) / (ge ' '* ((&('D' | 'd') date) | (&('T' | 't') time) | (&('0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9') number))) / ((&('=') (equal ' '* ((&('\'') value) | (&('D' | 'd') date) | (&('T' | 't') time) | (&('0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9') number)))) | (&('>') (g ' '* ((&('D' | 'd') date) | (&('T' | 't') time) | (&('0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9') number)))) | (&('<') (l ' '* ((&('D' | 'd') date) | (&('T' | 't') time) | (&('0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9') number)))) | (&('C' | 'c') (contains ' '* value)))))> */
+		func() bool {
+			position16, tokenIndex16 := position, tokenIndex
+			{
+				position17 := position
+				{
+					position18 := position
+					{
+						position19 := position
+						{
+							position22, tokenIndex22 := position, tokenIndex
+							{
+								switch buffer[position] {
+								case '<':
+									if buffer[position] != rune('<') {
+										goto l22
+									}
+									position++
+									break
+								case '>':
+									if buffer[position] != rune('>') {
+										goto l22
+									}
+									position++
+									break
+								case '=':
+									if buffer[position] != rune('=') {
+										goto l22
+									}
+									position++
+									break
+								case '\'':
+									if buffer[position] != rune('\'') {
+										goto l22
+									}
+									position++
+									break
+								case '"':
+									if buffer[position] != rune('"') {
+										goto l22
+									}
+									position++
+									break
+								case ')':
+									if buffer[position] != rune(')') {
+										goto l22
+									}
+									position++
+									break
+								case '(':
+									if buffer[position] != rune('(') {
+										goto l22
+									}
+									position++
+									break
+								case '\\':
+									if buffer[position] != rune('\\') {
+										goto l22
+									}
+									position++
+									break
+								case '\r':
+									if buffer[position] != rune('\r') {
+										goto l22
+									}
+									position++
+									break
+								case '\n':
+									if buffer[position] != rune('\n') {
+										goto l22
+									}
+									position++
+									break
+								case '\t':
+									if buffer[position] != rune('\t') {
+										goto l22
+									}
+									position++
+									break
+								default:
+									if buffer[position] != rune(' ') {
+										goto l22
+									}
+									position++
+									break
+								}
+							}
+
+							goto l16
+						l22:
+							position, tokenIndex = position22, tokenIndex22
+						}
+						if !matchDot() {
+							goto l16
+						}
+					l20:
+						{
+							position21, tokenIndex21 := position, tokenIndex
+							{
+								position24, tokenIndex24 := position, tokenIndex
+								{
+									switch buffer[position] {
+									case '<':
+										if buffer[position] != rune('<') {
+											goto l24
+										}
+										position++
+										break
+									case '>':
+										if buffer[position] != rune('>') {
+											goto l24
+										}
+										position++
+										break
+									case '=':
+										if buffer[position] != rune('=') {
+											goto l24
+										}
+										position++
+										break
+									case '\'':
+										if buffer[position] != rune('\'') {
+											goto l24
+										}
+										position++
+										break
+									case '"':
+										if buffer[position] != rune('"') {
+											goto l24
+										}
+										position++
+										break
+									case ')':
+										if buffer[position] != rune(')') {
+											goto l24
+										}
+										position++
+										break
+									case '(':
+										if buffer[position] != rune('(') {
+											goto l24
+										}
+										position++
+										break
+									case '\\':
+										if buffer[position] != rune('\\') {
+											goto l24
+										}
+										position++
+										break
+									case '\r':
+										if buffer[position] != rune('\r') {
+											goto l24
+										}
+										position++
+										break
+									case '\n':
+										if buffer[position] != rune('\n') {
+											goto l24
+										}
+										position++
+										break
+									case '\t':
+										if buffer[position] != rune('\t') {
+											goto l24
+										}
+										position++
+										break
+									default:
+										if buffer[position] != rune(' ') {
+											goto l24
+										}
+										position++
+										break
+									}
+								}
+
+								goto l21
+							l24:
+								position, tokenIndex = position24, tokenIndex24
+							}
+							if !matchDot() {
+								goto l21
+							}
+							goto l20
+						l21:
+							position, tokenIndex = position21, tokenIndex21
+						}
+						add(rulePegText, position19)
+					}
+					add(ruletag, position18)
+				}
+			l26:
+				{
+					position27, tokenIndex27 := position, tokenIndex
+					if buffer[position] != rune(' ') {
+						goto l27
+					}
+					position++
+					goto l26
+				l27:
+					position, tokenIndex = position27, tokenIndex27
+				}
+				{
+					position28, tokenIndex28 := position, tokenIndex
+					{
+						position30 := position
+						if buffer[position] != rune('<') {
+							goto l29
+						}
+						position++
+						if buffer[position] != rune('=') {
+							goto l29
+						}
+						position++
+						add(rulele, position30)
+					}
+				l31:
+					{
+						position32, tokenIndex32 := position, tokenIndex
+						if buffer[position] != rune(' ') {
+							goto l32
+						}
+						position++
+						goto l31
+					l32:
+						position, tokenIndex = position32, tokenIndex32
+					}
+					{
+						switch buffer[position] {
+						case 'D', 'd':
+							if !_rules[ruledate]() {
+								goto l29
+							}
+							break
+						case 'T', 't':
+							if !_rules[ruletime]() {
+								goto l29
+							}
+							break
+						default:
+							if !_rules[rulenumber]() {
+								goto l29
+							}
+							break
+						}
+					}
+
+					goto l28
+				l29:
+					position, tokenIndex = position28, tokenIndex28
+					{
+						position35 := position
+						if buffer[position] != rune('>') {
+							goto l34
+						}
+						position++
+						if buffer[position] != rune('=') {
+							goto l34
+						}
+						position++
+						add(rulege, position35)
+					}
+				l36:
+					{
+						position37, tokenIndex37 := position, tokenIndex
+						if buffer[position] != rune(' ') {
+							goto l37
+						}
+						position++
+						goto l36
+					l37:
+						position, tokenIndex = position37, tokenIndex37
+					}
+					{
+						switch buffer[position] {
+						case 'D', 'd':
+							if !_rules[ruledate]() {
+								goto l34
+							}
+							break
+						case 'T', 't':
+							if !_rules[ruletime]() {
+								goto l34
+							}
+							break
+						default:
+							if !_rules[rulenumber]() {
+								goto l34
+							}
+							break
+						}
+					}
+
+					goto l28
+				l34:
+					position, tokenIndex = position28, tokenIndex28
+					{
+						switch buffer[position] {
+						case '=':
+							{
+								position40 := position
+								if buffer[position] != rune('=') {
+									goto l16
+								}
+								position++
+								add(ruleequal, position40)
+							}
+						l41:
+							{
+								position42, tokenIndex42 := position, tokenIndex
+								if buffer[position] != rune(' ') {
+									goto l42
+								}
+								position++
+								goto l41
+							l42:
+								position, tokenIndex = position42, tokenIndex42
+							}
+							{
+								switch buffer[position] {
+								case '\'':
+									if !_rules[rulevalue]() {
+										goto l16
+									}
+									break
+								case 'D', 'd':
+									if !_rules[ruledate]() {
+										goto l16
+									}
+									break
+								case 'T', 't':
+									if !_rules[ruletime]() {
+										goto l16
+									}
+									break
+								default:
+									if !_rules[rulenumber]() {
+										goto l16
+									}
+									break
+								}
+							}
+
+							break
+						case '>':
+							{
+								position44 := position
+								if buffer[position] != rune('>') {
+									goto l16
+								}
+								position++
+								add(ruleg, position44)
+							}
+						l45:
+							{
+								position46, tokenIndex46 := position, tokenIndex
+								if buffer[position] != rune(' ') {
+									goto l46
+								}
+								position++
+								goto l45
+							l46:
+								position, tokenIndex = position46, tokenIndex46
+							}
+							{
+								switch buffer[position] {
+								case 'D', 'd':
+									if !_rules[ruledate]() {
+										goto l16
+									}
+									break
+								case 'T', 't':
+									if !_rules[ruletime]() {
+										goto l16
+									}
+									break
+								default:
+									if !_rules[rulenumber]() {
+										goto l16
+									}
+									break
+								}
+							}
+
+							break
+						case '<':
+							{
+								position48 := position
+								if buffer[position] != rune('<') {
+									goto l16
+								}
+								position++
+								add(rulel, position48)
+							}
+						l49:
+							{
+								position50, tokenIndex50 := position, tokenIndex
+								if buffer[position] != rune(' ') {
+									goto l50
+								}
+								position++
+								goto l49
+							l50:
+								position, tokenIndex = position50, tokenIndex50
+							}
+							{
+								switch buffer[position] {
+								case 'D', 'd':
+									if !_rules[ruledate]() {
+										goto l16
+									}
+									break
+								case 'T', 't':
+									if !_rules[ruletime]() {
+										goto l16
+									}
+									break
+								default:
+									if !_rules[rulenumber]() {
+										goto l16
+									}
+									break
+								}
+							}
+
+							break
+						default:
+							{
+								position52 := position
+								{
+									position53, tokenIndex53 := position, tokenIndex
+									if buffer[position] != rune('c') {
+										goto l54
+									}
+									position++
+									goto l53
+								l54:
+									position, tokenIndex = position53, tokenIndex53
+									if buffer[position] != rune('C') {
+										goto l16
+									}
+									position++
+								}
+							l53:
+								{
+									position55, tokenIndex55 := position, tokenIndex
+									if buffer[position] != rune('o') {
+										goto l56
+									}
+									position++
+									goto l55
+								l56:
+									position, tokenIndex = position55, tokenIndex55
+									if buffer[position] != rune('O') {
+										goto l16
+									}
+									position++
+								}
+							l55:
+								{
+									position57, tokenIndex57 := position, tokenIndex
+									if buffer[position] != rune('n') {
+										goto l58
+									}
+									position++
+									goto l57
+								l58:
+									position, tokenIndex = position57, tokenIndex57
+									if buffer[position] != rune('N') {
+										goto l16
+									}
+									position++
+								}
+							l57:
+								{
+									position59, tokenIndex59 := position, tokenIndex
+									if buffer[position] != rune('t') {
+										goto l60
+									}
+									position++
+									goto l59
+								l60:
+									position, tokenIndex = position59, tokenIndex59
+									if buffer[position] != rune('T') {
+										goto l16
+									}
+									position++
+								}
+							l59:
+								{
+									position61, tokenIndex61 := position, tokenIndex
+									if buffer[position] != rune('a') {
+										goto l62
+									}
+									position++
+									goto l61
+								l62:
+									position, tokenIndex = position61, tokenIndex61
+									if buffer[position] != rune('A') {
+										goto l16
+									}
+									position++
+								}
+							l61:
+								{
+									position63, tokenIndex63 := position, tokenIndex
+									if buffer[position] != rune('i') {
+										goto l64
+									}
+									position++
+									goto l63
+								l64:
+									position, tokenIndex = position63, tokenIndex63
+									if buffer[position] != rune('I') {
+										goto l16
+									}
+									position++
+								}
+							l63:
+								{
+									position65, tokenIndex65 := position, tokenIndex
+									if buffer[position] != rune('n') {
+										goto l66
+									}
+									position++
+									goto l65
+								l66:
+									position, tokenIndex = position65, tokenIndex65
+									if buffer[position] != rune('N') {
+										goto l16
+									}
+									position++
+								}
+							l65:
+								{
+									position67, tokenIndex67 := position, tokenIndex
+									if buffer[position] != rune('s') {
+										goto l68
+									}
+									position++
+									goto l67
+								l68:
+									position, tokenIndex = position67, tokenIndex67
+									if buffer[position] != rune('S') {
+										goto l16
+									}
+									position++
+								}
+							l67:
+								add(rulecontains, position52)
+							}
+						l69:
+							{
+								position70, tokenIndex70 := position, tokenIndex
+								if buffer[position] != rune(' ') {
+									goto l70
+								}
+								position++
+								goto l69
+							l70:
+								position, tokenIndex = position70, tokenIndex70
+							}
+							if !_rules[rulevalue]() {
+								goto l16
+							}
+							break
+						}
+					}
+
+				}
+			l28:
+				add(rulecondition, position17)
+			}
+			return true
+		l16:
+			position, tokenIndex = position16, tokenIndex16
+			return false
+		},
+		/* 2 tag <- <<(!((&('<') '<') | (&('>') '>') | (&('=') '=') | (&('\'') '\'') | (&('"') '"') | (&(')') ')') | (&('(') '(') | (&('\\') '\\') | (&('\r') '\r') | (&('\n') '\n') | (&('\t') '\t') | (&(' ') ' ')) .)+>> */
+		nil,
+		/* 3 value <- <<('\'' (!('"' / '\'') .)* '\'')>> */
+		func() bool {
+			position72, tokenIndex72 := position, tokenIndex
+			{
+				position73 := position
+				{
+					position74 := position
+					if buffer[position] != rune('\'') {
+						goto l72
+					}
+					position++
+				l75:
+					{
+						position76, tokenIndex76 := position, tokenIndex
+						{
+							position77, tokenIndex77 := position, tokenIndex
+							{
+								position78, tokenIndex78 := position, tokenIndex
+								if buffer[position] != rune('"') {
+									goto l79
+								}
+								position++
+								goto l78
+							l79:
+								position, tokenIndex = position78, tokenIndex78
+								if buffer[position] != rune('\'') {
+									goto l77
+								}
+								position++
+							}
+						l78:
+							goto l76
+						l77:
+							position, tokenIndex = position77, tokenIndex77
+						}
+						if !matchDot() {
+							goto l76
+						}
+						goto l75
+					l76:
+						position, tokenIndex = position76, tokenIndex76
+					}
+					if buffer[position] != rune('\'') {
+						goto l72
+					}
+					position++
+					add(rulePegText, position74)
+				}
+				add(rulevalue, position73)
+			}
+			return true
+		l72:
+			position, tokenIndex = position72, tokenIndex72
+			return false
+		},
+		/* 4 number <- <<('0' / ([1-9] digit* ('.' digit*)?))>> */
+		func() bool {
+			position80, tokenIndex80 := position, tokenIndex
+			{
+				position81 := position
+				{
+					position82 := position
+					{
+						position83, tokenIndex83 := position, tokenIndex
+						if buffer[position] != rune('0') {
+							goto l84
+						}
+						position++
+						goto l83
+					l84:
+						position, tokenIndex = position83, tokenIndex83
+						if c := buffer[position]; c < rune('1') || c > rune('9') {
+							goto l80
+						}
+						position++
+					l85:
+						{
+							position86, tokenIndex86 := position, tokenIndex
+							if !_rules[ruledigit]() {
+								goto l86
+							}
+							goto l85
+						l86:
+							position, tokenIndex = position86, tokenIndex86
+						}
+						{
+							position87, tokenIndex87 := position, tokenIndex
+							if buffer[position] != rune('.') {
+								goto l87
+							}
+							position++
+						l89:
+							{
+								position90, tokenIndex90 := position, tokenIndex
+								if !_rules[ruledigit]() {
+									goto l90
+								}
+								goto l89
+							l90:
+								position, tokenIndex = position90, tokenIndex90
+							}
+							goto l88
+						l87:
+							position, tokenIndex = position87, tokenIndex87
+						}
+					l88:
+					}
+				l83:
+					add(rulePegText, position82)
+				}
+				add(rulenumber, position81)
+			}
+			return true
+		l80:
+			position, tokenIndex = position80, tokenIndex80
+			return false
+		},
+		/* 5 digit <- <[0-9]> */
+		func() bool {
+			position91, tokenIndex91 := position, tokenIndex
+			{
+				position92 := position
+				if c := buffer[position]; c < rune('0') || c > rune('9') {
+					goto l91
+				}
+				position++
+				add(ruledigit, position92)
+			}
+			return true
+		l91:
+			position, tokenIndex = position91, tokenIndex91
+			return false
+		},
+		/* 6 time <- <(('t' / 'T') ('i' / 'I') ('m' / 'M') ('e' / 'E') ' ' <(year '-' month '-' day 'T' digit digit ':' digit digit ':' digit digit ((('-' / '+') digit digit ':' digit digit) / 'Z'))>)> */
+		func() bool {
+			position93, tokenIndex93 := position, tokenIndex
+			{
+				position94 := position
+				{
+					position95, tokenIndex95 := position, tokenIndex
+					if buffer[position] != rune('t') {
+						goto l96
+					}
+					position++
+					goto l95
+				l96:
+					position, tokenIndex = position95, tokenIndex95
+					if buffer[position] != rune('T') {
+						goto l93
+					}
+					position++
+				}
+			l95:
+				{
+					position97, tokenIndex97 := position, tokenIndex
+					if buffer[position] != rune('i') {
+						goto l98
+					}
+					position++
+					goto l97
+				l98:
+					position, tokenIndex = position97, tokenIndex97
+					if buffer[position] != rune('I') {
+						goto l93
+					}
+					position++
+				}
+			l97:
+				{
+					position99, tokenIndex99 := position, tokenIndex
+					if buffer[position] != rune('m') {
+						goto l100
+					}
+					position++
+					goto l99
+				l100:
+					position, tokenIndex = position99, tokenIndex99
+					if buffer[position] != rune('M') {
+						goto l93
+					}
+					position++
+				}
+			l99:
+				{
+					position101, tokenIndex101 := position, tokenIndex
+					if buffer[position] != rune('e') {
+						goto l102
+					}
+					position++
+					goto l101
+				l102:
+					position, tokenIndex = position101, tokenIndex101
+					if buffer[position] != rune('E') {
+						goto l93
+					}
+					position++
+				}
+			l101:
+				if buffer[position] != rune(' ') {
+					goto l93
+				}
+				position++
+				{
+					position103 := position
+					if !_rules[ruleyear]() {
+						goto l93
+					}
+					if buffer[position] != rune('-') {
+						goto l93
+					}
+					position++
+					if !_rules[rulemonth]() {
+						goto l93
+					}
+					if buffer[position] != rune('-') {
+						goto l93
+					}
+					position++
+					if !_rules[ruleday]() {
+						goto l93
+					}
+					if buffer[position] != rune('T') {
+						goto l93
+					}
+					position++
+					if !_rules[ruledigit]() {
+						goto l93
+					}
+					if !_rules[ruledigit]() {
+						goto l93
+					}
+					if buffer[position] != rune(':') {
+						goto l93
+					}
+					position++
+					if !_rules[ruledigit]() {
+						goto l93
+					}
+					if !_rules[ruledigit]() {
+						goto l93
+					}
+					if buffer[position] != rune(':') {
+						goto l93
+					}
+					position++
+					if !_rules[ruledigit]() {
+						goto l93
+					}
+					if !_rules[ruledigit]() {
+						goto l93
+					}
+					{
+						position104, tokenIndex104 := position, tokenIndex
+						{
+							position106, tokenIndex106 := position, tokenIndex
+							if buffer[position] != rune('-') {
+								goto l107
+							}
+							position++
+							goto l106
+						l107:
+							position, tokenIndex = position106, tokenIndex106
+							if buffer[position] != rune('+') {
+								goto l105
+							}
+							position++
+						}
+					l106:
+						if !_rules[ruledigit]() {
+							goto l105
+						}
+						if !_rules[ruledigit]() {
+							goto l105
+						}
+						if buffer[position] != rune(':') {
+							goto l105
+						}
+						position++
+						if !_rules[ruledigit]() {
+							goto l105
+						}
+						if !_rules[ruledigit]() {
+							goto l105
+						}
+						goto l104
+					l105:
+						position, tokenIndex = position104, tokenIndex104
+						if buffer[position] != rune('Z') {
+							goto l93
+						}
+						position++
+					}
+				l104:
+					add(rulePegText, position103)
+				}
+				add(ruletime, position94)
+			}
+			return true
+		l93:
+			position, tokenIndex = position93, tokenIndex93
+			return false
+		},
+		/* 7 date <- <(('d' / 'D') ('a' / 'A') ('t' / 'T') ('e' / 'E') ' ' <(year '-' month '-' day)>)> */
+		func() bool {
+			position108, tokenIndex108 := position, tokenIndex
+			{
+				position109 := position
+				{
+					position110, tokenIndex110 := position, tokenIndex
+					if buffer[position] != rune('d') {
+						goto l111
+					}
+					position++
+					goto l110
+				l111:
+					position, tokenIndex = position110, tokenIndex110
+					if buffer[position] != rune('D') {
+						goto l108
+					}
+					position++
+				}
+			l110:
+				{
+					position112, tokenIndex112 := position, tokenIndex
+					if buffer[position] != rune('a') {
+						goto l113
+					}
+					position++
+					goto l112
+				l113:
+					position, tokenIndex = position112, tokenIndex112
+					if buffer[position] != rune('A') {
+						goto l108
+					}
+					position++
+				}
+			l112:
+				{
+					position114, tokenIndex114 := position, tokenIndex
+					if buffer[position] != rune('t') {
+						goto l115
+					}
+					position++
+					goto l114
+				l115:
+					position, tokenIndex = position114, tokenIndex114
+					if buffer[position] != rune('T') {
+						goto l108
+					}
+					position++
+				}
+			l114:
+				{
+					position116, tokenIndex116 := position, tokenIndex
+					if buffer[position] != rune('e') {
+						goto l117
+					}
+					position++
+					goto l116
+				l117:
+					position, tokenIndex = position116, tokenIndex116
+					if buffer[position] != rune('E') {
+						goto l108
+					}
+					position++
+				}
+			l116:
+				if buffer[position] != rune(' ') {
+					goto l108
+				}
+				position++
+				{
+					position118 := position
+					if !_rules[ruleyear]() {
+						goto l108
+					}
+					if buffer[position] != rune('-') {
+						goto l108
+					}
+					position++
+					if !_rules[rulemonth]() {
+						goto l108
+					}
+					if buffer[position] != rune('-') {
+						goto l108
+					}
+					position++
+					if !_rules[ruleday]() {
+						goto l108
+					}
+					add(rulePegText, position118)
+				}
+				add(ruledate, position109)
+			}
+			return true
+		l108:
+			position, tokenIndex = position108, tokenIndex108
+			return false
+		},
+		/* 8 year <- <(('1' / '2') digit digit digit)> */
+		func() bool {
+			position119, tokenIndex119 := position, tokenIndex
+			{
+				position120 := position
+				{
+					position121, tokenIndex121 := position, tokenIndex
+					if buffer[position] != rune('1') {
+						goto l122
+					}
+					position++
+					goto l121
+				l122:
+					position, tokenIndex = position121, tokenIndex121
+					if buffer[position] != rune('2') {
+						goto l119
+					}
+					position++
+				}
+			l121:
+				if !_rules[ruledigit]() {
+					goto l119
+				}
+				if !_rules[ruledigit]() {
+					goto l119
+				}
+				if !_rules[ruledigit]() {
+					goto l119
+				}
+				add(ruleyear, position120)
+			}
+			return true
+		l119:
+			position, tokenIndex = position119, tokenIndex119
+			return false
+		},
+		/* 9 month <- <(('0' / '1') digit)> */
+		func() bool {
+			position123, tokenIndex123 := position, tokenIndex
+			{
+				position124 := position
+				{
+					position125, tokenIndex125 := position, tokenIndex
+					if buffer[position] != rune('0') {
+						goto l126
+					}
+					position++
+					goto l125
+				l126:
+					position, tokenIndex = position125, tokenIndex125
+					if buffer[position] != rune('1') {
+						goto l123
+					}
+					position++
+				}
+			l125:
+				if !_rules[ruledigit]() {
+					goto l123
+				}
+				add(rulemonth, position124)
+			}
+			return true
+		l123:
+			position, tokenIndex = position123, tokenIndex123
+			return false
+		},
+		/* 10 day <- <(((&('3') '3') | (&('2') '2') | (&('1') '1') | (&('0') '0')) digit)> */
+		func() bool {
+			position127, tokenIndex127 := position, tokenIndex
+			{
+				position128 := position
+				{
+					switch buffer[position] {
+					case '3':
+						if buffer[position] != rune('3') {
+							goto l127
+						}
+						position++
+						break
+					case '2':
+						if buffer[position] != rune('2') {
+							goto l127
+						}
+						position++
+						break
+					case '1':
+						if buffer[position] != rune('1') {
+							goto l127
+						}
+						position++
+						break
+					default:
+						if buffer[position] != rune('0') {
+							goto l127
+						}
+						position++
+						break
+					}
+				}
+
+				if !_rules[ruledigit]() {
+					goto l127
+				}
+				add(ruleday, position128)
+			}
+			return true
+		l127:
+			position, tokenIndex = position127, tokenIndex127
+			return false
+		},
+		/* 11 and <- <(('a' / 'A') ('n' / 'N') ('d' / 'D'))> */
+		nil,
+		/* 12 equal <- <'='> */
+		nil,
+		/* 13 contains <- <(('c' / 'C') ('o' / 'O') ('n' / 'N') ('t' / 'T') ('a' / 'A') ('i' / 'I') ('n' / 'N') ('s' / 'S'))> */
+		nil,
+		/* 14 le <- <('<' '=')> */
+		nil,
+		/* 15 ge <- <('>' '=')> */
+		nil,
+		/* 16 l <- <'<'> */
+		nil,
+		/* 17 g <- <'>'> */
+		nil,
+		nil,
+	}
+	p.rules = _rules
+}
diff --git a/event/query/query_test.go b/event/query/query_test.go
index a7116b0a8b43c50e2099f82b6ede2178fa22bcdc..0951bf434e92f7f1cd6e17c572bc22fd504f06cb 100644
--- a/event/query/query_test.go
+++ b/event/query/query_test.go
@@ -1,53 +1,84 @@
 package query
 
 import (
+	"fmt"
 	"testing"
+	"time"
 
-	"github.com/hyperledger/burrow/logging/structure"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
-	"github.com/tendermint/tendermint/libs/pubsub"
 )
 
-func TestQueryBuilder(t *testing.T) {
-	qb := NewBuilder()
-	qry, err := qb.Query()
-	require.NoError(t, err)
-	assert.Equal(t, emptyString, qry.String())
+func TestMatches(t *testing.T) {
+	var (
+		txDate = "2017-01-01"
+		txTime = "2018-05-03T14:45:00Z"
+	)
 
-	qb = qb.AndGreaterThanOrEqual("foo.size", 45)
-	qry, err = qb.Query()
-	require.NoError(t, err)
-	assert.Equal(t, "foo.size >= 45", qry.String())
+	testCases := []struct {
+		s       string
+		tags    map[string]interface{}
+		err     bool
+		matches bool
+	}{
+		{"tm.events.type='NewBlock'", map[string]interface{}{"tm.events.type": "NewBlock"}, false, true},
 
-	qb = qb.AndEquals("bar.name", "marmot")
-	qry, err = qb.Query()
-	require.NoError(t, err)
-	assert.Equal(t, "foo.size >= 45 AND bar.name = 'marmot'", qry.String())
+		{"tx.gas > 7", map[string]interface{}{"tx.gas": "8"}, false, true},
+		{"tx.gas > 7 AND tx.gas < 9", map[string]interface{}{"tx.gas": "8"}, false, true},
+		{"body.weight >= 3.5", map[string]interface{}{"body.weight": "3.5"}, false, true},
+		{"account.balance < 1000.0", map[string]interface{}{"account.balance": "900"}, false, true},
+		{"apples.kg <= 4", map[string]interface{}{"apples.kg": "4.0"}, false, true},
+		{"body.weight >= 4.5", map[string]interface{}{"body.weight": fmt.Sprintf("%v", float32(4.5))}, false, true},
+		{"oranges.kg < 4 AND watermellons.kg > 10", map[string]interface{}{"oranges.kg": "3", "watermellons.kg": "12"}, false, true},
+		{"peaches.kg < 4", map[string]interface{}{"peaches.kg": "5"}, false, false},
 
-	assert.True(t, qry.Matches(makeTagMap("foo.size", 80, "bar.name", "marmot")))
-	assert.False(t, qry.Matches(makeTagMap("foo.size", 8, "bar.name", "marmot")))
-	assert.False(t, qry.Matches(makeTagMap("foo.size", 80, "bar.name", "marot")))
+		{"tx.date > DATE 2017-01-01", map[string]interface{}{"tx.date": time.Now().Format(DateLayout)}, false, true},
+		{"tx.date = DATE 2017-01-01", map[string]interface{}{"tx.date": txDate}, false, true},
+		{"tx.date = DATE 2018-01-01", map[string]interface{}{"tx.date": txDate}, false, false},
 
-	qb = qb.AndContains("bar.desc", "burrow")
-	qry, err = qb.Query()
-	require.NoError(t, err)
-	assert.Equal(t, "foo.size >= 45 AND bar.name = 'marmot' AND bar.desc CONTAINS 'burrow'", qry.String())
+		{"tx.time >= TIME 2013-05-03T14:45:00Z", map[string]interface{}{"tx.time": time.Now().Format(TimeLayout)}, false, true},
+		{"tx.time = TIME 2013-05-03T14:45:00Z", map[string]interface{}{"tx.time": txTime}, false, false},
 
-	assert.True(t, qry.Matches(makeTagMap("foo.size", 80, "bar.name", "marmot", "bar.desc", "lives in a burrow")))
-	assert.False(t, qry.Matches(makeTagMap("foo.size", 80, "bar.name", "marmot", "bar.desc", "lives in a shoe")))
+		{"abci.owner.name CONTAINS 'Igor'", map[string]interface{}{"abci.owner.name": "Igor,Ivan"}, false, true},
+		{"abci.owner.name CONTAINS 'Igor'", map[string]interface{}{"abci.owner.name": "Pavel,Ivan"}, false, false},
+	}
 
-	qb = NewBuilder().AndEquals("foo", "bar")
-	qb = qb.And(NewBuilder().AndGreaterThanOrEqual("frogs", 4))
-	qry, err = qb.Query()
-	require.NoError(t, err)
-	assert.Equal(t, "foo = 'bar' AND frogs >= 4", qry.String())
+	for _, tc := range testCases {
+		q, err := New(tc.s)
+		if !tc.err {
+			require.Nil(t, err)
+		}
+
+		if tc.matches {
+			assert.True(t, q.Matches(TagMap(tc.tags)), "Query '%s' should match %v", tc.s, tc.tags)
+		} else {
+			assert.False(t, q.Matches(TagMap(tc.tags)), "Query '%s' should not match %v", tc.s, tc.tags)
+		}
+	}
 }
 
-func makeTagMap(keyvals ...interface{}) pubsub.TagMap {
-	tmap := make(map[string]string)
-	for i := 0; i < len(keyvals); i += 2 {
-		tmap[keyvals[i].(string)] = structure.StringifyKey(keyvals[i+1])
+func TestMustParse(t *testing.T) {
+	assert.Panics(t, func() { MustParse("=") })
+	assert.NotPanics(t, func() { MustParse("tm.events.type='NewBlock'") })
+}
+
+func TestConditions(t *testing.T) {
+	txTime, err := time.Parse(time.RFC3339, "2013-05-03T14:45:00Z")
+	require.NoError(t, err)
+
+	testCases := []struct {
+		s          string
+		conditions []Condition
+	}{
+		{s: "tm.events.type='NewBlock'", conditions: []Condition{{Tag: "tm.events.type", Op: OpEqual, Operand: "NewBlock"}}},
+		{s: "tx.gas > 7 AND tx.gas < 9", conditions: []Condition{{Tag: "tx.gas", Op: OpGreater, Operand: int64(7)}, {Tag: "tx.gas", Op: OpLess, Operand: int64(9)}}},
+		{s: "tx.time >= TIME 2013-05-03T14:45:00Z", conditions: []Condition{{Tag: "tx.time", Op: OpGreaterEqual, Operand: txTime}}},
+	}
+
+	for _, tc := range testCases {
+		q, err := New(tc.s)
+		require.Nil(t, err)
+
+		assert.Equal(t, tc.conditions, q.Conditions())
 	}
-	return pubsub.NewTagMap(tmap)
 }
diff --git a/event/query/reflect_tagged.go b/event/query/reflect_tagged.go
new file mode 100644
index 0000000000000000000000000000000000000000..b5cc6386452ce25029bd56f7e9130c99a881f057
--- /dev/null
+++ b/event/query/reflect_tagged.go
@@ -0,0 +1,99 @@
+package query
+
+import (
+	"fmt"
+	"reflect"
+)
+
+type ReflectTagged struct {
+	rv   reflect.Value
+	keys []string
+	ks   map[string]struct{}
+}
+
+var _ Tagged = &ReflectTagged{}
+
+func MustReflectTags(value interface{}, fieldNames ...string) *ReflectTagged {
+	rt, err := ReflectTags(value, fieldNames...)
+	if err != nil {
+		panic(err)
+	}
+	return rt
+}
+
+// ReflectTags provides a query.Tagged on a structs exported fields using query.StringFromValue to derive the string
+// values associated with each field. If passed explicit field names will only only provide those fields as tags,
+// otherwise all exported fields are provided.
+func ReflectTags(value interface{}, fieldNames ...string) (*ReflectTagged, error) {
+	rv := reflect.ValueOf(value)
+	if rv.IsNil() {
+		return &ReflectTagged{}, nil
+	}
+	if rv.Kind() != reflect.Ptr {
+		return nil, fmt.Errorf("ReflectStructTags needs a pointer to a struct but %v is not a pointer",
+			rv.Interface())
+	}
+	if rv.Elem().Kind() != reflect.Struct {
+		return nil, fmt.Errorf("ReflectStructTags needs a pointer to a struct but %v does not point to a struct",
+			rv.Interface())
+	}
+	ty := rv.Elem().Type()
+
+	numField := ty.NumField()
+	if len(fieldNames) > 0 {
+		if len(fieldNames) > numField {
+			return nil, fmt.Errorf("ReflectTags asked to tag %v fields but %v only has %v fields",
+				len(fieldNames), rv.Interface(), numField)
+		}
+		numField = len(fieldNames)
+	}
+	rt := &ReflectTagged{
+		rv:   rv,
+		ks:   make(map[string]struct{}, numField),
+		keys: make([]string, 0, numField),
+	}
+	if len(fieldNames) > 0 {
+		for _, fieldName := range fieldNames {
+			field, ok := ty.FieldByName(fieldName)
+			if !ok {
+				return nil, fmt.Errorf("ReflectTags asked to tag field named %s by no such field on %v",
+					fieldName, rv.Interface())
+			}
+			ok = rt.registerField(field)
+			if !ok {
+				return nil, fmt.Errorf("field %s of %v is not exported so cannot act as tag", fieldName,
+					rv.Interface())
+			}
+		}
+	} else {
+		for i := 0; i < numField; i++ {
+			rt.registerField(ty.Field(i))
+		}
+	}
+	return rt, nil
+}
+
+func (rt *ReflectTagged) registerField(field reflect.StructField) (ok bool) {
+	// Empty iff struct field is exported
+	if field.PkgPath == "" {
+		rt.keys = append(rt.keys, field.Name)
+		rt.ks[field.Name] = struct{}{}
+		return true
+	}
+	return false
+}
+
+func (rt *ReflectTagged) Keys() []string {
+	return rt.keys
+}
+
+func (rt *ReflectTagged) Get(key string) (value string, ok bool) {
+	if _, ok := rt.ks[key]; ok {
+		return StringFromValue(rt.rv.Elem().FieldByName(key).Interface()), true
+	}
+	return "", false
+}
+
+func (rt *ReflectTagged) Len() int {
+	return len(rt.keys)
+}
diff --git a/event/query/reflect_tagged_test.go b/event/query/reflect_tagged_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..1a2fe1aa774fd874ee925e68dbc6fd12b40ce926
--- /dev/null
+++ b/event/query/reflect_tagged_test.go
@@ -0,0 +1,97 @@
+package query
+
+import (
+	"testing"
+
+	"github.com/hyperledger/burrow/binary"
+	"github.com/hyperledger/burrow/crypto"
+	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/require"
+)
+
+type testTaggable struct {
+	Foo        string
+	Bar        string
+	Baz        binary.HexBytes
+	Address    crypto.Address
+	Indices    []int
+	unexported int
+}
+
+func TestReflectTagged_Keys(t *testing.T) {
+	rt, err := ReflectTags(&testTaggable{})
+	require.NoError(t, err)
+	assert.Equal(t, []string{"Foo", "Bar", "Baz", "Address", "Indices"}, rt.Keys())
+}
+
+func TestReflectTagged_Get(t *testing.T) {
+	tt := testTaggable{
+		Foo:     "Thumbs",
+		Bar:     "Numbed",
+		Baz:     []byte{255, 255, 255},
+		Address: crypto.Address{1, 2, 3},
+		Indices: []int{5, 7, 9},
+	}
+	rt, err := ReflectTags(&tt)
+	require.NoError(t, err)
+
+	value, ok := rt.Get("Foo")
+	assert.True(t, ok)
+	assert.Equal(t, tt.Foo, value)
+
+	value, ok = rt.Get("Bar")
+	assert.True(t, ok)
+	assert.Equal(t, tt.Bar, value)
+
+	value, ok = rt.Get("Baz")
+	assert.True(t, ok)
+	assert.Equal(t, "FFFFFF", value)
+
+	value, ok = rt.Get("Indices")
+	assert.True(t, ok)
+	assert.Equal(t, "5;7;9", value)
+
+	value, ok = rt.Get("Address")
+	assert.True(t, ok)
+	assert.Equal(t, "0102030000000000000000000000000000000000", value)
+
+	// Make sure we see updates through pointer
+	tt.Foo = "Plums"
+	value, ok = rt.Get("Foo")
+	assert.True(t, ok)
+	assert.Equal(t, tt.Foo, value)
+}
+
+func TestReflectTagged_Len(t *testing.T) {
+	rt, err := ReflectTags(&testTaggable{})
+	require.NoError(t, err)
+	assert.Equal(t, 5, rt.Len())
+}
+
+func TestExplicitFields(t *testing.T) {
+	tt := testTaggable{
+		Foo:     "Thumbs",
+		Bar:     "Numbed",
+		Baz:     []byte{255, 255, 255},
+		Address: crypto.Address{1, 2, 3},
+	}
+	rt, err := ReflectTags(&tt, "Foo", "Address")
+	require.NoError(t, err)
+
+	value, ok := rt.Get("Foo")
+	assert.True(t, ok)
+	assert.Equal(t, tt.Foo, value)
+
+	value, ok = rt.Get("Address")
+	assert.True(t, ok)
+	assert.Equal(t, "0102030000000000000000000000000000000000", value)
+
+	_, ok = rt.Get("Bar")
+	assert.False(t, ok)
+
+	_, ok = rt.Get("Barsss")
+	assert.False(t, ok)
+
+	_, err = ReflectTags(&tt, "Foo", "Address", "Balloons")
+	require.Error(t, err)
+}
diff --git a/event/query/tags.go b/event/query/tags.go
new file mode 100644
index 0000000000000000000000000000000000000000..d177b1a09e43ca16a0545bca85972b111c878999
--- /dev/null
+++ b/event/query/tags.go
@@ -0,0 +1,126 @@
+package query
+
+import (
+	"fmt"
+	"strings"
+)
+
+type Tagged interface {
+	Keys() []string
+	Get(key string) (value string, ok bool)
+	// Len returns the number of tags.
+	Len() int
+}
+
+type TagMap map[string]interface{}
+
+func MapFromTagged(tagged Tagged) map[string]interface{} {
+	tags := make(map[string]interface{})
+	for _, k := range tagged.Keys() {
+		v, ok := tagged.Get(k)
+		if ok {
+			tags[k] = v
+		}
+	}
+	return tags
+}
+
+func (ts TagMap) Get(key string) (value string, ok bool) {
+	var vint interface{}
+	vint, ok = ts[key]
+	if !ok {
+		return
+	}
+	switch v := vint.(type) {
+	case string:
+		value = v
+	case fmt.Stringer:
+		value = v.String()
+	default:
+		value = fmt.Sprintf("%v", v)
+	}
+	return
+}
+
+func (ts TagMap) Len() int {
+	return len(ts)
+}
+
+func (ts TagMap) Map() map[string]interface{} {
+	return ts
+}
+
+func (ts TagMap) Keys() []string {
+	keys := make([]string, 0, len(ts))
+	for k := range ts {
+		keys = append(keys, k)
+	}
+	return keys
+}
+
+type CombinedTags struct {
+	keys   []string
+	ks     map[string][]Tagged
+	concat bool
+}
+
+func NewCombinedTags() *CombinedTags {
+	return &CombinedTags{
+		ks: make(map[string][]Tagged),
+	}
+}
+
+func MergeTags(tags ...Tagged) *CombinedTags {
+	ct := NewCombinedTags()
+	ct.AddTags(false, tags...)
+	return ct
+}
+
+func ConcatTags(tags ...Tagged) *CombinedTags {
+	ct := NewCombinedTags()
+	ct.AddTags(true, tags...)
+	return ct
+}
+
+// Adds each of tagsList to CombinedTags - choosing whether values for the same key should
+// be concatenated or whether the first should value should stick
+func (ct *CombinedTags) AddTags(concat bool, tagsList ...Tagged) {
+	for _, t := range tagsList {
+		for _, k := range t.Keys() {
+			if len(ct.ks[k]) == 0 {
+				ct.keys = append(ct.keys, k)
+				// Store reference to key-holder amongst Taggeds
+				ct.ks[k] = append(ct.ks[k], t)
+			} else if concat {
+				// Store additional tag reference only if concat, otherwise first key-holder wins
+				ct.ks[k] = append(ct.ks[k], t)
+			}
+		}
+	}
+}
+
+func (ct *CombinedTags) Get(key string) (string, bool) {
+	ts := ct.ks[key]
+	if len(ts) == 0 {
+		return "", false
+	}
+	values := make([]string, 0, len(ts))
+	for _, t := range ts {
+		value, ok := t.Get(key)
+		if ok {
+			values = append(values, value)
+		}
+	}
+	if len(values) == 0 {
+		return "", false
+	}
+	return strings.Join(values, MultipleValueTagSeparator), true
+}
+
+func (ct *CombinedTags) Len() (length int) {
+	return len(ct.keys)
+}
+
+func (ct *CombinedTags) Keys() []string {
+	return ct.keys
+}
diff --git a/event/tags.go b/event/tags.go
deleted file mode 100644
index 759d035d734b6ee4987cd1952c3b63da47373f39..0000000000000000000000000000000000000000
--- a/event/tags.go
+++ /dev/null
@@ -1,87 +0,0 @@
-package event
-
-import (
-	"fmt"
-
-	"github.com/tendermint/tendermint/libs/pubsub"
-)
-
-type Tags interface {
-	pubsub.TagMap
-	Keys() []string
-}
-
-type TagMap map[string]interface{}
-
-func (ts TagMap) Get(key string) (value string, ok bool) {
-	var vint interface{}
-	vint, ok = ts[key]
-	if !ok {
-		return
-	}
-	switch v := vint.(type) {
-	case string:
-		value = v
-	case fmt.Stringer:
-		value = v.String()
-	default:
-		value = fmt.Sprintf("%v", v)
-	}
-	return
-}
-
-func (ts TagMap) Len() int {
-	return len(ts)
-}
-
-func (ts TagMap) Map() map[string]interface{} {
-	return ts
-}
-
-func (ts TagMap) Keys() []string {
-	keys := make([]string, 0, len(ts))
-	for k := range ts {
-		keys = append(keys, k)
-	}
-	return keys
-}
-
-type CombinedTags []Tags
-
-func (ct CombinedTags) Get(key string) (value string, ok bool) {
-	for _, t := range ct {
-		value, ok = t.Get(key)
-		if ok {
-			return
-		}
-	}
-	return
-}
-
-func (ct CombinedTags) Len() (length int) {
-	for _, t := range ct {
-		length += t.Len()
-	}
-	return length
-}
-
-func (ct CombinedTags) Map() map[string]interface{} {
-	tags := make(map[string]interface{})
-	for _, t := range ct {
-		for _, k := range t.Keys() {
-			v, ok := t.Get(k)
-			if ok {
-				tags[k] = v
-			}
-		}
-	}
-	return tags
-}
-
-func (ct CombinedTags) Keys() []string {
-	var keys []string
-	for _, t := range ct {
-		keys = append(keys, t.Keys()...)
-	}
-	return keys
-}
diff --git a/execution/accounts.go b/execution/accounts.go
index 8125ef0a10d9546c8165b9c98d65b04881e7f717..396f43302fd4fbc60f9fb57b1dfee0d5f064adb1 100644
--- a/execution/accounts.go
+++ b/execution/accounts.go
@@ -1,11 +1,10 @@
 package execution
 
 import (
-	"fmt"
 	"sync"
 
-	acm "github.com/hyperledger/burrow/account"
-	"github.com/hyperledger/burrow/account/state"
+	"github.com/hyperledger/burrow/acm"
+	"github.com/hyperledger/burrow/acm/state"
 	"github.com/hyperledger/burrow/crypto"
 	"github.com/hyperledger/burrow/keys"
 	burrow_sync "github.com/hyperledger/burrow/sync"
@@ -25,6 +24,7 @@ type SigningAccount struct {
 }
 
 type SequentialSigningAccount struct {
+	Address       crypto.Address
 	accountLocker sync.Locker
 	getter        func() (*SigningAccount, error)
 }
@@ -37,7 +37,11 @@ func NewAccounts(reader state.Reader, keyClient keys.KeyClient, mutexCount int)
 		keyClient: keyClient,
 	}
 }
-func (accs *Accounts) SigningAccount(address crypto.Address, signer crypto.Signer) (*SigningAccount, error) {
+func (accs *Accounts) SigningAccount(address crypto.Address) (*SigningAccount, error) {
+	signer, err := keys.AddressableSigner(accs.keyClient, address)
+	if err != nil {
+		return nil, err
+	}
 	account, err := state.GetMutableAccount(accs, address)
 	if err != nil {
 		return nil, err
@@ -60,50 +64,15 @@ func (accs *Accounts) SigningAccount(address crypto.Address, signer crypto.Signe
 }
 
 func (accs *Accounts) SequentialSigningAccount(address crypto.Address) (*SequentialSigningAccount, error) {
-	signer, err := keys.AddressableSigner(accs.keyClient, address)
-	if err != nil {
-		return nil, err
-	}
 	return &SequentialSigningAccount{
+		Address:       address,
 		accountLocker: accs.Mutex(address.Bytes()),
 		getter: func() (*SigningAccount, error) {
-			return accs.SigningAccount(address, signer)
-		},
-	}, nil
-}
-
-func (accs *Accounts) SequentialSigningAccountFromPrivateKey(privateKeyBytes []byte) (*SequentialSigningAccount, error) {
-	if len(privateKeyBytes) != 64 {
-		return nil, fmt.Errorf("private key is not of the right length: %d\n", len(privateKeyBytes))
-	}
-	privateAccount, err := acm.GeneratePrivateAccountFromPrivateKeyBytes(privateKeyBytes)
-	if err != nil {
-		return nil, err
-	}
-	return &SequentialSigningAccount{
-		accountLocker: accs.Mutex(privateAccount.Address().Bytes()),
-		getter: func() (*SigningAccount, error) {
-			return accs.SigningAccount(privateAccount.Address(), privateAccount)
+			return accs.SigningAccount(address)
 		},
 	}, nil
 }
 
-// Gets signing account from onr of private key or address - failing if both are provided
-func (accs *Accounts) GetSequentialSigningAccount(address, privateKey []byte) (*SequentialSigningAccount, error) {
-	if len(address) > 0 {
-		if len(privateKey) > 0 {
-			return nil, fmt.Errorf("address and private key provided but only one or the other should be given")
-		}
-		address, err := crypto.AddressFromBytes(address)
-		if err != nil {
-			return nil, err
-		}
-		return accs.SequentialSigningAccount(address)
-	}
-
-	return accs.SequentialSigningAccountFromPrivateKey(privateKey)
-}
-
 type UnlockFunc func()
 
 func (ssa *SequentialSigningAccount) Lock() (*SigningAccount, UnlockFunc, error) {
diff --git a/execution/config.go b/execution/config.go
index f90b6a02c529fcd5aa67fee1abf1011f725673d2..1f61d068f394dd1c7b8514b49b64fa72a099cc01 100644
--- a/execution/config.go
+++ b/execution/config.go
@@ -21,6 +21,14 @@ func DefaultExecutionConfig() *ExecutionConfig {
 	return &ExecutionConfig{}
 }
 
+type ExecutionOption func(*executor)
+
+func VMOptions(vmOptions ...func(*evm.VM)) func(*executor) {
+	return func(exe *executor) {
+		exe.vmOptions = vmOptions
+	}
+}
+
 func (ec *ExecutionConfig) ExecutionOptions() ([]ExecutionOption, error) {
 	var exeOptions []ExecutionOption
 	var vmOptions []func(*evm.VM)
diff --git a/execution/errors/errors.go b/execution/errors/errors.go
index ba15497f0212b37909f772f9b2f321a89ef08567..8e3bd2cc144312712983a4ddb2418dea055daace 100644
--- a/execution/errors/errors.go
+++ b/execution/errors/errors.go
@@ -1,9 +1,6 @@
 package errors
 
-import (
-	"encoding/json"
-	"fmt"
-)
+import "fmt"
 
 type CodedError interface {
 	error
@@ -33,6 +30,8 @@ const (
 	ErrorCodePermissionDenied
 	ErrorCodeNativeFunction
 	ErrorCodeEventPublish
+	ErrorCodeInvalidString
+	ErrorCodeEventMapping
 )
 
 func (c Code) ErrorCode() Code {
@@ -77,6 +76,10 @@ func (c Code) Error() string {
 		return "Native function error"
 	case ErrorCodeEventPublish:
 		return "Event publish error"
+	case ErrorCodeInvalidString:
+		return "Invalid string"
+	case ErrorCodeEventMapping:
+		return "Event mapping error"
 	case ErrorCodeGeneric:
 		return "Generic error"
 	default:
@@ -89,15 +92,13 @@ func NewCodedError(errorCode Code, exception string) *Exception {
 		return nil
 	}
 	return &Exception{
-		Code: &ErrorCode{
-			Code: uint32(errorCode),
-		},
+		Code:      errorCode,
 		Exception: exception,
 	}
 }
 
 // Wraps any error as a Exception
-func AsCodedError(err error) *Exception {
+func AsException(err error) *Exception {
 	if err == nil {
 		return nil
 	}
@@ -115,11 +116,11 @@ func Wrap(err CodedError, message string) *Exception {
 	return NewCodedError(err.ErrorCode(), message+": "+err.Error())
 }
 
-func Errorf(format string, a ...interface{}) CodedError {
+func Errorf(format string, a ...interface{}) *Exception {
 	return ErrorCodef(ErrorCodeGeneric, format, a...)
 }
 
-func ErrorCodef(errorCode Code, format string, a ...interface{}) CodedError {
+func ErrorCodef(errorCode Code, format string, a ...interface{}) *Exception {
 	return NewCodedError(errorCode, fmt.Sprintf(format, a...))
 }
 
@@ -132,26 +133,16 @@ func (e *Exception) AsError() error {
 }
 
 func (e *Exception) ErrorCode() Code {
-	return Code(e.GetCode().Code)
+	return e.Code
+}
+
+func (e *Exception) String() string {
+	return e.Error()
 }
 
 func (e *Exception) Error() string {
 	if e == nil {
 		return ""
 	}
-	return fmt.Sprintf("Error %v: %s", e.Code.Code, e.Exception)
-}
-
-func NewErrorCode(code Code) *ErrorCode {
-	return &ErrorCode{
-		Code: uint32(code),
-	}
-}
-
-func (e ErrorCode) MarshalJSON() ([]byte, error) {
-	return json.Marshal(e.Code)
-}
-
-func (e *ErrorCode) UnmarshalJSON(bs []byte) error {
-	return json.Unmarshal(bs, &(e.Code))
+	return fmt.Sprintf("Error %v: %s", e.Code, e.Exception)
 }
diff --git a/execution/errors/errors.pb.go b/execution/errors/errors.pb.go
index 14d297a6c41cda1f905353a1f056f72b5fab3895..859a4c2044ef022da6a0ab341ab399fb8ef46e9f 100644
--- a/execution/errors/errors.pb.go
+++ b/execution/errors/errors.pb.go
@@ -1,14 +1,28 @@
-// Code generated by protoc-gen-go. DO NOT EDIT.
-// source: github.com/hyperledger/burrow/execution/errors/errors.proto
+// Code generated by protoc-gen-gogo. DO NOT EDIT.
+// source: errors.proto
 
+/*
+	Package errors is a generated protocol buffer package.
+
+	It is generated from these files:
+		errors.proto
+
+	It has these top-level messages:
+		Exception
+*/
 package errors
 
-import proto "github.com/golang/protobuf/proto"
+import proto "github.com/gogo/protobuf/proto"
+import golang_proto "github.com/golang/protobuf/proto"
 import fmt "fmt"
 import math "math"
+import _ "github.com/gogo/protobuf/gogoproto"
+
+import io "io"
 
 // Reference imports to suppress errors if they are not otherwise used.
 var _ = proto.Marshal
+var _ = golang_proto.Marshal
 var _ = fmt.Errorf
 var _ = math.Inf
 
@@ -16,46 +30,22 @@ var _ = math.Inf
 // is compatible with the proto package it is being compiled against.
 // A compilation error at this line likely means your copy of the
 // proto package needs to be updated.
-const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
+const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package
 
 type Exception struct {
-	Code                 *ErrorCode `protobuf:"bytes,1,opt,name=Code,proto3" json:"Code,omitempty"`
-	Exception            string     `protobuf:"bytes,2,opt,name=Exception,proto3" json:"Exception,omitempty"`
-	BS                   []byte     `protobuf:"bytes,3,opt,name=BS,proto3" json:"BS,omitempty"`
-	XXX_NoUnkeyedLiteral struct{}   `json:"-"`
-	XXX_unrecognized     []byte     `json:"-"`
-	XXX_sizecache        int32      `json:"-"`
-}
-
-func (m *Exception) Reset()         { *m = Exception{} }
-func (m *Exception) String() string { return proto.CompactTextString(m) }
-func (*Exception) ProtoMessage()    {}
-func (*Exception) Descriptor() ([]byte, []int) {
-	return fileDescriptor_errors_e7e9443965b28d5d, []int{0}
-}
-func (m *Exception) XXX_Unmarshal(b []byte) error {
-	return xxx_messageInfo_Exception.Unmarshal(m, b)
-}
-func (m *Exception) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
-	return xxx_messageInfo_Exception.Marshal(b, m, deterministic)
-}
-func (dst *Exception) XXX_Merge(src proto.Message) {
-	xxx_messageInfo_Exception.Merge(dst, src)
-}
-func (m *Exception) XXX_Size() int {
-	return xxx_messageInfo_Exception.Size(m)
-}
-func (m *Exception) XXX_DiscardUnknown() {
-	xxx_messageInfo_Exception.DiscardUnknown(m)
+	Code      Code   `protobuf:"varint,1,opt,name=Code,proto3,casttype=Code" json:"Code,omitempty"`
+	Exception string `protobuf:"bytes,2,opt,name=Exception,proto3" json:"Exception,omitempty"`
 }
 
-var xxx_messageInfo_Exception proto.InternalMessageInfo
+func (m *Exception) Reset()                    { *m = Exception{} }
+func (*Exception) ProtoMessage()               {}
+func (*Exception) Descriptor() ([]byte, []int) { return fileDescriptorErrors, []int{0} }
 
-func (m *Exception) GetCode() *ErrorCode {
+func (m *Exception) GetCode() Code {
 	if m != nil {
 		return m.Code
 	}
-	return nil
+	return 0
 }
 
 func (m *Exception) GetException() string {
@@ -65,71 +55,295 @@ func (m *Exception) GetException() string {
 	return ""
 }
 
-func (m *Exception) GetBS() []byte {
-	if m != nil {
-		return m.BS
+func (*Exception) XXX_MessageName() string {
+	return "errors.Exception"
+}
+func init() {
+	proto.RegisterType((*Exception)(nil), "errors.Exception")
+	golang_proto.RegisterType((*Exception)(nil), "errors.Exception")
+}
+func (m *Exception) Marshal() (dAtA []byte, err error) {
+	size := m.Size()
+	dAtA = make([]byte, size)
+	n, err := m.MarshalTo(dAtA)
+	if err != nil {
+		return nil, err
 	}
-	return nil
+	return dAtA[:n], nil
 }
 
-type ErrorCode struct {
-	Code                 uint32   `protobuf:"varint,1,opt,name=Code,proto3" json:"Code,omitempty"`
-	XXX_NoUnkeyedLiteral struct{} `json:"-"`
-	XXX_unrecognized     []byte   `json:"-"`
-	XXX_sizecache        int32    `json:"-"`
+func (m *Exception) MarshalTo(dAtA []byte) (int, error) {
+	var i int
+	_ = i
+	var l int
+	_ = l
+	if m.Code != 0 {
+		dAtA[i] = 0x8
+		i++
+		i = encodeVarintErrors(dAtA, i, uint64(m.Code))
+	}
+	if len(m.Exception) > 0 {
+		dAtA[i] = 0x12
+		i++
+		i = encodeVarintErrors(dAtA, i, uint64(len(m.Exception)))
+		i += copy(dAtA[i:], m.Exception)
+	}
+	return i, nil
 }
 
-func (m *ErrorCode) Reset()         { *m = ErrorCode{} }
-func (m *ErrorCode) String() string { return proto.CompactTextString(m) }
-func (*ErrorCode) ProtoMessage()    {}
-func (*ErrorCode) Descriptor() ([]byte, []int) {
-	return fileDescriptor_errors_e7e9443965b28d5d, []int{1}
-}
-func (m *ErrorCode) XXX_Unmarshal(b []byte) error {
-	return xxx_messageInfo_ErrorCode.Unmarshal(m, b)
-}
-func (m *ErrorCode) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
-	return xxx_messageInfo_ErrorCode.Marshal(b, m, deterministic)
+func encodeVarintErrors(dAtA []byte, offset int, v uint64) int {
+	for v >= 1<<7 {
+		dAtA[offset] = uint8(v&0x7f | 0x80)
+		v >>= 7
+		offset++
+	}
+	dAtA[offset] = uint8(v)
+	return offset + 1
 }
-func (dst *ErrorCode) XXX_Merge(src proto.Message) {
-	xxx_messageInfo_ErrorCode.Merge(dst, src)
+func (m *Exception) Size() (n int) {
+	var l int
+	_ = l
+	if m.Code != 0 {
+		n += 1 + sovErrors(uint64(m.Code))
+	}
+	l = len(m.Exception)
+	if l > 0 {
+		n += 1 + l + sovErrors(uint64(l))
+	}
+	return n
 }
-func (m *ErrorCode) XXX_Size() int {
-	return xxx_messageInfo_ErrorCode.Size(m)
+
+func sovErrors(x uint64) (n int) {
+	for {
+		n++
+		x >>= 7
+		if x == 0 {
+			break
+		}
+	}
+	return n
 }
-func (m *ErrorCode) XXX_DiscardUnknown() {
-	xxx_messageInfo_ErrorCode.DiscardUnknown(m)
+func sozErrors(x uint64) (n int) {
+	return sovErrors(uint64((x << 1) ^ uint64((int64(x) >> 63))))
 }
+func (m *Exception) Unmarshal(dAtA []byte) error {
+	l := len(dAtA)
+	iNdEx := 0
+	for iNdEx < l {
+		preIndex := iNdEx
+		var wire uint64
+		for shift := uint(0); ; shift += 7 {
+			if shift >= 64 {
+				return ErrIntOverflowErrors
+			}
+			if iNdEx >= l {
+				return io.ErrUnexpectedEOF
+			}
+			b := dAtA[iNdEx]
+			iNdEx++
+			wire |= (uint64(b) & 0x7F) << shift
+			if b < 0x80 {
+				break
+			}
+		}
+		fieldNum := int32(wire >> 3)
+		wireType := int(wire & 0x7)
+		if wireType == 4 {
+			return fmt.Errorf("proto: Exception: wiretype end group for non-group")
+		}
+		if fieldNum <= 0 {
+			return fmt.Errorf("proto: Exception: illegal tag %d (wire type %d)", fieldNum, wire)
+		}
+		switch fieldNum {
+		case 1:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Code", wireType)
+			}
+			m.Code = 0
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowErrors
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				m.Code |= (Code(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+		case 2:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Exception", wireType)
+			}
+			var stringLen uint64
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowErrors
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				stringLen |= (uint64(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			intStringLen := int(stringLen)
+			if intStringLen < 0 {
+				return ErrInvalidLengthErrors
+			}
+			postIndex := iNdEx + intStringLen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			m.Exception = string(dAtA[iNdEx:postIndex])
+			iNdEx = postIndex
+		default:
+			iNdEx = preIndex
+			skippy, err := skipErrors(dAtA[iNdEx:])
+			if err != nil {
+				return err
+			}
+			if skippy < 0 {
+				return ErrInvalidLengthErrors
+			}
+			if (iNdEx + skippy) > l {
+				return io.ErrUnexpectedEOF
+			}
+			iNdEx += skippy
+		}
+	}
 
-var xxx_messageInfo_ErrorCode proto.InternalMessageInfo
-
-func (m *ErrorCode) GetCode() uint32 {
-	if m != nil {
-		return m.Code
+	if iNdEx > l {
+		return io.ErrUnexpectedEOF
 	}
-	return 0
+	return nil
 }
-
-func init() {
-	proto.RegisterType((*Exception)(nil), "errors.Exception")
-	proto.RegisterType((*ErrorCode)(nil), "errors.ErrorCode")
+func skipErrors(dAtA []byte) (n int, err error) {
+	l := len(dAtA)
+	iNdEx := 0
+	for iNdEx < l {
+		var wire uint64
+		for shift := uint(0); ; shift += 7 {
+			if shift >= 64 {
+				return 0, ErrIntOverflowErrors
+			}
+			if iNdEx >= l {
+				return 0, io.ErrUnexpectedEOF
+			}
+			b := dAtA[iNdEx]
+			iNdEx++
+			wire |= (uint64(b) & 0x7F) << shift
+			if b < 0x80 {
+				break
+			}
+		}
+		wireType := int(wire & 0x7)
+		switch wireType {
+		case 0:
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return 0, ErrIntOverflowErrors
+				}
+				if iNdEx >= l {
+					return 0, io.ErrUnexpectedEOF
+				}
+				iNdEx++
+				if dAtA[iNdEx-1] < 0x80 {
+					break
+				}
+			}
+			return iNdEx, nil
+		case 1:
+			iNdEx += 8
+			return iNdEx, nil
+		case 2:
+			var length int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return 0, ErrIntOverflowErrors
+				}
+				if iNdEx >= l {
+					return 0, io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				length |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			iNdEx += length
+			if length < 0 {
+				return 0, ErrInvalidLengthErrors
+			}
+			return iNdEx, nil
+		case 3:
+			for {
+				var innerWire uint64
+				var start int = iNdEx
+				for shift := uint(0); ; shift += 7 {
+					if shift >= 64 {
+						return 0, ErrIntOverflowErrors
+					}
+					if iNdEx >= l {
+						return 0, io.ErrUnexpectedEOF
+					}
+					b := dAtA[iNdEx]
+					iNdEx++
+					innerWire |= (uint64(b) & 0x7F) << shift
+					if b < 0x80 {
+						break
+					}
+				}
+				innerWireType := int(innerWire & 0x7)
+				if innerWireType == 4 {
+					break
+				}
+				next, err := skipErrors(dAtA[start:])
+				if err != nil {
+					return 0, err
+				}
+				iNdEx = start + next
+			}
+			return iNdEx, nil
+		case 4:
+			return iNdEx, nil
+		case 5:
+			iNdEx += 4
+			return iNdEx, nil
+		default:
+			return 0, fmt.Errorf("proto: illegal wireType %d", wireType)
+		}
+	}
+	panic("unreachable")
 }
 
-func init() {
-	proto.RegisterFile("github.com/hyperledger/burrow/execution/errors/errors.proto", fileDescriptor_errors_e7e9443965b28d5d)
-}
+var (
+	ErrInvalidLengthErrors = fmt.Errorf("proto: negative length found during unmarshaling")
+	ErrIntOverflowErrors   = fmt.Errorf("proto: integer overflow")
+)
+
+func init() { proto.RegisterFile("errors.proto", fileDescriptorErrors) }
+func init() { golang_proto.RegisterFile("errors.proto", fileDescriptorErrors) }
 
-var fileDescriptor_errors_e7e9443965b28d5d = []byte{
-	// 168 bytes of a gzipped FileDescriptorProto
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xb2, 0x4e, 0xcf, 0x2c, 0xc9,
-	0x28, 0x4d, 0xd2, 0x4b, 0xce, 0xcf, 0xd5, 0xcf, 0xa8, 0x2c, 0x48, 0x2d, 0xca, 0x49, 0x4d, 0x49,
-	0x4f, 0x2d, 0xd2, 0x4f, 0x2a, 0x2d, 0x2a, 0xca, 0x2f, 0xd7, 0x4f, 0xad, 0x48, 0x4d, 0x2e, 0x2d,
-	0xc9, 0xcc, 0xcf, 0xd3, 0x4f, 0x2d, 0x2a, 0xca, 0x2f, 0x2a, 0x86, 0x52, 0x7a, 0x05, 0x45, 0xf9,
-	0x25, 0xf9, 0x42, 0x6c, 0x10, 0x9e, 0x52, 0x02, 0x17, 0xa7, 0x6b, 0x45, 0x72, 0x6a, 0x01, 0x48,
-	0xa1, 0x90, 0x2a, 0x17, 0x8b, 0x73, 0x7e, 0x4a, 0xaa, 0x04, 0xa3, 0x02, 0xa3, 0x06, 0xb7, 0x91,
-	0xa0, 0x1e, 0x54, 0x87, 0x2b, 0x88, 0x02, 0x49, 0x04, 0x81, 0xa5, 0x85, 0x64, 0x90, 0xf4, 0x48,
-	0x30, 0x29, 0x30, 0x6a, 0x70, 0x06, 0x21, 0x19, 0xc2, 0xc7, 0xc5, 0xe4, 0x14, 0x2c, 0xc1, 0xac,
-	0xc0, 0xa8, 0xc1, 0x13, 0xc4, 0xe4, 0x14, 0xac, 0x24, 0xcf, 0xc5, 0x09, 0x37, 0x40, 0x48, 0x08,
-	0xc9, 0x06, 0x5e, 0x88, 0x71, 0x49, 0x6c, 0x60, 0x17, 0x19, 0x03, 0x02, 0x00, 0x00, 0xff, 0xff,
-	0x20, 0x37, 0xb1, 0xd9, 0xd0, 0x00, 0x00, 0x00,
+var fileDescriptorErrors = []byte{
+	// 190 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0x49, 0x2d, 0x2a, 0xca,
+	0x2f, 0x2a, 0xd6, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, 0x83, 0xf0, 0xa4, 0x74, 0xd3, 0x33,
+	0x4b, 0x32, 0x4a, 0x93, 0xf4, 0x92, 0xf3, 0x73, 0xf5, 0xd3, 0xf3, 0xd3, 0xf3, 0xf5, 0xc1, 0xd2,
+	0x49, 0xa5, 0x69, 0x60, 0x1e, 0x98, 0x03, 0x66, 0x41, 0xb4, 0x29, 0xf9, 0x72, 0x71, 0xba, 0x56,
+	0x24, 0xa7, 0x16, 0x94, 0x64, 0xe6, 0xe7, 0x09, 0xc9, 0x70, 0xb1, 0x38, 0xe7, 0xa7, 0xa4, 0x4a,
+	0x30, 0x2a, 0x30, 0x6a, 0xf0, 0x3a, 0x71, 0xfc, 0xba, 0x27, 0x0f, 0xe6, 0x07, 0x81, 0x49, 0x21,
+	0x19, 0x24, 0xa5, 0x12, 0x4c, 0x0a, 0x8c, 0x1a, 0x9c, 0x41, 0x08, 0x01, 0x2b, 0x96, 0x19, 0x0b,
+	0xe4, 0x19, 0x9c, 0x5c, 0x4e, 0x3c, 0x92, 0x63, 0xbc, 0xf0, 0x48, 0x8e, 0xf1, 0xc1, 0x23, 0x39,
+	0xc6, 0x03, 0x8f, 0xe5, 0x18, 0x4f, 0x3c, 0x96, 0x63, 0x8c, 0xd2, 0x43, 0x72, 0x53, 0x46, 0x65,
+	0x41, 0x6a, 0x51, 0x4e, 0x6a, 0x4a, 0x7a, 0x6a, 0x91, 0x7e, 0x52, 0x69, 0x51, 0x51, 0x7e, 0xb9,
+	0x7e, 0x6a, 0x45, 0x6a, 0x72, 0x29, 0xc8, 0x10, 0x7d, 0x88, 0x1f, 0x92, 0xd8, 0xc0, 0x6e, 0x33,
+	0x06, 0x04, 0x00, 0x00, 0xff, 0xff, 0x33, 0x9a, 0x19, 0x05, 0xe2, 0x00, 0x00, 0x00,
 }
diff --git a/execution/errors/errors.proto b/execution/errors/errors.proto
deleted file mode 100644
index 2620fdd403e97fd1d7037ab49be92bfbb4e94bac..0000000000000000000000000000000000000000
--- a/execution/errors/errors.proto
+++ /dev/null
@@ -1,13 +0,0 @@
-syntax = "proto3";
-
-package errors;
-
-message Exception {
-    ErrorCode Code = 1;
-    string Exception = 2;
-    bytes BS = 3;
-}
-
-message ErrorCode {
-    uint32 Code = 1;
-}
diff --git a/execution/errors/errors_test.go b/execution/errors/errors_test.go
index 3b85c4adbd71f64b1c1fcd82460dc3e428c41ed9..2a4a0a37bfda11113edfeb08417a37cf497c0e25 100644
--- a/execution/errors/errors_test.go
+++ b/execution/errors/errors_test.go
@@ -4,39 +4,18 @@ import (
 	"encoding/json"
 	"testing"
 
-	"fmt"
-
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
-	"github.com/tendermint/abci/types"
 )
 
 func TestErrorCode_MarshalJSON(t *testing.T) {
-	ec := NewErrorCode(ErrorCodeDataStackOverflow)
+	ec := NewCodedError(ErrorCodeDataStackOverflow, "arrg")
 	bs, err := json.Marshal(ec)
 	require.NoError(t, err)
 
-	ecOut := new(ErrorCode)
+	ecOut := new(Exception)
 	err = json.Unmarshal(bs, ecOut)
 	require.NoError(t, err)
 
 	assert.Equal(t, ec, ecOut)
 }
-
-func TestException_MarshalJSON(t *testing.T) {
-	ex := NewCodedError(ErrorCodeExecutionReverted, "Oh noes we reverted")
-	ex.BS = []byte{2, 3, 4, 5}
-	bs, err := json.Marshal(ex)
-	require.NoError(t, err)
-	fmt.Println(string(bs))
-	exOut := new(Exception)
-	err = json.Unmarshal(bs, exOut)
-	require.NoError(t, err)
-
-	bb := types.RequestBeginBlock{
-		Hash: []byte{2, 3, 4},
-	}
-	bs, err = json.Marshal(bb)
-	require.NoError(t, err)
-	fmt.Println(string(bs))
-}
diff --git a/execution/errors/vm.go b/execution/errors/vm.go
index f2d40983fd03377db7064a8716c3c2cc1bff0c6c..7e97d37504205e5d509f7f4262932f3a48c98046 100644
--- a/execution/errors/vm.go
+++ b/execution/errors/vm.go
@@ -5,11 +5,11 @@ import (
 	"fmt"
 
 	"github.com/hyperledger/burrow/crypto"
-	"github.com/hyperledger/burrow/permission/types"
+	"github.com/hyperledger/burrow/permission"
 )
 
 type PermissionDenied struct {
-	Perm types.PermFlag
+	Perm permission.PermFlag
 }
 
 func (err PermissionDenied) ErrorCode() Code {
diff --git a/execution/events/call.go b/execution/events/call.go
deleted file mode 100644
index 23e047248756c6f4a8362af08b5dbf8bce36cb0b..0000000000000000000000000000000000000000
--- a/execution/events/call.go
+++ /dev/null
@@ -1,149 +0,0 @@
-// Copyright 2017 Monax Industries Limited
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//    http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package events
-
-import (
-	"context"
-	"fmt"
-
-	"github.com/hyperledger/burrow/binary"
-	"github.com/hyperledger/burrow/crypto"
-	"github.com/hyperledger/burrow/event"
-	"github.com/hyperledger/burrow/event/query"
-	"github.com/hyperledger/burrow/execution/errors"
-	"github.com/hyperledger/burrow/txs"
-	hex "github.com/tmthrgd/go-hex"
-)
-
-// Functions to generate eventId strings
-
-func EventStringAccountCall(addr crypto.Address) string { return fmt.Sprintf("Acc/%s/Call", addr) }
-
-//----------------------------------------
-
-// EventDataCall fires when we call a contract, and when a contract calls another contract
-type EventDataCall struct {
-	CallData   *CallData
-	Origin     crypto.Address
-	StackDepth uint64
-	Return     binary.HexBytes
-	Exception  *errors.Exception
-}
-
-type CallData struct {
-	Caller crypto.Address
-	Callee crypto.Address
-	Data   binary.HexBytes
-	Value  uint64
-	Gas    uint64
-}
-
-// Publish/Subscribe
-func PublishAccountCall(publisher event.Publisher, tx *txs.Tx, height uint64, call *EventDataCall) error {
-	eventID := EventStringAccountCall(call.CallData.Callee)
-	ev := &Event{
-		Header: &Header{
-			TxType:    tx.Type(),
-			TxHash:    tx.Hash(),
-			EventType: TypeCall,
-			EventID:   eventID,
-			Height:    height,
-		},
-		Call: call,
-	}
-	return publisher.Publish(context.Background(), ev, ev.Tags())
-}
-
-// Subscribe to account call event - if TxHash is provided listens for a specifc Tx otherwise captures all, if
-// stackDepth is greater than or equal to 0 captures calls at a specific stack depth (useful for capturing the return
-// of the root call over recursive calls
-func SubscribeAccountCall(ctx context.Context, subscribable event.Subscribable, subscriber string, address crypto.Address,
-	txHash []byte, stackDepth int, ch chan<- *EventDataCall) error {
-
-	query := event.QueryForEventID(EventStringAccountCall(address))
-
-	if len(txHash) > 0 {
-		query = query.AndEquals(event.TxHashKey, hex.EncodeUpperToString(txHash))
-	}
-
-	if stackDepth >= 0 {
-		query = query.AndEquals(event.StackDepthKey, stackDepth)
-	}
-
-	return event.SubscribeCallback(ctx, subscribable, subscriber, query, func(message interface{}) (stop bool) {
-		ev, ok := message.(*Event)
-		if ok && ev.Call != nil {
-			ch <- ev.Call
-		}
-		return
-	})
-}
-
-// Tags
-
-var callTagKeys = []string{
-	event.CalleeKey,
-	event.CallerKey,
-	event.ValueKey,
-	event.GasKey,
-	event.StackDepthKey,
-	event.OriginKey,
-	event.ExceptionKey,
-}
-
-// Implements Tags for events
-func (call *EventDataCall) Get(key string) (string, bool) {
-	var value interface{}
-	switch key {
-	case event.CalleeKey:
-		value = call.CallData.Callee
-	case event.CallerKey:
-		value = call.CallData.Caller
-	case event.ValueKey:
-		value = call.CallData.Value
-	case event.GasKey:
-		value = call.CallData.Gas
-	case event.StackDepthKey:
-		value = call.StackDepth
-	case event.OriginKey:
-		value = call.Origin
-	case event.ExceptionKey:
-		value = call.Exception
-	default:
-		return "", false
-	}
-	return query.StringFromValue(value), true
-}
-
-func (call *EventDataCall) Len() int {
-	return len(callTagKeys)
-}
-
-func (call *EventDataCall) Keys() []string {
-	return callTagKeys
-}
-
-func (call *EventDataCall) Tags(tags map[string]interface{}) map[string]interface{} {
-	tags[event.CalleeKey] = call.CallData.Callee
-	tags[event.CallerKey] = call.CallData.Caller
-	tags[event.ValueKey] = call.CallData.Value
-	tags[event.GasKey] = call.CallData.Gas
-	tags[event.StackDepthKey] = call.StackDepth
-	tags[event.OriginKey] = call.Origin
-	if call.Exception != nil {
-		tags[event.ExceptionKey] = call.Exception
-	}
-	return tags
-}
diff --git a/execution/events/event.go b/execution/events/event.go
deleted file mode 100644
index 508c96776e19b5e360c61830ffa2ccae90ac8525..0000000000000000000000000000000000000000
--- a/execution/events/event.go
+++ /dev/null
@@ -1,121 +0,0 @@
-package events
-
-import (
-	"fmt"
-
-	"reflect"
-
-	"github.com/hyperledger/burrow/event"
-	"github.com/hyperledger/burrow/txs"
-)
-
-var cdc = txs.NewAminoCodec()
-
-var eventMessageTag = event.TagMap{event.MessageTypeKey: reflect.TypeOf(&Event{}).String()}
-
-type Provider interface {
-	// Get events between startKey (inclusive) and endKey (exclusive) - i.e. the half open interval [start, end)
-	GetEvents(startKey, endKey Key, consumer func(*Event) (stop bool)) (stopped bool, err error)
-	LatestEventKey() Key
-}
-
-type Event struct {
-	Header *Header
-	Call   *EventDataCall `json:",omitempty"`
-	Log    *EventDataLog  `json:",omitempty"`
-	Tx     *EventDataTx   `json:",omitempty"`
-	tags   event.Tags
-}
-
-func DecodeEvent(bs []byte) (*Event, error) {
-	ev := new(Event)
-	err := cdc.UnmarshalBinary(bs, ev)
-	if err != nil {
-		return nil, err
-	}
-	return ev, nil
-}
-
-func (ev *Event) Key() Key {
-	return ev.Header.Key()
-}
-
-// Performs a shallow copy of Event
-func (ev *Event) Copy() *Event {
-	h := *ev.Header
-	evCopy := Event{
-		Header: &h,
-	}
-	if ev.Tx != nil {
-		tx := *ev.Tx
-		evCopy.Tx = &tx
-	}
-	if ev.Call != nil {
-		call := *ev.Call
-		evCopy.Call = &call
-	}
-	if ev.Log != nil {
-		log := *ev.Log
-		evCopy.Log = &log
-	}
-	return &evCopy
-}
-
-func (ev *Event) Encode() ([]byte, error) {
-	return cdc.MarshalBinary(ev)
-}
-
-func (ev *Event) Tags() event.Tags {
-	if ev.tags == nil {
-		ev.tags = event.CombinedTags{
-			ev.Header,
-			eventMessageTag,
-			ev.Tx,
-			ev.Call,
-			ev.Log,
-		}
-	}
-	return ev.tags
-}
-
-func (ev *Event) Get(key string) (value string, ok bool) {
-	return ev.Tags().Get(key)
-}
-
-func (ev *Event) Keys() []string {
-	return ev.Tags().Keys()
-}
-
-func (ev *Event) Len() int {
-	return ev.Tags().Len()
-}
-
-// event.Cache will provide an index through this methods of Indexable
-func (ev *Event) ProvideIndex(index uint64) {
-	ev.Header.Index = index
-}
-
-func (ev *Event) String() string {
-	return fmt.Sprintf("%v", ev.Header)
-}
-
-func (ev *Event) GetTx() *EventDataTx {
-	if ev == nil {
-		return nil
-	}
-	return ev.Tx
-}
-
-func (ev *Event) GetCall() *EventDataCall {
-	if ev == nil {
-		return nil
-	}
-	return ev.Call
-}
-
-func (ev *Event) GetLog() *EventDataLog {
-	if ev == nil {
-		return nil
-	}
-	return ev.Log
-}
diff --git a/execution/events/event_test.go b/execution/events/event_test.go
deleted file mode 100644
index 4831edfe2760a4fcc5d2d97b2471ddfbf5bf6987..0000000000000000000000000000000000000000
--- a/execution/events/event_test.go
+++ /dev/null
@@ -1,92 +0,0 @@
-package events
-
-import (
-	"testing"
-
-	"github.com/hyperledger/burrow/binary"
-	"github.com/hyperledger/burrow/crypto"
-	"github.com/hyperledger/burrow/event"
-	"github.com/hyperledger/burrow/event/query"
-	"github.com/stretchr/testify/assert"
-	"github.com/stretchr/testify/require"
-	"github.com/tmthrgd/go-hex"
-)
-
-func TestHeader_Key(t *testing.T) {
-	h := &Header{
-		EventID: "Foos",
-		Height:  2345345232,
-		Index:   34,
-	}
-	key := h.Key()
-	keyString := hex.EncodeUpperToString(key)
-	assert.Equal(t, "000000008BCB20D00000000000000022", keyString)
-	assert.Len(t, keyString, 32, "should be 16 bytes")
-	assert.Equal(t, h.Height, key.Height())
-	assert.Equal(t, h.Index, key.Index())
-}
-
-func TestKey_IsSuccessorOf(t *testing.T) {
-	assert.True(t, NewKey(1, 0).IsSuccessorOf(NewKey(0, 1)))
-	assert.True(t, NewKey(100, 24).IsSuccessorOf(NewKey(100, 23)))
-	assert.False(t, NewKey(100, 23).IsSuccessorOf(NewKey(100, 25)))
-	assert.False(t, NewKey(1, 1).IsSuccessorOf(NewKey(0, 25)))
-	assert.True(t, NewKey(3, 0).IsSuccessorOf(NewKey(2, 0)))
-}
-
-func TestEventTagQueries(t *testing.T) {
-	addressHex := "DEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEF"
-	address, err := crypto.AddressFromHexString(addressHex)
-	require.NoError(t, err)
-	ev := &Event{
-		Header: &Header{
-			EventType: TypeLog,
-			EventID:   "foo/bar",
-			TxHash:    []byte{2, 3, 4},
-			Height:    34,
-			Index:     2,
-		},
-		Log: &EventDataLog{
-			Address: address,
-			Topics:  []binary.Word256{binary.RightPadWord256([]byte("marmot"))},
-		},
-	}
-
-	qb := query.NewBuilder().AndEquals(event.EventTypeKey, TypeLog.String())
-	qry, err := qb.Query()
-	require.NoError(t, err)
-	assert.True(t, qry.Matches(ev))
-
-	qb = qb.AndContains(event.EventIDKey, "bar")
-	qry, err = qb.Query()
-	require.NoError(t, err)
-	assert.True(t, qry.Matches(ev))
-
-	qb = qb.AndEquals(event.TxHashKey, hex.EncodeUpperToString(ev.Header.TxHash))
-	qry, err = qb.Query()
-	require.NoError(t, err)
-	assert.True(t, qry.Matches(ev))
-
-	qb = qb.AndGreaterThanOrEqual(event.HeightKey, ev.Header.Height)
-	qry, err = qb.Query()
-	require.NoError(t, err)
-	assert.True(t, qry.Matches(ev))
-
-	qb = qb.AndStrictlyLessThan(event.IndexKey, ev.Header.Index+1)
-	qry, err = qb.Query()
-	require.NoError(t, err)
-	assert.True(t, qry.Matches(ev))
-
-	qb = qb.AndEquals(event.AddressKey, addressHex)
-	qry, err = qb.Query()
-	require.NoError(t, err)
-	assert.True(t, qry.Matches(ev))
-
-	qb = qb.AndEquals(event.LogNTextKey(0), "marmot")
-	qry, err = qb.Query()
-	require.NoError(t, err)
-	assert.True(t, qry.Matches(ev))
-
-	t.Logf("Query: %v", qry)
-	t.Logf("Keys: %v", ev.Keys())
-}
diff --git a/execution/events/header.go b/execution/events/header.go
deleted file mode 100644
index d5b09749b3c3bbbe3d57b1e6ea3f8800c81d0b5b..0000000000000000000000000000000000000000
--- a/execution/events/header.go
+++ /dev/null
@@ -1,76 +0,0 @@
-package events
-
-import (
-	"fmt"
-
-	"github.com/hyperledger/burrow/binary"
-	"github.com/hyperledger/burrow/event"
-	"github.com/hyperledger/burrow/event/query"
-	"github.com/hyperledger/burrow/txs/payload"
-)
-
-type Header struct {
-	TxType    payload.Type
-	TxHash    binary.HexBytes
-	EventType Type
-	EventID   string
-	Height    uint64
-	Index     uint64
-}
-
-var headerTagKeys = []string{
-	event.TxTypeKey,
-	event.TxHashKey,
-	event.EventTypeKey,
-	event.EventIDKey,
-	event.HeightKey,
-	event.IndexKey,
-}
-
-// Implements Tags for events
-func (h *Header) Get(key string) (value string, ok bool) {
-	var v interface{}
-	switch key {
-	case event.TxTypeKey:
-		v = h.TxType
-	case event.TxHashKey:
-		v = h.TxHash
-	case event.EventTypeKey:
-		v = h.EventType
-	case event.EventIDKey:
-		v = h.EventID
-	case event.HeightKey:
-		v = h.Height
-	case event.IndexKey:
-		v = h.Index
-	default:
-		return "", false
-	}
-	return query.StringFromValue(v), true
-}
-
-func (h *Header) Len() int {
-	return len(headerTagKeys)
-}
-
-func (h *Header) Map() map[string]interface{} {
-	tags := make(map[string]interface{})
-	for _, key := range headerTagKeys {
-		tags[key], _ = h.Get(key)
-	}
-	return tags
-}
-
-func (h *Header) Keys() []string {
-	return headerTagKeys
-}
-
-// Returns a lexicographically sortable key encoding the height and index of this event
-func (h *Header) Key() Key {
-	return NewKey(h.Height, h.Index)
-}
-
-func (h *Header) String() string {
-	return fmt.Sprintf("Header{Tx{%v}: %v; Event{%v}: %v; Height: %v; Index: %v}",
-		h.TxType, h.TxHash, h.EventType, h.EventID, h.Height, h.Index)
-}
diff --git a/execution/events/key.go b/execution/events/key.go
deleted file mode 100644
index 52371518fb6c5ac7a6a3f4cb53fa32f9289f90b0..0000000000000000000000000000000000000000
--- a/execution/events/key.go
+++ /dev/null
@@ -1,57 +0,0 @@
-package events
-
-import (
-	"bytes"
-	"fmt"
-
-	"github.com/hyperledger/burrow/binary"
-)
-
-type Key []byte
-
-func NewKey(height, index uint64) Key {
-	k := make(Key, 16)
-	// Will order first by height then by index so events from the same block will be consecutive
-	binary.PutUint64BE(k[:8], height)
-	binary.PutUint64BE(k[8:], index)
-	return k
-}
-
-// -1 if k < k2
-//  0 if k == k2
-//  1 if k > k2
-func (k Key) Compare(k2 Key) int {
-	return bytes.Compare(k, k2)
-}
-
-// Returns true iff k is a valid successor key to p;
-// iff (the height is the same and the index is one greater) or (the height is greater and the index is zero) or (p
-// is uninitialised)
-func (k Key) IsSuccessorOf(p Key) bool {
-	if len(p) == 0 {
-		return true
-	}
-	ph, kh := p.Height(), k.Height()
-	pi, ki := p.Index(), k.Index()
-	return ph == kh && pi+1 == ki || ph < kh && ki == 0
-}
-
-func (k Key) IncHeight() Key {
-	return NewKey(k.Height()+1, k.Index())
-}
-
-func (k Key) Bytes() []byte {
-	return k
-}
-
-func (k Key) Height() uint64 {
-	return binary.GetUint64BE(k[:8])
-}
-
-func (k Key) Index() uint64 {
-	return binary.GetUint64BE(k[8:])
-}
-
-func (k Key) String() string {
-	return fmt.Sprintf("Key{Height: %v; Index: %v}", k.Height(), k.Index())
-}
diff --git a/execution/events/pbevents/events.go b/execution/events/pbevents/events.go
deleted file mode 100644
index 99bc841b766b8df191a7c8fe881e0431a81d5be2..0000000000000000000000000000000000000000
--- a/execution/events/pbevents/events.go
+++ /dev/null
@@ -1,168 +0,0 @@
-package pbevents
-
-import (
-	"github.com/hyperledger/burrow/binary"
-	"github.com/hyperledger/burrow/crypto"
-	"github.com/hyperledger/burrow/execution/events"
-	"github.com/hyperledger/burrow/txs/payload"
-)
-
-// this mostly contains tedious mapping between protobuf and our domain objects, but it may be worth
-// the pain to avoid complexity and edge cases using gogoproto or other techniques.
-
-func GetEventDataCall(edt *events.EventDataCall) *EventDataCall {
-	return &EventDataCall{
-		Origin:     edt.Origin.Bytes(),
-		CallData:   GetCallData(edt.CallData),
-		StackDepth: edt.StackDepth,
-		Return:     edt.Return,
-		Exception:  edt.Exception,
-	}
-}
-
-func GetCallData(cd *events.CallData) *CallData {
-	return &CallData{
-		Caller: cd.Caller.Bytes(),
-		Callee: cd.Callee.Bytes(),
-		Data:   cd.Data,
-		Gas:    cd.Gas,
-	}
-}
-
-func GetExecutionEvent(event *events.Event) *ExecutionEvent {
-	return &ExecutionEvent{
-		Header:    GetEventHeader(event.Header),
-		EventData: GetEventData(event),
-	}
-}
-
-func GetEventHeader(header *events.Header) *EventHeader {
-	return &EventHeader{
-		TxType:    header.TxType.String(),
-		TxHash:    header.TxHash,
-		EventType: header.EventType.String(),
-		EventID:   header.EventID,
-		Height:    header.Height,
-		Index:     header.Index,
-	}
-}
-
-func GetEventData(ev *events.Event) isExecutionEvent_EventData {
-	if ev.Call != nil {
-		return &ExecutionEvent_EventDataCall{
-			EventDataCall: &EventDataCall{
-				CallData:   GetCallData(ev.Call.CallData),
-				Origin:     ev.Call.Origin.Bytes(),
-				StackDepth: ev.Call.StackDepth,
-				Return:     ev.Call.Return,
-				Exception:  ev.Call.Exception,
-			},
-		}
-	}
-
-	if ev.Log != nil {
-		return &ExecutionEvent_EventDataLog{
-			EventDataLog: &EventDataLog{
-				Address: ev.Log.Address.Bytes(),
-				Data:    ev.Log.Data,
-				Topics:  GetTopic(ev.Log.Topics),
-			},
-		}
-	}
-
-	if ev.Tx != nil {
-		return &ExecutionEvent_EventDataTx{
-			EventDataTx: &EventDataTx{
-				Return:    ev.Tx.Return,
-				Exception: ev.Tx.Exception,
-			},
-		}
-	}
-
-	return nil
-}
-
-func GetTopic(topics []binary.Word256) [][]byte {
-	topicBytes := make([][]byte, len(topics))
-	for i, t := range topics {
-		topicBytes[i] = t.Bytes()
-	}
-	return topicBytes
-}
-
-func (ee *ExecutionEvent) Event() *events.Event {
-	return &events.Event{
-		Header: ee.GetHeader().Header(),
-		Tx:     ee.GetEventDataTx().Tx(),
-		Log:    ee.GetEventDataLog().Log(ee.Header.Height),
-		Call:   ee.GetEventDataCall().Call(ee.Header.TxHash),
-	}
-}
-
-func (ee *ExecutionEvent) Key() events.Key {
-	return ee.Header.Key()
-}
-
-func (h *EventHeader) Key() events.Key {
-	return events.NewKey(h.Height, h.Index)
-}
-
-func (h *EventHeader) Header() *events.Header {
-	return &events.Header{
-		TxType:    payload.TxTypeFromString(h.TxType),
-		TxHash:    h.TxHash,
-		EventType: events.EventTypeFromString(h.EventType),
-		EventID:   h.EventID,
-		Height:    h.Height,
-		Index:     h.Index,
-	}
-}
-
-func (tx *EventDataTx) Tx() *events.EventDataTx {
-	if tx == nil {
-		return nil
-	}
-	return &events.EventDataTx{
-		Return:    tx.Return,
-		Exception: tx.Exception,
-	}
-}
-
-func (log *EventDataLog) Log(height uint64) *events.EventDataLog {
-	if log == nil {
-		return nil
-	}
-	topicWords := make([]binary.Word256, len(log.Topics))
-	for i, bs := range log.Topics {
-		topicWords[i] = binary.LeftPadWord256(bs)
-	}
-	return &events.EventDataLog{
-		Height:  height,
-		Topics:  topicWords,
-		Address: crypto.MustAddressFromBytes(log.Address),
-		Data:    log.Data,
-	}
-}
-
-func (call *EventDataCall) Call(txHash []byte) *events.EventDataCall {
-	if call == nil {
-		return nil
-	}
-	return &events.EventDataCall{
-		Return:     call.Return,
-		CallData:   call.CallData.CallData(),
-		Origin:     crypto.MustAddressFromBytes(call.Origin),
-		StackDepth: call.StackDepth,
-		Exception:  call.Exception,
-	}
-}
-
-func (cd *CallData) CallData() *events.CallData {
-	return &events.CallData{
-		Caller: crypto.MustAddressFromBytes(cd.Caller),
-		Callee: crypto.MustAddressFromBytes(cd.Callee),
-		Value:  cd.Value,
-		Gas:    cd.Gas,
-		Data:   cd.Data,
-	}
-}
diff --git a/execution/events/pbevents/events.pb.go b/execution/events/pbevents/events.pb.go
deleted file mode 100644
index 132817582cfcda6667e5e75c5fc750bf1b565a4a..0000000000000000000000000000000000000000
--- a/execution/events/pbevents/events.pb.go
+++ /dev/null
@@ -1,1403 +0,0 @@
-// Code generated by protoc-gen-go. DO NOT EDIT.
-// source: github.com/hyperledger/burrow/execution/events/pbevents/events.proto
-
-package pbevents // import "github.com/hyperledger/burrow/execution/events/pbevents"
-
-import proto "github.com/golang/protobuf/proto"
-import fmt "fmt"
-import math "math"
-import errors "github.com/hyperledger/burrow/execution/errors"
-
-import (
-	context "golang.org/x/net/context"
-	grpc "google.golang.org/grpc"
-)
-
-// Reference imports to suppress errors if they are not otherwise used.
-var _ = proto.Marshal
-var _ = fmt.Errorf
-var _ = math.Inf
-
-// This is a compile-time assertion to ensure that this generated file
-// is compatible with the proto package it is being compiled against.
-// A compilation error at this line likely means your copy of the
-// proto package needs to be updated.
-const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
-
-type Bound_BoundType int32
-
-const (
-	// Index is absolute index of object in collection
-	Bound_ABSOLUTE Bound_BoundType = 0
-	// Index is an offset relative to another bound determined by context
-	Bound_RELATIVE Bound_BoundType = 1
-	// The first block
-	Bound_FIRST Bound_BoundType = 2
-	// Ignore provided index and evaluate to latest index
-	Bound_LATEST Bound_BoundType = 3
-	// Ignore provided index and stream new objects as they are generated
-	Bound_STREAM Bound_BoundType = 4
-)
-
-var Bound_BoundType_name = map[int32]string{
-	0: "ABSOLUTE",
-	1: "RELATIVE",
-	2: "FIRST",
-	3: "LATEST",
-	4: "STREAM",
-}
-var Bound_BoundType_value = map[string]int32{
-	"ABSOLUTE": 0,
-	"RELATIVE": 1,
-	"FIRST":    2,
-	"LATEST":   3,
-	"STREAM":   4,
-}
-
-func (x Bound_BoundType) String() string {
-	return proto.EnumName(Bound_BoundType_name, int32(x))
-}
-func (Bound_BoundType) EnumDescriptor() ([]byte, []int) {
-	return fileDescriptor_events_a0e2b84614955cff, []int{7, 0}
-}
-
-// Params
-type EventIdParam struct {
-	EventId              string   `protobuf:"bytes,1,opt,name=eventId,proto3" json:"eventId,omitempty"`
-	XXX_NoUnkeyedLiteral struct{} `json:"-"`
-	XXX_unrecognized     []byte   `json:"-"`
-	XXX_sizecache        int32    `json:"-"`
-}
-
-func (m *EventIdParam) Reset()         { *m = EventIdParam{} }
-func (m *EventIdParam) String() string { return proto.CompactTextString(m) }
-func (*EventIdParam) ProtoMessage()    {}
-func (*EventIdParam) Descriptor() ([]byte, []int) {
-	return fileDescriptor_events_a0e2b84614955cff, []int{0}
-}
-func (m *EventIdParam) XXX_Unmarshal(b []byte) error {
-	return xxx_messageInfo_EventIdParam.Unmarshal(m, b)
-}
-func (m *EventIdParam) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
-	return xxx_messageInfo_EventIdParam.Marshal(b, m, deterministic)
-}
-func (dst *EventIdParam) XXX_Merge(src proto.Message) {
-	xxx_messageInfo_EventIdParam.Merge(dst, src)
-}
-func (m *EventIdParam) XXX_Size() int {
-	return xxx_messageInfo_EventIdParam.Size(m)
-}
-func (m *EventIdParam) XXX_DiscardUnknown() {
-	xxx_messageInfo_EventIdParam.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_EventIdParam proto.InternalMessageInfo
-
-func (m *EventIdParam) GetEventId() string {
-	if m != nil {
-		return m.EventId
-	}
-	return ""
-}
-
-type SubIdParam struct {
-	SubId                string   `protobuf:"bytes,1,opt,name=subId,proto3" json:"subId,omitempty"`
-	XXX_NoUnkeyedLiteral struct{} `json:"-"`
-	XXX_unrecognized     []byte   `json:"-"`
-	XXX_sizecache        int32    `json:"-"`
-}
-
-func (m *SubIdParam) Reset()         { *m = SubIdParam{} }
-func (m *SubIdParam) String() string { return proto.CompactTextString(m) }
-func (*SubIdParam) ProtoMessage()    {}
-func (*SubIdParam) Descriptor() ([]byte, []int) {
-	return fileDescriptor_events_a0e2b84614955cff, []int{1}
-}
-func (m *SubIdParam) XXX_Unmarshal(b []byte) error {
-	return xxx_messageInfo_SubIdParam.Unmarshal(m, b)
-}
-func (m *SubIdParam) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
-	return xxx_messageInfo_SubIdParam.Marshal(b, m, deterministic)
-}
-func (dst *SubIdParam) XXX_Merge(src proto.Message) {
-	xxx_messageInfo_SubIdParam.Merge(dst, src)
-}
-func (m *SubIdParam) XXX_Size() int {
-	return xxx_messageInfo_SubIdParam.Size(m)
-}
-func (m *SubIdParam) XXX_DiscardUnknown() {
-	xxx_messageInfo_SubIdParam.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_SubIdParam proto.InternalMessageInfo
-
-func (m *SubIdParam) GetSubId() string {
-	if m != nil {
-		return m.SubId
-	}
-	return ""
-}
-
-// Results
-type EventUnSub struct {
-	Result               bool     `protobuf:"varint,1,opt,name=result,proto3" json:"result,omitempty"`
-	XXX_NoUnkeyedLiteral struct{} `json:"-"`
-	XXX_unrecognized     []byte   `json:"-"`
-	XXX_sizecache        int32    `json:"-"`
-}
-
-func (m *EventUnSub) Reset()         { *m = EventUnSub{} }
-func (m *EventUnSub) String() string { return proto.CompactTextString(m) }
-func (*EventUnSub) ProtoMessage()    {}
-func (*EventUnSub) Descriptor() ([]byte, []int) {
-	return fileDescriptor_events_a0e2b84614955cff, []int{2}
-}
-func (m *EventUnSub) XXX_Unmarshal(b []byte) error {
-	return xxx_messageInfo_EventUnSub.Unmarshal(m, b)
-}
-func (m *EventUnSub) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
-	return xxx_messageInfo_EventUnSub.Marshal(b, m, deterministic)
-}
-func (dst *EventUnSub) XXX_Merge(src proto.Message) {
-	xxx_messageInfo_EventUnSub.Merge(dst, src)
-}
-func (m *EventUnSub) XXX_Size() int {
-	return xxx_messageInfo_EventUnSub.Size(m)
-}
-func (m *EventUnSub) XXX_DiscardUnknown() {
-	xxx_messageInfo_EventUnSub.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_EventUnSub proto.InternalMessageInfo
-
-func (m *EventUnSub) GetResult() bool {
-	if m != nil {
-		return m.Result
-	}
-	return false
-}
-
-type PollResponse struct {
-	Events               []*Event `protobuf:"bytes,1,rep,name=events,proto3" json:"events,omitempty"`
-	XXX_NoUnkeyedLiteral struct{} `json:"-"`
-	XXX_unrecognized     []byte   `json:"-"`
-	XXX_sizecache        int32    `json:"-"`
-}
-
-func (m *PollResponse) Reset()         { *m = PollResponse{} }
-func (m *PollResponse) String() string { return proto.CompactTextString(m) }
-func (*PollResponse) ProtoMessage()    {}
-func (*PollResponse) Descriptor() ([]byte, []int) {
-	return fileDescriptor_events_a0e2b84614955cff, []int{3}
-}
-func (m *PollResponse) XXX_Unmarshal(b []byte) error {
-	return xxx_messageInfo_PollResponse.Unmarshal(m, b)
-}
-func (m *PollResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
-	return xxx_messageInfo_PollResponse.Marshal(b, m, deterministic)
-}
-func (dst *PollResponse) XXX_Merge(src proto.Message) {
-	xxx_messageInfo_PollResponse.Merge(dst, src)
-}
-func (m *PollResponse) XXX_Size() int {
-	return xxx_messageInfo_PollResponse.Size(m)
-}
-func (m *PollResponse) XXX_DiscardUnknown() {
-	xxx_messageInfo_PollResponse.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_PollResponse proto.InternalMessageInfo
-
-func (m *PollResponse) GetEvents() []*Event {
-	if m != nil {
-		return m.Events
-	}
-	return nil
-}
-
-type Event struct {
-	Name string `protobuf:"bytes,1,opt,name=Name,proto3" json:"Name,omitempty"`
-	// Types that are valid to be assigned to Event:
-	//	*Event_ExecutionEvent
-	//	*Event_TendermintEventJSON
-	Event                isEvent_Event `protobuf_oneof:"Event"`
-	XXX_NoUnkeyedLiteral struct{}      `json:"-"`
-	XXX_unrecognized     []byte        `json:"-"`
-	XXX_sizecache        int32         `json:"-"`
-}
-
-func (m *Event) Reset()         { *m = Event{} }
-func (m *Event) String() string { return proto.CompactTextString(m) }
-func (*Event) ProtoMessage()    {}
-func (*Event) Descriptor() ([]byte, []int) {
-	return fileDescriptor_events_a0e2b84614955cff, []int{4}
-}
-func (m *Event) XXX_Unmarshal(b []byte) error {
-	return xxx_messageInfo_Event.Unmarshal(m, b)
-}
-func (m *Event) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
-	return xxx_messageInfo_Event.Marshal(b, m, deterministic)
-}
-func (dst *Event) XXX_Merge(src proto.Message) {
-	xxx_messageInfo_Event.Merge(dst, src)
-}
-func (m *Event) XXX_Size() int {
-	return xxx_messageInfo_Event.Size(m)
-}
-func (m *Event) XXX_DiscardUnknown() {
-	xxx_messageInfo_Event.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_Event proto.InternalMessageInfo
-
-type isEvent_Event interface {
-	isEvent_Event()
-}
-
-type Event_ExecutionEvent struct {
-	ExecutionEvent *ExecutionEvent `protobuf:"bytes,2,opt,name=ExecutionEvent,proto3,oneof"`
-}
-type Event_TendermintEventJSON struct {
-	TendermintEventJSON string `protobuf:"bytes,3,opt,name=TendermintEventJSON,proto3,oneof"`
-}
-
-func (*Event_ExecutionEvent) isEvent_Event()      {}
-func (*Event_TendermintEventJSON) isEvent_Event() {}
-
-func (m *Event) GetEvent() isEvent_Event {
-	if m != nil {
-		return m.Event
-	}
-	return nil
-}
-
-func (m *Event) GetName() string {
-	if m != nil {
-		return m.Name
-	}
-	return ""
-}
-
-func (m *Event) GetExecutionEvent() *ExecutionEvent {
-	if x, ok := m.GetEvent().(*Event_ExecutionEvent); ok {
-		return x.ExecutionEvent
-	}
-	return nil
-}
-
-func (m *Event) GetTendermintEventJSON() string {
-	if x, ok := m.GetEvent().(*Event_TendermintEventJSON); ok {
-		return x.TendermintEventJSON
-	}
-	return ""
-}
-
-// XXX_OneofFuncs is for the internal use of the proto package.
-func (*Event) XXX_OneofFuncs() (func(msg proto.Message, b *proto.Buffer) error, func(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error), func(msg proto.Message) (n int), []interface{}) {
-	return _Event_OneofMarshaler, _Event_OneofUnmarshaler, _Event_OneofSizer, []interface{}{
-		(*Event_ExecutionEvent)(nil),
-		(*Event_TendermintEventJSON)(nil),
-	}
-}
-
-func _Event_OneofMarshaler(msg proto.Message, b *proto.Buffer) error {
-	m := msg.(*Event)
-	// Event
-	switch x := m.Event.(type) {
-	case *Event_ExecutionEvent:
-		b.EncodeVarint(2<<3 | proto.WireBytes)
-		if err := b.EncodeMessage(x.ExecutionEvent); err != nil {
-			return err
-		}
-	case *Event_TendermintEventJSON:
-		b.EncodeVarint(3<<3 | proto.WireBytes)
-		b.EncodeStringBytes(x.TendermintEventJSON)
-	case nil:
-	default:
-		return fmt.Errorf("Event.Event has unexpected type %T", x)
-	}
-	return nil
-}
-
-func _Event_OneofUnmarshaler(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error) {
-	m := msg.(*Event)
-	switch tag {
-	case 2: // Event.ExecutionEvent
-		if wire != proto.WireBytes {
-			return true, proto.ErrInternalBadWireType
-		}
-		msg := new(ExecutionEvent)
-		err := b.DecodeMessage(msg)
-		m.Event = &Event_ExecutionEvent{msg}
-		return true, err
-	case 3: // Event.TendermintEventJSON
-		if wire != proto.WireBytes {
-			return true, proto.ErrInternalBadWireType
-		}
-		x, err := b.DecodeStringBytes()
-		m.Event = &Event_TendermintEventJSON{x}
-		return true, err
-	default:
-		return false, nil
-	}
-}
-
-func _Event_OneofSizer(msg proto.Message) (n int) {
-	m := msg.(*Event)
-	// Event
-	switch x := m.Event.(type) {
-	case *Event_ExecutionEvent:
-		s := proto.Size(x.ExecutionEvent)
-		n += 1 // tag and wire
-		n += proto.SizeVarint(uint64(s))
-		n += s
-	case *Event_TendermintEventJSON:
-		n += 1 // tag and wire
-		n += proto.SizeVarint(uint64(len(x.TendermintEventJSON)))
-		n += len(x.TendermintEventJSON)
-	case nil:
-	default:
-		panic(fmt.Sprintf("proto: unexpected type %T in oneof", x))
-	}
-	return n
-}
-
-type GetEventsRequest struct {
-	BlockRange *BlockRange `protobuf:"bytes,1,opt,name=BlockRange,proto3" json:"BlockRange,omitempty"`
-	// Specify a query on which to match the tags of events.
-	// Tag        | Match type | Values
-	// -----------------------------------------
-	//   All events
-	// -----------------------------------------
-	// TxType       | String     | "UnknownTx", "SendTx", "CallTx", "NameTx", "BondTx", "UnbondTx", "PermissionsTx", "GovernanceTx"
-	// TxHash       | String     | bytes
-	// EventType    | String     | "CallEvent", "LogEvent", "AccountInputEvent", "AccountOutputEvent"
-	// EventID      | String     | string
-	// Height       | Integer    | uint64
-	// Index        | Integer    | uint64
-	// MessageType  | String     | Go type name
-	// -----------------------------------------
-	//   Log event
-	// -----------------------------------------
-	// Address      | String     | Address (hex)
-	// Log<0-4>     | String     | Word256 (hex)
-	// Log<0-4>Text | String     | string (trimmed)
-	// -----------------------------------------
-	//   Call event
-	// -----------------------------------------
-	// Origin       | String     | Address (hex)
-	// Callee       | String     | Address (hex)
-	// Caller       | String     | Address (hex)
-	// Value        | Integer    | uint64
-	// Gas          | Integer    | uint64
-	// StackDepth   | Integer    | uint64
-	// Exception    | String     | string
-	// -----------------------------------------
-	//   Tx event (input/output)
-	// -----------------------------------------
-	// Exception  | String     | string
-	//
-	// For example:
-	// EventType = 'LogEvent' AND EventID CONTAINS 'bar' AND TxHash = '020304' AND Height >= 34 AND Index < 3 AND Address = 'DEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEF'
-	Query                string   `protobuf:"bytes,2,opt,name=Query,proto3" json:"Query,omitempty"`
-	XXX_NoUnkeyedLiteral struct{} `json:"-"`
-	XXX_unrecognized     []byte   `json:"-"`
-	XXX_sizecache        int32    `json:"-"`
-}
-
-func (m *GetEventsRequest) Reset()         { *m = GetEventsRequest{} }
-func (m *GetEventsRequest) String() string { return proto.CompactTextString(m) }
-func (*GetEventsRequest) ProtoMessage()    {}
-func (*GetEventsRequest) Descriptor() ([]byte, []int) {
-	return fileDescriptor_events_a0e2b84614955cff, []int{5}
-}
-func (m *GetEventsRequest) XXX_Unmarshal(b []byte) error {
-	return xxx_messageInfo_GetEventsRequest.Unmarshal(m, b)
-}
-func (m *GetEventsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
-	return xxx_messageInfo_GetEventsRequest.Marshal(b, m, deterministic)
-}
-func (dst *GetEventsRequest) XXX_Merge(src proto.Message) {
-	xxx_messageInfo_GetEventsRequest.Merge(dst, src)
-}
-func (m *GetEventsRequest) XXX_Size() int {
-	return xxx_messageInfo_GetEventsRequest.Size(m)
-}
-func (m *GetEventsRequest) XXX_DiscardUnknown() {
-	xxx_messageInfo_GetEventsRequest.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_GetEventsRequest proto.InternalMessageInfo
-
-func (m *GetEventsRequest) GetBlockRange() *BlockRange {
-	if m != nil {
-		return m.BlockRange
-	}
-	return nil
-}
-
-func (m *GetEventsRequest) GetQuery() string {
-	if m != nil {
-		return m.Query
-	}
-	return ""
-}
-
-type GetEventsResponse struct {
-	Events               []*ExecutionEvent `protobuf:"bytes,1,rep,name=events,proto3" json:"events,omitempty"`
-	XXX_NoUnkeyedLiteral struct{}          `json:"-"`
-	XXX_unrecognized     []byte            `json:"-"`
-	XXX_sizecache        int32             `json:"-"`
-}
-
-func (m *GetEventsResponse) Reset()         { *m = GetEventsResponse{} }
-func (m *GetEventsResponse) String() string { return proto.CompactTextString(m) }
-func (*GetEventsResponse) ProtoMessage()    {}
-func (*GetEventsResponse) Descriptor() ([]byte, []int) {
-	return fileDescriptor_events_a0e2b84614955cff, []int{6}
-}
-func (m *GetEventsResponse) XXX_Unmarshal(b []byte) error {
-	return xxx_messageInfo_GetEventsResponse.Unmarshal(m, b)
-}
-func (m *GetEventsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
-	return xxx_messageInfo_GetEventsResponse.Marshal(b, m, deterministic)
-}
-func (dst *GetEventsResponse) XXX_Merge(src proto.Message) {
-	xxx_messageInfo_GetEventsResponse.Merge(dst, src)
-}
-func (m *GetEventsResponse) XXX_Size() int {
-	return xxx_messageInfo_GetEventsResponse.Size(m)
-}
-func (m *GetEventsResponse) XXX_DiscardUnknown() {
-	xxx_messageInfo_GetEventsResponse.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_GetEventsResponse proto.InternalMessageInfo
-
-func (m *GetEventsResponse) GetEvents() []*ExecutionEvent {
-	if m != nil {
-		return m.Events
-	}
-	return nil
-}
-
-type Bound struct {
-	Type                 Bound_BoundType `protobuf:"varint,1,opt,name=Type,proto3,enum=pbevents.Bound_BoundType" json:"Type,omitempty"`
-	Index                uint64          `protobuf:"varint,2,opt,name=Index,proto3" json:"Index,omitempty"`
-	XXX_NoUnkeyedLiteral struct{}        `json:"-"`
-	XXX_unrecognized     []byte          `json:"-"`
-	XXX_sizecache        int32           `json:"-"`
-}
-
-func (m *Bound) Reset()         { *m = Bound{} }
-func (m *Bound) String() string { return proto.CompactTextString(m) }
-func (*Bound) ProtoMessage()    {}
-func (*Bound) Descriptor() ([]byte, []int) {
-	return fileDescriptor_events_a0e2b84614955cff, []int{7}
-}
-func (m *Bound) XXX_Unmarshal(b []byte) error {
-	return xxx_messageInfo_Bound.Unmarshal(m, b)
-}
-func (m *Bound) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
-	return xxx_messageInfo_Bound.Marshal(b, m, deterministic)
-}
-func (dst *Bound) XXX_Merge(src proto.Message) {
-	xxx_messageInfo_Bound.Merge(dst, src)
-}
-func (m *Bound) XXX_Size() int {
-	return xxx_messageInfo_Bound.Size(m)
-}
-func (m *Bound) XXX_DiscardUnknown() {
-	xxx_messageInfo_Bound.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_Bound proto.InternalMessageInfo
-
-func (m *Bound) GetType() Bound_BoundType {
-	if m != nil {
-		return m.Type
-	}
-	return Bound_ABSOLUTE
-}
-
-func (m *Bound) GetIndex() uint64 {
-	if m != nil {
-		return m.Index
-	}
-	return 0
-}
-
-// An inclusive range of blocks to include in output
-type BlockRange struct {
-	// Bounds can be set to:
-	// absolute: block height
-	// relative: block height counting back from latest
-	// latest: latest block when call is processed
-	// stream: for End keep sending new blocks, for start same as latest
-	Start                *Bound   `protobuf:"bytes,1,opt,name=Start,proto3" json:"Start,omitempty"`
-	End                  *Bound   `protobuf:"bytes,2,opt,name=End,proto3" json:"End,omitempty"`
-	XXX_NoUnkeyedLiteral struct{} `json:"-"`
-	XXX_unrecognized     []byte   `json:"-"`
-	XXX_sizecache        int32    `json:"-"`
-}
-
-func (m *BlockRange) Reset()         { *m = BlockRange{} }
-func (m *BlockRange) String() string { return proto.CompactTextString(m) }
-func (*BlockRange) ProtoMessage()    {}
-func (*BlockRange) Descriptor() ([]byte, []int) {
-	return fileDescriptor_events_a0e2b84614955cff, []int{8}
-}
-func (m *BlockRange) XXX_Unmarshal(b []byte) error {
-	return xxx_messageInfo_BlockRange.Unmarshal(m, b)
-}
-func (m *BlockRange) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
-	return xxx_messageInfo_BlockRange.Marshal(b, m, deterministic)
-}
-func (dst *BlockRange) XXX_Merge(src proto.Message) {
-	xxx_messageInfo_BlockRange.Merge(dst, src)
-}
-func (m *BlockRange) XXX_Size() int {
-	return xxx_messageInfo_BlockRange.Size(m)
-}
-func (m *BlockRange) XXX_DiscardUnknown() {
-	xxx_messageInfo_BlockRange.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_BlockRange proto.InternalMessageInfo
-
-func (m *BlockRange) GetStart() *Bound {
-	if m != nil {
-		return m.Start
-	}
-	return nil
-}
-
-func (m *BlockRange) GetEnd() *Bound {
-	if m != nil {
-		return m.End
-	}
-	return nil
-}
-
-type EventHeader struct {
-	// Transaction type
-	TxType string `protobuf:"bytes,1,opt,name=TxType,proto3" json:"TxType,omitempty"`
-	// The hash of the transaction that caused this event to be generated
-	TxHash []byte `protobuf:"bytes,2,opt,name=TxHash,proto3" json:"TxHash,omitempty"`
-	// The type of event
-	EventType string `protobuf:"bytes,3,opt,name=EventType,proto3" json:"EventType,omitempty"`
-	// EventID published with event
-	EventID string `protobuf:"bytes,4,opt,name=EventID,proto3" json:"EventID,omitempty"`
-	// The block height at which this event was emitted
-	Height uint64 `protobuf:"varint,5,opt,name=Height,proto3" json:"Height,omitempty"`
-	// The index amongst all other events in the block of this event
-	Index                uint64   `protobuf:"varint,6,opt,name=Index,proto3" json:"Index,omitempty"`
-	XXX_NoUnkeyedLiteral struct{} `json:"-"`
-	XXX_unrecognized     []byte   `json:"-"`
-	XXX_sizecache        int32    `json:"-"`
-}
-
-func (m *EventHeader) Reset()         { *m = EventHeader{} }
-func (m *EventHeader) String() string { return proto.CompactTextString(m) }
-func (*EventHeader) ProtoMessage()    {}
-func (*EventHeader) Descriptor() ([]byte, []int) {
-	return fileDescriptor_events_a0e2b84614955cff, []int{9}
-}
-func (m *EventHeader) XXX_Unmarshal(b []byte) error {
-	return xxx_messageInfo_EventHeader.Unmarshal(m, b)
-}
-func (m *EventHeader) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
-	return xxx_messageInfo_EventHeader.Marshal(b, m, deterministic)
-}
-func (dst *EventHeader) XXX_Merge(src proto.Message) {
-	xxx_messageInfo_EventHeader.Merge(dst, src)
-}
-func (m *EventHeader) XXX_Size() int {
-	return xxx_messageInfo_EventHeader.Size(m)
-}
-func (m *EventHeader) XXX_DiscardUnknown() {
-	xxx_messageInfo_EventHeader.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_EventHeader proto.InternalMessageInfo
-
-func (m *EventHeader) GetTxType() string {
-	if m != nil {
-		return m.TxType
-	}
-	return ""
-}
-
-func (m *EventHeader) GetTxHash() []byte {
-	if m != nil {
-		return m.TxHash
-	}
-	return nil
-}
-
-func (m *EventHeader) GetEventType() string {
-	if m != nil {
-		return m.EventType
-	}
-	return ""
-}
-
-func (m *EventHeader) GetEventID() string {
-	if m != nil {
-		return m.EventID
-	}
-	return ""
-}
-
-func (m *EventHeader) GetHeight() uint64 {
-	if m != nil {
-		return m.Height
-	}
-	return 0
-}
-
-func (m *EventHeader) GetIndex() uint64 {
-	if m != nil {
-		return m.Index
-	}
-	return 0
-}
-
-type ExecutionEvent struct {
-	Header *EventHeader `protobuf:"bytes,1,opt,name=Header,proto3" json:"Header,omitempty"`
-	// Types that are valid to be assigned to EventData:
-	//	*ExecutionEvent_EventDataTx
-	//	*ExecutionEvent_EventDataCall
-	//	*ExecutionEvent_EventDataLog
-	EventData            isExecutionEvent_EventData `protobuf_oneof:"EventData"`
-	XXX_NoUnkeyedLiteral struct{}                   `json:"-"`
-	XXX_unrecognized     []byte                     `json:"-"`
-	XXX_sizecache        int32                      `json:"-"`
-}
-
-func (m *ExecutionEvent) Reset()         { *m = ExecutionEvent{} }
-func (m *ExecutionEvent) String() string { return proto.CompactTextString(m) }
-func (*ExecutionEvent) ProtoMessage()    {}
-func (*ExecutionEvent) Descriptor() ([]byte, []int) {
-	return fileDescriptor_events_a0e2b84614955cff, []int{10}
-}
-func (m *ExecutionEvent) XXX_Unmarshal(b []byte) error {
-	return xxx_messageInfo_ExecutionEvent.Unmarshal(m, b)
-}
-func (m *ExecutionEvent) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
-	return xxx_messageInfo_ExecutionEvent.Marshal(b, m, deterministic)
-}
-func (dst *ExecutionEvent) XXX_Merge(src proto.Message) {
-	xxx_messageInfo_ExecutionEvent.Merge(dst, src)
-}
-func (m *ExecutionEvent) XXX_Size() int {
-	return xxx_messageInfo_ExecutionEvent.Size(m)
-}
-func (m *ExecutionEvent) XXX_DiscardUnknown() {
-	xxx_messageInfo_ExecutionEvent.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_ExecutionEvent proto.InternalMessageInfo
-
-type isExecutionEvent_EventData interface {
-	isExecutionEvent_EventData()
-}
-
-type ExecutionEvent_EventDataTx struct {
-	EventDataTx *EventDataTx `protobuf:"bytes,2,opt,name=EventDataTx,proto3,oneof"`
-}
-type ExecutionEvent_EventDataCall struct {
-	EventDataCall *EventDataCall `protobuf:"bytes,3,opt,name=EventDataCall,proto3,oneof"`
-}
-type ExecutionEvent_EventDataLog struct {
-	EventDataLog *EventDataLog `protobuf:"bytes,4,opt,name=EventDataLog,proto3,oneof"`
-}
-
-func (*ExecutionEvent_EventDataTx) isExecutionEvent_EventData()   {}
-func (*ExecutionEvent_EventDataCall) isExecutionEvent_EventData() {}
-func (*ExecutionEvent_EventDataLog) isExecutionEvent_EventData()  {}
-
-func (m *ExecutionEvent) GetEventData() isExecutionEvent_EventData {
-	if m != nil {
-		return m.EventData
-	}
-	return nil
-}
-
-func (m *ExecutionEvent) GetHeader() *EventHeader {
-	if m != nil {
-		return m.Header
-	}
-	return nil
-}
-
-func (m *ExecutionEvent) GetEventDataTx() *EventDataTx {
-	if x, ok := m.GetEventData().(*ExecutionEvent_EventDataTx); ok {
-		return x.EventDataTx
-	}
-	return nil
-}
-
-func (m *ExecutionEvent) GetEventDataCall() *EventDataCall {
-	if x, ok := m.GetEventData().(*ExecutionEvent_EventDataCall); ok {
-		return x.EventDataCall
-	}
-	return nil
-}
-
-func (m *ExecutionEvent) GetEventDataLog() *EventDataLog {
-	if x, ok := m.GetEventData().(*ExecutionEvent_EventDataLog); ok {
-		return x.EventDataLog
-	}
-	return nil
-}
-
-// XXX_OneofFuncs is for the internal use of the proto package.
-func (*ExecutionEvent) XXX_OneofFuncs() (func(msg proto.Message, b *proto.Buffer) error, func(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error), func(msg proto.Message) (n int), []interface{}) {
-	return _ExecutionEvent_OneofMarshaler, _ExecutionEvent_OneofUnmarshaler, _ExecutionEvent_OneofSizer, []interface{}{
-		(*ExecutionEvent_EventDataTx)(nil),
-		(*ExecutionEvent_EventDataCall)(nil),
-		(*ExecutionEvent_EventDataLog)(nil),
-	}
-}
-
-func _ExecutionEvent_OneofMarshaler(msg proto.Message, b *proto.Buffer) error {
-	m := msg.(*ExecutionEvent)
-	// EventData
-	switch x := m.EventData.(type) {
-	case *ExecutionEvent_EventDataTx:
-		b.EncodeVarint(2<<3 | proto.WireBytes)
-		if err := b.EncodeMessage(x.EventDataTx); err != nil {
-			return err
-		}
-	case *ExecutionEvent_EventDataCall:
-		b.EncodeVarint(3<<3 | proto.WireBytes)
-		if err := b.EncodeMessage(x.EventDataCall); err != nil {
-			return err
-		}
-	case *ExecutionEvent_EventDataLog:
-		b.EncodeVarint(4<<3 | proto.WireBytes)
-		if err := b.EncodeMessage(x.EventDataLog); err != nil {
-			return err
-		}
-	case nil:
-	default:
-		return fmt.Errorf("ExecutionEvent.EventData has unexpected type %T", x)
-	}
-	return nil
-}
-
-func _ExecutionEvent_OneofUnmarshaler(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error) {
-	m := msg.(*ExecutionEvent)
-	switch tag {
-	case 2: // EventData.EventDataTx
-		if wire != proto.WireBytes {
-			return true, proto.ErrInternalBadWireType
-		}
-		msg := new(EventDataTx)
-		err := b.DecodeMessage(msg)
-		m.EventData = &ExecutionEvent_EventDataTx{msg}
-		return true, err
-	case 3: // EventData.EventDataCall
-		if wire != proto.WireBytes {
-			return true, proto.ErrInternalBadWireType
-		}
-		msg := new(EventDataCall)
-		err := b.DecodeMessage(msg)
-		m.EventData = &ExecutionEvent_EventDataCall{msg}
-		return true, err
-	case 4: // EventData.EventDataLog
-		if wire != proto.WireBytes {
-			return true, proto.ErrInternalBadWireType
-		}
-		msg := new(EventDataLog)
-		err := b.DecodeMessage(msg)
-		m.EventData = &ExecutionEvent_EventDataLog{msg}
-		return true, err
-	default:
-		return false, nil
-	}
-}
-
-func _ExecutionEvent_OneofSizer(msg proto.Message) (n int) {
-	m := msg.(*ExecutionEvent)
-	// EventData
-	switch x := m.EventData.(type) {
-	case *ExecutionEvent_EventDataTx:
-		s := proto.Size(x.EventDataTx)
-		n += 1 // tag and wire
-		n += proto.SizeVarint(uint64(s))
-		n += s
-	case *ExecutionEvent_EventDataCall:
-		s := proto.Size(x.EventDataCall)
-		n += 1 // tag and wire
-		n += proto.SizeVarint(uint64(s))
-		n += s
-	case *ExecutionEvent_EventDataLog:
-		s := proto.Size(x.EventDataLog)
-		n += 1 // tag and wire
-		n += proto.SizeVarint(uint64(s))
-		n += s
-	case nil:
-	default:
-		panic(fmt.Sprintf("proto: unexpected type %T in oneof", x))
-	}
-	return n
-}
-
-type EventDataLog struct {
-	Address              []byte   `protobuf:"bytes,1,opt,name=Address,proto3" json:"Address,omitempty"`
-	Data                 []byte   `protobuf:"bytes,2,opt,name=Data,proto3" json:"Data,omitempty"`
-	Topics               [][]byte `protobuf:"bytes,3,rep,name=Topics,proto3" json:"Topics,omitempty"`
-	XXX_NoUnkeyedLiteral struct{} `json:"-"`
-	XXX_unrecognized     []byte   `json:"-"`
-	XXX_sizecache        int32    `json:"-"`
-}
-
-func (m *EventDataLog) Reset()         { *m = EventDataLog{} }
-func (m *EventDataLog) String() string { return proto.CompactTextString(m) }
-func (*EventDataLog) ProtoMessage()    {}
-func (*EventDataLog) Descriptor() ([]byte, []int) {
-	return fileDescriptor_events_a0e2b84614955cff, []int{11}
-}
-func (m *EventDataLog) XXX_Unmarshal(b []byte) error {
-	return xxx_messageInfo_EventDataLog.Unmarshal(m, b)
-}
-func (m *EventDataLog) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
-	return xxx_messageInfo_EventDataLog.Marshal(b, m, deterministic)
-}
-func (dst *EventDataLog) XXX_Merge(src proto.Message) {
-	xxx_messageInfo_EventDataLog.Merge(dst, src)
-}
-func (m *EventDataLog) XXX_Size() int {
-	return xxx_messageInfo_EventDataLog.Size(m)
-}
-func (m *EventDataLog) XXX_DiscardUnknown() {
-	xxx_messageInfo_EventDataLog.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_EventDataLog proto.InternalMessageInfo
-
-func (m *EventDataLog) GetAddress() []byte {
-	if m != nil {
-		return m.Address
-	}
-	return nil
-}
-
-func (m *EventDataLog) GetData() []byte {
-	if m != nil {
-		return m.Data
-	}
-	return nil
-}
-
-func (m *EventDataLog) GetTopics() [][]byte {
-	if m != nil {
-		return m.Topics
-	}
-	return nil
-}
-
-type EventDataTx struct {
-	Return               []byte            `protobuf:"bytes,1,opt,name=Return,proto3" json:"Return,omitempty"`
-	Exception            *errors.Exception `protobuf:"bytes,2,opt,name=Exception,proto3" json:"Exception,omitempty"`
-	XXX_NoUnkeyedLiteral struct{}          `json:"-"`
-	XXX_unrecognized     []byte            `json:"-"`
-	XXX_sizecache        int32             `json:"-"`
-}
-
-func (m *EventDataTx) Reset()         { *m = EventDataTx{} }
-func (m *EventDataTx) String() string { return proto.CompactTextString(m) }
-func (*EventDataTx) ProtoMessage()    {}
-func (*EventDataTx) Descriptor() ([]byte, []int) {
-	return fileDescriptor_events_a0e2b84614955cff, []int{12}
-}
-func (m *EventDataTx) XXX_Unmarshal(b []byte) error {
-	return xxx_messageInfo_EventDataTx.Unmarshal(m, b)
-}
-func (m *EventDataTx) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
-	return xxx_messageInfo_EventDataTx.Marshal(b, m, deterministic)
-}
-func (dst *EventDataTx) XXX_Merge(src proto.Message) {
-	xxx_messageInfo_EventDataTx.Merge(dst, src)
-}
-func (m *EventDataTx) XXX_Size() int {
-	return xxx_messageInfo_EventDataTx.Size(m)
-}
-func (m *EventDataTx) XXX_DiscardUnknown() {
-	xxx_messageInfo_EventDataTx.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_EventDataTx proto.InternalMessageInfo
-
-func (m *EventDataTx) GetReturn() []byte {
-	if m != nil {
-		return m.Return
-	}
-	return nil
-}
-
-func (m *EventDataTx) GetException() *errors.Exception {
-	if m != nil {
-		return m.Exception
-	}
-	return nil
-}
-
-type EventDataCall struct {
-	CallData             *CallData         `protobuf:"bytes,1,opt,name=CallData,proto3" json:"CallData,omitempty"`
-	Origin               []byte            `protobuf:"bytes,2,opt,name=Origin,proto3" json:"Origin,omitempty"`
-	StackDepth           uint64            `protobuf:"varint,3,opt,name=StackDepth,proto3" json:"StackDepth,omitempty"`
-	Return               []byte            `protobuf:"bytes,4,opt,name=Return,proto3" json:"Return,omitempty"`
-	Exception            *errors.Exception `protobuf:"bytes,5,opt,name=Exception,proto3" json:"Exception,omitempty"`
-	XXX_NoUnkeyedLiteral struct{}          `json:"-"`
-	XXX_unrecognized     []byte            `json:"-"`
-	XXX_sizecache        int32             `json:"-"`
-}
-
-func (m *EventDataCall) Reset()         { *m = EventDataCall{} }
-func (m *EventDataCall) String() string { return proto.CompactTextString(m) }
-func (*EventDataCall) ProtoMessage()    {}
-func (*EventDataCall) Descriptor() ([]byte, []int) {
-	return fileDescriptor_events_a0e2b84614955cff, []int{13}
-}
-func (m *EventDataCall) XXX_Unmarshal(b []byte) error {
-	return xxx_messageInfo_EventDataCall.Unmarshal(m, b)
-}
-func (m *EventDataCall) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
-	return xxx_messageInfo_EventDataCall.Marshal(b, m, deterministic)
-}
-func (dst *EventDataCall) XXX_Merge(src proto.Message) {
-	xxx_messageInfo_EventDataCall.Merge(dst, src)
-}
-func (m *EventDataCall) XXX_Size() int {
-	return xxx_messageInfo_EventDataCall.Size(m)
-}
-func (m *EventDataCall) XXX_DiscardUnknown() {
-	xxx_messageInfo_EventDataCall.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_EventDataCall proto.InternalMessageInfo
-
-func (m *EventDataCall) GetCallData() *CallData {
-	if m != nil {
-		return m.CallData
-	}
-	return nil
-}
-
-func (m *EventDataCall) GetOrigin() []byte {
-	if m != nil {
-		return m.Origin
-	}
-	return nil
-}
-
-func (m *EventDataCall) GetStackDepth() uint64 {
-	if m != nil {
-		return m.StackDepth
-	}
-	return 0
-}
-
-func (m *EventDataCall) GetReturn() []byte {
-	if m != nil {
-		return m.Return
-	}
-	return nil
-}
-
-func (m *EventDataCall) GetException() *errors.Exception {
-	if m != nil {
-		return m.Exception
-	}
-	return nil
-}
-
-type CallData struct {
-	Caller               []byte   `protobuf:"bytes,1,opt,name=Caller,proto3" json:"Caller,omitempty"`
-	Callee               []byte   `protobuf:"bytes,2,opt,name=Callee,proto3" json:"Callee,omitempty"`
-	Data                 []byte   `protobuf:"bytes,3,opt,name=Data,proto3" json:"Data,omitempty"`
-	Value                uint64   `protobuf:"varint,4,opt,name=Value,proto3" json:"Value,omitempty"`
-	Gas                  uint64   `protobuf:"varint,5,opt,name=Gas,proto3" json:"Gas,omitempty"`
-	XXX_NoUnkeyedLiteral struct{} `json:"-"`
-	XXX_unrecognized     []byte   `json:"-"`
-	XXX_sizecache        int32    `json:"-"`
-}
-
-func (m *CallData) Reset()         { *m = CallData{} }
-func (m *CallData) String() string { return proto.CompactTextString(m) }
-func (*CallData) ProtoMessage()    {}
-func (*CallData) Descriptor() ([]byte, []int) {
-	return fileDescriptor_events_a0e2b84614955cff, []int{14}
-}
-func (m *CallData) XXX_Unmarshal(b []byte) error {
-	return xxx_messageInfo_CallData.Unmarshal(m, b)
-}
-func (m *CallData) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
-	return xxx_messageInfo_CallData.Marshal(b, m, deterministic)
-}
-func (dst *CallData) XXX_Merge(src proto.Message) {
-	xxx_messageInfo_CallData.Merge(dst, src)
-}
-func (m *CallData) XXX_Size() int {
-	return xxx_messageInfo_CallData.Size(m)
-}
-func (m *CallData) XXX_DiscardUnknown() {
-	xxx_messageInfo_CallData.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_CallData proto.InternalMessageInfo
-
-func (m *CallData) GetCaller() []byte {
-	if m != nil {
-		return m.Caller
-	}
-	return nil
-}
-
-func (m *CallData) GetCallee() []byte {
-	if m != nil {
-		return m.Callee
-	}
-	return nil
-}
-
-func (m *CallData) GetData() []byte {
-	if m != nil {
-		return m.Data
-	}
-	return nil
-}
-
-func (m *CallData) GetValue() uint64 {
-	if m != nil {
-		return m.Value
-	}
-	return 0
-}
-
-func (m *CallData) GetGas() uint64 {
-	if m != nil {
-		return m.Gas
-	}
-	return 0
-}
-
-func init() {
-	proto.RegisterType((*EventIdParam)(nil), "pbevents.EventIdParam")
-	proto.RegisterType((*SubIdParam)(nil), "pbevents.SubIdParam")
-	proto.RegisterType((*EventUnSub)(nil), "pbevents.EventUnSub")
-	proto.RegisterType((*PollResponse)(nil), "pbevents.PollResponse")
-	proto.RegisterType((*Event)(nil), "pbevents.Event")
-	proto.RegisterType((*GetEventsRequest)(nil), "pbevents.GetEventsRequest")
-	proto.RegisterType((*GetEventsResponse)(nil), "pbevents.GetEventsResponse")
-	proto.RegisterType((*Bound)(nil), "pbevents.Bound")
-	proto.RegisterType((*BlockRange)(nil), "pbevents.BlockRange")
-	proto.RegisterType((*EventHeader)(nil), "pbevents.EventHeader")
-	proto.RegisterType((*ExecutionEvent)(nil), "pbevents.ExecutionEvent")
-	proto.RegisterType((*EventDataLog)(nil), "pbevents.EventDataLog")
-	proto.RegisterType((*EventDataTx)(nil), "pbevents.EventDataTx")
-	proto.RegisterType((*EventDataCall)(nil), "pbevents.EventDataCall")
-	proto.RegisterType((*CallData)(nil), "pbevents.CallData")
-	proto.RegisterEnum("pbevents.Bound_BoundType", Bound_BoundType_name, Bound_BoundType_value)
-}
-
-// Reference imports to suppress errors if they are not otherwise used.
-var _ context.Context
-var _ grpc.ClientConn
-
-// This is a compile-time assertion to ensure that this generated file
-// is compatible with the grpc package it is being compiled against.
-const _ = grpc.SupportPackageIsVersion4
-
-// EventsClient is the client API for Events service.
-//
-// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
-type EventsClient interface {
-	EventPoll(ctx context.Context, in *SubIdParam, opts ...grpc.CallOption) (*PollResponse, error)
-	EventSubscribe(ctx context.Context, in *EventIdParam, opts ...grpc.CallOption) (*SubIdParam, error)
-	EventUnsubscribe(ctx context.Context, in *SubIdParam, opts ...grpc.CallOption) (*EventUnSub, error)
-}
-
-type eventsClient struct {
-	cc *grpc.ClientConn
-}
-
-func NewEventsClient(cc *grpc.ClientConn) EventsClient {
-	return &eventsClient{cc}
-}
-
-func (c *eventsClient) EventPoll(ctx context.Context, in *SubIdParam, opts ...grpc.CallOption) (*PollResponse, error) {
-	out := new(PollResponse)
-	err := c.cc.Invoke(ctx, "/pbevents.Events/EventPoll", in, out, opts...)
-	if err != nil {
-		return nil, err
-	}
-	return out, nil
-}
-
-func (c *eventsClient) EventSubscribe(ctx context.Context, in *EventIdParam, opts ...grpc.CallOption) (*SubIdParam, error) {
-	out := new(SubIdParam)
-	err := c.cc.Invoke(ctx, "/pbevents.Events/EventSubscribe", in, out, opts...)
-	if err != nil {
-		return nil, err
-	}
-	return out, nil
-}
-
-func (c *eventsClient) EventUnsubscribe(ctx context.Context, in *SubIdParam, opts ...grpc.CallOption) (*EventUnSub, error) {
-	out := new(EventUnSub)
-	err := c.cc.Invoke(ctx, "/pbevents.Events/EventUnsubscribe", in, out, opts...)
-	if err != nil {
-		return nil, err
-	}
-	return out, nil
-}
-
-// EventsServer is the server API for Events service.
-type EventsServer interface {
-	EventPoll(context.Context, *SubIdParam) (*PollResponse, error)
-	EventSubscribe(context.Context, *EventIdParam) (*SubIdParam, error)
-	EventUnsubscribe(context.Context, *SubIdParam) (*EventUnSub, error)
-}
-
-func RegisterEventsServer(s *grpc.Server, srv EventsServer) {
-	s.RegisterService(&_Events_serviceDesc, srv)
-}
-
-func _Events_EventPoll_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
-	in := new(SubIdParam)
-	if err := dec(in); err != nil {
-		return nil, err
-	}
-	if interceptor == nil {
-		return srv.(EventsServer).EventPoll(ctx, in)
-	}
-	info := &grpc.UnaryServerInfo{
-		Server:     srv,
-		FullMethod: "/pbevents.Events/EventPoll",
-	}
-	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
-		return srv.(EventsServer).EventPoll(ctx, req.(*SubIdParam))
-	}
-	return interceptor(ctx, in, info, handler)
-}
-
-func _Events_EventSubscribe_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
-	in := new(EventIdParam)
-	if err := dec(in); err != nil {
-		return nil, err
-	}
-	if interceptor == nil {
-		return srv.(EventsServer).EventSubscribe(ctx, in)
-	}
-	info := &grpc.UnaryServerInfo{
-		Server:     srv,
-		FullMethod: "/pbevents.Events/EventSubscribe",
-	}
-	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
-		return srv.(EventsServer).EventSubscribe(ctx, req.(*EventIdParam))
-	}
-	return interceptor(ctx, in, info, handler)
-}
-
-func _Events_EventUnsubscribe_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
-	in := new(SubIdParam)
-	if err := dec(in); err != nil {
-		return nil, err
-	}
-	if interceptor == nil {
-		return srv.(EventsServer).EventUnsubscribe(ctx, in)
-	}
-	info := &grpc.UnaryServerInfo{
-		Server:     srv,
-		FullMethod: "/pbevents.Events/EventUnsubscribe",
-	}
-	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
-		return srv.(EventsServer).EventUnsubscribe(ctx, req.(*SubIdParam))
-	}
-	return interceptor(ctx, in, info, handler)
-}
-
-var _Events_serviceDesc = grpc.ServiceDesc{
-	ServiceName: "pbevents.Events",
-	HandlerType: (*EventsServer)(nil),
-	Methods: []grpc.MethodDesc{
-		{
-			MethodName: "EventPoll",
-			Handler:    _Events_EventPoll_Handler,
-		},
-		{
-			MethodName: "EventSubscribe",
-			Handler:    _Events_EventSubscribe_Handler,
-		},
-		{
-			MethodName: "EventUnsubscribe",
-			Handler:    _Events_EventUnsubscribe_Handler,
-		},
-	},
-	Streams:  []grpc.StreamDesc{},
-	Metadata: "github.com/hyperledger/burrow/execution/events/pbevents/events.proto",
-}
-
-// ExecutionEventsClient is the client API for ExecutionEvents service.
-//
-// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
-type ExecutionEventsClient interface {
-	// GetEvents provides events streaming one block at a time - that is all events emitted in a particular block
-	// are guaranteed to be delivered in each GetEventsResponse
-	GetEvents(ctx context.Context, in *GetEventsRequest, opts ...grpc.CallOption) (ExecutionEvents_GetEventsClient, error)
-}
-
-type executionEventsClient struct {
-	cc *grpc.ClientConn
-}
-
-func NewExecutionEventsClient(cc *grpc.ClientConn) ExecutionEventsClient {
-	return &executionEventsClient{cc}
-}
-
-func (c *executionEventsClient) GetEvents(ctx context.Context, in *GetEventsRequest, opts ...grpc.CallOption) (ExecutionEvents_GetEventsClient, error) {
-	stream, err := c.cc.NewStream(ctx, &_ExecutionEvents_serviceDesc.Streams[0], "/pbevents.ExecutionEvents/GetEvents", opts...)
-	if err != nil {
-		return nil, err
-	}
-	x := &executionEventsGetEventsClient{stream}
-	if err := x.ClientStream.SendMsg(in); err != nil {
-		return nil, err
-	}
-	if err := x.ClientStream.CloseSend(); err != nil {
-		return nil, err
-	}
-	return x, nil
-}
-
-type ExecutionEvents_GetEventsClient interface {
-	Recv() (*GetEventsResponse, error)
-	grpc.ClientStream
-}
-
-type executionEventsGetEventsClient struct {
-	grpc.ClientStream
-}
-
-func (x *executionEventsGetEventsClient) Recv() (*GetEventsResponse, error) {
-	m := new(GetEventsResponse)
-	if err := x.ClientStream.RecvMsg(m); err != nil {
-		return nil, err
-	}
-	return m, nil
-}
-
-// ExecutionEventsServer is the server API for ExecutionEvents service.
-type ExecutionEventsServer interface {
-	// GetEvents provides events streaming one block at a time - that is all events emitted in a particular block
-	// are guaranteed to be delivered in each GetEventsResponse
-	GetEvents(*GetEventsRequest, ExecutionEvents_GetEventsServer) error
-}
-
-func RegisterExecutionEventsServer(s *grpc.Server, srv ExecutionEventsServer) {
-	s.RegisterService(&_ExecutionEvents_serviceDesc, srv)
-}
-
-func _ExecutionEvents_GetEvents_Handler(srv interface{}, stream grpc.ServerStream) error {
-	m := new(GetEventsRequest)
-	if err := stream.RecvMsg(m); err != nil {
-		return err
-	}
-	return srv.(ExecutionEventsServer).GetEvents(m, &executionEventsGetEventsServer{stream})
-}
-
-type ExecutionEvents_GetEventsServer interface {
-	Send(*GetEventsResponse) error
-	grpc.ServerStream
-}
-
-type executionEventsGetEventsServer struct {
-	grpc.ServerStream
-}
-
-func (x *executionEventsGetEventsServer) Send(m *GetEventsResponse) error {
-	return x.ServerStream.SendMsg(m)
-}
-
-var _ExecutionEvents_serviceDesc = grpc.ServiceDesc{
-	ServiceName: "pbevents.ExecutionEvents",
-	HandlerType: (*ExecutionEventsServer)(nil),
-	Methods:     []grpc.MethodDesc{},
-	Streams: []grpc.StreamDesc{
-		{
-			StreamName:    "GetEvents",
-			Handler:       _ExecutionEvents_GetEvents_Handler,
-			ServerStreams: true,
-		},
-	},
-	Metadata: "github.com/hyperledger/burrow/execution/events/pbevents/events.proto",
-}
-
-func init() {
-	proto.RegisterFile("github.com/hyperledger/burrow/execution/events/pbevents/events.proto", fileDescriptor_events_a0e2b84614955cff)
-}
-
-var fileDescriptor_events_a0e2b84614955cff = []byte{
-	// 907 bytes of a gzipped FileDescriptorProto
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x56, 0xdd, 0x6e, 0xdc, 0x44,
-	0x14, 0x5e, 0x67, 0x7f, 0x1a, 0x9f, 0x5d, 0x12, 0x77, 0x08, 0xc5, 0x04, 0x84, 0x82, 0x05, 0x22,
-	0x37, 0xdd, 0xad, 0x0c, 0x52, 0x15, 0x81, 0x8a, 0x76, 0x89, 0xdb, 0x4d, 0xb5, 0x34, 0x65, 0xec,
-	0x46, 0x82, 0x0b, 0x24, 0x7b, 0x3d, 0xda, 0xb5, 0xea, 0xd8, 0x66, 0xc6, 0x2e, 0x9b, 0x17, 0xe0,
-	0x19, 0xb8, 0xe0, 0x8e, 0x17, 0x41, 0xe2, 0xc5, 0xd0, 0xfc, 0xf8, 0x97, 0xad, 0x54, 0x71, 0x13,
-	0xcf, 0x37, 0xe7, 0x9b, 0x6f, 0xcf, 0xf9, 0xce, 0xfc, 0x04, 0x2e, 0x37, 0x51, 0xbe, 0x2d, 0x82,
-	0xe9, 0x3a, 0xbd, 0x9d, 0x6d, 0xef, 0x32, 0x42, 0x63, 0x12, 0x6e, 0x08, 0x9d, 0x05, 0x05, 0xa5,
-	0xe9, 0x6f, 0x33, 0xb2, 0x23, 0xeb, 0x22, 0x8f, 0xd2, 0x64, 0x46, 0xde, 0x90, 0x24, 0x67, 0xb3,
-	0x2c, 0x50, 0x03, 0xf9, 0x99, 0x66, 0x34, 0xcd, 0x53, 0x74, 0x58, 0x4e, 0x9f, 0x7e, 0xf3, 0xce,
-	0x7a, 0x94, 0xa6, 0x94, 0xa9, 0x8f, 0x94, 0xb1, 0xce, 0x61, 0xe2, 0x70, 0x99, 0xab, 0xf0, 0xa5,
-	0x4f, 0xfd, 0x5b, 0x64, 0xc2, 0x3d, 0x22, 0xb1, 0xa9, 0x9d, 0x69, 0xe7, 0x3a, 0x2e, 0xa1, 0x65,
-	0x01, 0xb8, 0x45, 0x50, 0xf2, 0x4e, 0x60, 0xc8, 0x38, 0x52, 0x2c, 0x09, 0xac, 0xcf, 0x01, 0x84,
-	0xda, 0xab, 0xc4, 0x2d, 0x02, 0xf4, 0x00, 0x46, 0x94, 0xb0, 0x22, 0xce, 0x05, 0xe9, 0x10, 0x2b,
-	0x64, 0x3d, 0x86, 0xc9, 0xcb, 0x34, 0x8e, 0x31, 0x61, 0x59, 0x9a, 0x30, 0x82, 0xbe, 0x84, 0x91,
-	0x2c, 0xc5, 0xd4, 0xce, 0xfa, 0xe7, 0x63, 0xfb, 0x78, 0x5a, 0xd6, 0x36, 0x15, 0x6a, 0x58, 0x85,
-	0xad, 0x3f, 0x35, 0x18, 0x8a, 0x19, 0x84, 0x60, 0xf0, 0xc2, 0xbf, 0x25, 0xea, 0xd7, 0xc5, 0x18,
-	0x2d, 0xe0, 0xc8, 0x29, 0x6b, 0x15, 0x2c, 0xf3, 0xe0, 0x4c, 0x3b, 0x1f, 0xdb, 0x66, 0x43, 0xae,
-	0x15, 0x5f, 0xf6, 0x70, 0x67, 0x05, 0xb2, 0xe1, 0x7d, 0x8f, 0x24, 0x21, 0xa1, 0xb7, 0x51, 0x92,
-	0x8b, 0xa9, 0xe7, 0xee, 0xf5, 0x0b, 0xb3, 0xcf, 0x7f, 0x66, 0xd9, 0xc3, 0xfb, 0x82, 0x8b, 0x7b,
-	0x2a, 0x29, 0xeb, 0x17, 0x30, 0x9e, 0x11, 0x19, 0x60, 0x98, 0xfc, 0x5a, 0x10, 0x96, 0xa3, 0xaf,
-	0x01, 0x16, 0x71, 0xba, 0x7e, 0x8d, 0xfd, 0x64, 0x23, 0xd3, 0x1d, 0xdb, 0x27, 0x75, 0x42, 0x75,
-	0x0c, 0x37, 0x78, 0xdc, 0xdd, 0x1f, 0x0b, 0x42, 0xef, 0x44, 0x05, 0x3a, 0x96, 0xc0, 0x72, 0xe0,
-	0x7e, 0x43, 0x5f, 0x99, 0xf7, 0xa8, 0x63, 0xde, 0x5b, 0xab, 0xad, 0x5c, 0xfc, 0x43, 0x83, 0xe1,
-	0x22, 0x2d, 0x92, 0x10, 0x3d, 0x84, 0x81, 0x77, 0x97, 0xc9, 0xb4, 0x8e, 0xec, 0x8f, 0x1a, 0x69,
-	0xf1, 0xb0, 0xfc, 0xcb, 0x09, 0x58, 0xd0, 0x78, 0x56, 0x57, 0x49, 0x48, 0x76, 0x22, 0xab, 0x01,
-	0x96, 0xc0, 0x7a, 0x0e, 0x7a, 0x45, 0x44, 0x13, 0x38, 0x9c, 0x2f, 0xdc, 0xeb, 0xd5, 0x2b, 0xcf,
-	0x31, 0x7a, 0x1c, 0x61, 0x67, 0x35, 0xf7, 0xae, 0x6e, 0x1c, 0x43, 0x43, 0x3a, 0x0c, 0x9f, 0x5e,
-	0x61, 0xd7, 0x33, 0x0e, 0x10, 0xc0, 0x68, 0x35, 0xf7, 0x1c, 0xd7, 0x33, 0xfa, 0x7c, 0xec, 0x7a,
-	0xd8, 0x99, 0xff, 0x60, 0x0c, 0xac, 0x9b, 0xa6, 0x5b, 0xe8, 0x0b, 0x18, 0xba, 0xb9, 0x4f, 0x73,
-	0x65, 0xdb, 0x71, 0x27, 0x3f, 0x2c, 0xa3, 0xe8, 0x33, 0xe8, 0x3b, 0x49, 0xa8, 0x9a, 0xfd, 0x1f,
-	0x12, 0x8f, 0x59, 0x7f, 0x69, 0x30, 0x96, 0x2d, 0x27, 0x7e, 0x48, 0x28, 0xdf, 0x99, 0xde, 0xae,
-	0x2a, 0x5d, 0xc7, 0x0a, 0xc9, 0xf9, 0xa5, 0xcf, 0xb6, 0x42, 0x6d, 0x82, 0x15, 0x42, 0x9f, 0x80,
-	0x2e, 0x96, 0x8b, 0x25, 0x62, 0x33, 0xe0, 0x7a, 0x82, 0x9f, 0x19, 0x79, 0x86, 0x2e, 0xcd, 0x81,
-	0x3c, 0x33, 0x0a, 0x72, 0xbd, 0x25, 0x89, 0x36, 0xdb, 0xdc, 0x1c, 0x0a, 0xcb, 0x14, 0xaa, 0x9d,
-	0x1c, 0x35, 0x9d, 0xfc, 0xfd, 0xa0, 0xbb, 0x83, 0xd1, 0x43, 0x2e, 0xc0, 0x53, 0x56, 0x1e, 0x7c,
-	0xd0, 0x39, 0x1a, 0x32, 0x88, 0x15, 0x09, 0x5d, 0xa8, 0x32, 0x2f, 0xfd, 0xdc, 0xf7, 0x76, 0xca,
-	0x92, 0xee, 0x1a, 0x19, 0x5c, 0xf6, 0x70, 0x93, 0x8b, 0xbe, 0x83, 0xf7, 0x2a, 0xf8, 0xbd, 0x1f,
-	0xc7, 0xa2, 0xcc, 0xb1, 0xfd, 0xe1, 0x9e, 0xc5, 0x3c, 0xbc, 0xec, 0xe1, 0x36, 0x1f, 0x7d, 0xab,
-	0x6e, 0x12, 0x3e, 0xb1, 0x4a, 0x37, 0xc2, 0x8a, 0xb1, 0xfd, 0x60, 0xcf, 0xfa, 0x55, 0xba, 0x59,
-	0xf6, 0x70, 0x8b, 0xbd, 0x18, 0x2b, 0x87, 0x39, 0xb6, 0xbc, 0xb6, 0x14, 0x37, 0x78, 0x1e, 0x86,
-	0x94, 0x30, 0x26, 0x6c, 0x98, 0xe0, 0x12, 0xf2, 0x7b, 0x80, 0x93, 0x54, 0xbb, 0xc4, 0x58, 0x34,
-	0x31, 0xcd, 0xa2, 0x35, 0x33, 0xfb, 0x67, 0x7d, 0xd1, 0x44, 0x81, 0xac, 0x9b, 0x96, 0x39, 0x9c,
-	0x86, 0x49, 0x5e, 0xd0, 0x44, 0x69, 0x2a, 0x84, 0x66, 0xa0, 0x3b, 0xbb, 0x35, 0xc9, 0x78, 0x13,
-	0x94, 0x83, 0xf7, 0xa7, 0xea, 0xce, 0xac, 0x02, 0xb8, 0xe6, 0x58, 0x7f, 0x6b, 0x1d, 0xeb, 0xd0,
-	0x14, 0x0e, 0xf9, 0x57, 0x64, 0x26, 0xfb, 0x86, 0x6a, 0x1b, 0xca, 0x08, 0xae, 0x38, 0x3c, 0x95,
-	0x6b, 0x1a, 0x6d, 0xa2, 0xa4, 0xdc, 0x76, 0x12, 0xa1, 0x4f, 0x01, 0xdc, 0xdc, 0x5f, 0xbf, 0xbe,
-	0x24, 0x59, 0xbe, 0x15, 0x0d, 0x19, 0xe0, 0xc6, 0x4c, 0xa3, 0x84, 0xc1, 0xdb, 0x4b, 0x18, 0xbe,
-	0x43, 0x09, 0x6f, 0xa0, 0x95, 0x0c, 0x1f, 0xab, 0x2d, 0x37, 0xc1, 0x0a, 0x55, 0xf3, 0xa4, 0x4c,
-	0x52, 0xa2, 0xaa, 0x05, 0xfd, 0x46, 0x0b, 0x4e, 0x60, 0x78, 0xe3, 0xc7, 0x05, 0x11, 0x79, 0x0d,
-	0xb0, 0x04, 0xc8, 0x80, 0xfe, 0x33, 0x9f, 0xa9, 0xa3, 0xc0, 0x87, 0xf6, 0x3f, 0x1a, 0x8c, 0xe4,
-	0x7d, 0x86, 0x2e, 0xd4, 0x06, 0xe0, 0x2f, 0x03, 0x6a, 0xdc, 0x90, 0xf5, 0x9b, 0x73, 0xda, 0xd8,
-	0x4b, 0xad, 0xf7, 0xe3, 0x09, 0x1c, 0x89, 0xa5, 0x6e, 0x11, 0xb0, 0x35, 0x8d, 0x02, 0x82, 0xba,
-	0xbb, 0xae, 0x54, 0xd8, 0xab, 0x8b, 0x9e, 0x80, 0xa1, 0x5e, 0x2d, 0x56, 0x29, 0xec, 0xcf, 0xe0,
-	0xa4, 0xa3, 0x2b, 0xde, 0x39, 0xfb, 0x27, 0x38, 0x6e, 0x1f, 0x5b, 0x86, 0x9e, 0x82, 0x5e, 0x5d,
-	0xd5, 0xe8, 0xb4, 0x5e, 0xd5, 0x7d, 0x1f, 0x4e, 0x3f, 0xde, 0x1b, 0x93, 0x85, 0x3d, 0xd2, 0x16,
-	0x17, 0x3f, 0x3f, 0xfe, 0x9f, 0xff, 0x2d, 0x04, 0x23, 0xf1, 0xc0, 0x7f, 0xf5, 0x6f, 0x00, 0x00,
-	0x00, 0xff, 0xff, 0x6f, 0x28, 0x40, 0xd9, 0x6f, 0x08, 0x00, 0x00,
-}
diff --git a/execution/events/pbevents/events.proto b/execution/events/pbevents/events.proto
deleted file mode 100644
index 67cb46c39152e9ba95ab05d4539c55b80cbf803e..0000000000000000000000000000000000000000
--- a/execution/events/pbevents/events.proto
+++ /dev/null
@@ -1,177 +0,0 @@
-syntax = 'proto3';
-
-option go_package = "github.com/hyperledger/burrow/execution/events/pbevents";
-
-import "github.com/hyperledger/burrow/execution/errors/errors.proto";
-
-package pbevents;
-
-//--------------------------------------------------
-// Event Service Definition
-service Events {
-    rpc EventPoll (SubIdParam) returns (PollResponse);
-    rpc EventSubscribe (EventIdParam) returns (SubIdParam);
-    rpc EventUnsubscribe (SubIdParam) returns (EventUnSub);
-}
-
-// Params
-message EventIdParam {
-    string eventId = 1;
-}
-
-message SubIdParam {
-    string subId = 1;
-}
-
-// Results
-message EventUnSub {
-    bool result = 1;
-}
-
-message PollResponse {
-    repeated Event events = 1;
-}
-
-message Event {
-    string Name = 1;
-    oneof Event {
-        // Burrow's execution domain events generated deterministically from transactions
-        ExecutionEvent ExecutionEvent = 2;
-        // Operational events from tendermint serialised into their standard JSON representation
-        string TendermintEventJSON = 3;
-    }
-}
-
-//--------------------------------------------------
-// Execution events
-service ExecutionEvents {
-    // GetEvents provides events streaming one block at a time - that is all events emitted in a particular block
-    // are guaranteed to be delivered in each GetEventsResponse
-    rpc GetEvents (GetEventsRequest) returns (stream GetEventsResponse);
-}
-
-message GetEventsRequest {
-    BlockRange BlockRange = 1;
-    // Specify a query on which to match the tags of events.
-    // Tag        | Match type | Values
-    // -----------------------------------------
-    //   All events
-    // -----------------------------------------
-    // TxType       | String     | "UnknownTx", "SendTx", "CallTx", "NameTx", "BondTx", "UnbondTx", "PermissionsTx", "GovernanceTx"
-    // TxHash       | String     | bytes
-    // EventType    | String     | "CallEvent", "LogEvent", "AccountInputEvent", "AccountOutputEvent"
-    // EventID      | String     | string
-    // Height       | Integer    | uint64
-    // Index        | Integer    | uint64
-    // MessageType  | String     | Go type name
-    // -----------------------------------------
-    //   Log event
-    // -----------------------------------------
-    // Address      | String     | Address (hex)
-    // Log<0-4>     | String     | Word256 (hex)
-    // Log<0-4>Text | String     | string (trimmed)
-    // -----------------------------------------
-    //   Call event
-    // -----------------------------------------
-    // Origin       | String     | Address (hex)
-    // Callee       | String     | Address (hex)
-    // Caller       | String     | Address (hex)
-    // Value        | Integer    | uint64
-    // Gas          | Integer    | uint64
-    // StackDepth   | Integer    | uint64
-    // Exception    | String     | string
-    // -----------------------------------------
-    //   Tx event (input/output)
-    // -----------------------------------------
-    // Exception  | String     | string
-    //
-    // For example:
-    // EventType = 'LogEvent' AND EventID CONTAINS 'bar' AND TxHash = '020304' AND Height >= 34 AND Index < 3 AND Address = 'DEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEF'
-    string Query = 2;
-}
-
-message GetEventsResponse {
-    repeated ExecutionEvent events = 1;
-}
-
-message Bound {
-    BoundType Type = 1;
-    uint64 Index = 2;
-    enum BoundType {
-        // Index is absolute index of object in collection
-        ABSOLUTE = 0;
-        // Index is an offset relative to another bound determined by context
-        RELATIVE = 1;
-        // The first block
-        FIRST = 2;
-        // Ignore provided index and evaluate to latest index
-        LATEST = 3;
-        // Ignore provided index and stream new objects as they are generated
-        STREAM = 4;
-    }
-}
-
-// An inclusive range of blocks to include in output
-message BlockRange {
-    // Bounds can be set to:
-    // absolute: block height
-    // relative: block height counting back from latest
-    // latest: latest block when call is processed
-    // stream: for End keep sending new blocks, for start same as latest
-    Bound Start = 1;
-    Bound End = 2;
-}
-
-//--------------------------------------------------
-// Event types
-
-message EventHeader {
-    // Transaction type
-    string TxType = 1;
-    // The hash of the transaction that caused this event to be generated
-    bytes TxHash = 2;
-    // The type of event
-    string EventType = 3;
-    // EventID published with event
-    string EventID = 4;
-    // The block height at which this event was emitted
-    uint64 Height = 5;
-    // The index amongst all other events in the block of this event
-    uint64 Index = 6;
-}
-
-message ExecutionEvent {
-    EventHeader Header = 1;
-    oneof EventData {
-        EventDataTx EventDataTx = 2;
-        EventDataCall EventDataCall = 3;
-        EventDataLog EventDataLog = 4;
-    }
-}
-
-message EventDataLog {
-    bytes Address = 1;
-    bytes Data = 2;
-    repeated bytes Topics = 3;
-}
-
-message EventDataTx {
-    bytes Return = 1;
-    errors.Exception Exception = 2;
-}
-
-message EventDataCall {
-    CallData CallData = 1;
-    bytes Origin = 2;
-    uint64 StackDepth = 3;
-    bytes Return = 4;
-    errors.Exception Exception = 5;
-}
-
-message CallData {
-    bytes Caller = 1;
-    bytes Callee = 2;
-    bytes Data = 3;
-    uint64 Value = 4;
-    uint64 Gas = 5;
-}
diff --git a/execution/events/tx.go b/execution/events/tx.go
deleted file mode 100644
index c1da5c62d4856d96e6d6fbdd5c1feff9d58dbc67..0000000000000000000000000000000000000000
--- a/execution/events/tx.go
+++ /dev/null
@@ -1,134 +0,0 @@
-package events
-
-import (
-	"context"
-	"fmt"
-
-	"github.com/hyperledger/burrow/binary"
-	"github.com/hyperledger/burrow/crypto"
-	"github.com/hyperledger/burrow/event"
-	"github.com/hyperledger/burrow/event/query"
-	"github.com/hyperledger/burrow/execution/errors"
-	ptypes "github.com/hyperledger/burrow/permission/types"
-	"github.com/hyperledger/burrow/txs"
-	"github.com/hyperledger/burrow/txs/payload"
-	"github.com/tmthrgd/go-hex"
-)
-
-func EventStringAccountInput(addr crypto.Address) string  { return fmt.Sprintf("Acc/%s/Input", addr) }
-func EventStringAccountOutput(addr crypto.Address) string { return fmt.Sprintf("Acc/%s/Output", addr) }
-func EventStringNameReg(name string) string               { return fmt.Sprintf("NameReg/%s", name) }
-func EventStringPermissions(perm ptypes.PermFlag) string  { return fmt.Sprintf("Permissions/%v", perm) }
-func EventStringBond() string                             { return "Bond" }
-func EventStringUnbond() string                           { return "Unbond" }
-
-// All txs fire EventDataTx, but only CallTx might have Return or Exception
-type EventDataTx struct {
-	Tx        *txs.Tx
-	Return    binary.HexBytes
-	Exception *errors.Exception
-}
-
-// For re-use
-var sendTxQuery = query.NewBuilder().
-	AndEquals(event.TxTypeKey, payload.TypeSend.String())
-
-var callTxQuery = query.NewBuilder().
-	AndEquals(event.TxTypeKey, payload.TypeCall.String())
-
-// Publish/Subscribe
-func PublishAccountInput(publisher event.Publisher, height uint64, address crypto.Address, tx *txs.Tx, ret []byte,
-	exception *errors.Exception) error {
-
-	ev := txEvent(height, TypeAccountInput, EventStringAccountInput(address), tx, ret, exception)
-	return publisher.Publish(context.Background(), ev, event.CombinedTags{ev.Tags(), event.TagMap{
-		event.AddressKey: address,
-	}})
-}
-
-func PublishAccountOutput(publisher event.Publisher, height uint64, address crypto.Address, tx *txs.Tx, ret []byte,
-	exception *errors.Exception) error {
-
-	ev := txEvent(height, TypeAccountOutput, EventStringAccountOutput(address), tx, ret, exception)
-	return publisher.Publish(context.Background(), ev, event.CombinedTags{ev.Tags(), event.TagMap{
-		event.AddressKey: address,
-	}})
-}
-
-func PublishNameReg(publisher event.Publisher, height uint64, tx *txs.Tx) error {
-	nameTx, ok := tx.Payload.(*payload.NameTx)
-	if !ok {
-		return fmt.Errorf("Tx payload must be NameTx to PublishNameReg")
-	}
-	ev := txEvent(height, TypeAccountInput, EventStringNameReg(nameTx.Name), tx, nil, nil)
-	return publisher.Publish(context.Background(), ev, event.CombinedTags{ev.Tags(), event.TagMap{
-		event.NameKey: nameTx.Name,
-	}})
-}
-
-func PublishPermissions(publisher event.Publisher, height uint64, tx *txs.Tx) error {
-	permTx, ok := tx.Payload.(*payload.PermissionsTx)
-	if !ok {
-		return fmt.Errorf("Tx payload must be PermissionsTx to PublishPermissions")
-	}
-	ev := txEvent(height, TypeAccountInput, EventStringPermissions(permTx.PermArgs.PermFlag), tx, nil, nil)
-	return publisher.Publish(context.Background(), ev, event.CombinedTags{ev.Tags(), event.TagMap{
-		event.PermissionKey: permTx.PermArgs.PermFlag.String(),
-	}})
-}
-
-func SubscribeAccountOutputSendTx(ctx context.Context, subscribable event.Subscribable, subscriber string,
-	address crypto.Address, txHash []byte, ch chan<- *payload.SendTx) error {
-
-	qry := sendTxQuery.And(event.QueryForEventID(EventStringAccountOutput(address))).
-		AndEquals(event.TxHashKey, hex.EncodeUpperToString(txHash))
-
-	return event.SubscribeCallback(ctx, subscribable, subscriber, qry, func(message interface{}) (stop bool) {
-		if ev, ok := message.(*Event); ok && ev.Tx != nil {
-			if sendTx, ok := ev.Tx.Tx.Payload.(*payload.SendTx); ok {
-				ch <- sendTx
-			}
-		}
-		return
-	})
-}
-
-func txEvent(height uint64, eventType Type, eventID string, tx *txs.Tx, ret []byte, exception *errors.Exception) *Event {
-	return &Event{
-		Header: &Header{
-			TxType:    tx.Type(),
-			TxHash:    tx.Hash(),
-			EventType: eventType,
-			EventID:   eventID,
-			Height:    height,
-		},
-		Tx: &EventDataTx{
-			Tx:        tx,
-			Return:    ret,
-			Exception: exception,
-		},
-	}
-}
-
-// Tags
-
-var txTagKeys = []string{event.ExceptionKey}
-
-func (tx *EventDataTx) Get(key string) (string, bool) {
-	var value interface{}
-	switch key {
-	case event.ExceptionKey:
-		value = tx.Exception
-	default:
-		return "", false
-	}
-	return query.StringFromValue(value), true
-}
-
-func (tx *EventDataTx) Len() int {
-	return len(txTagKeys)
-}
-
-func (tx *EventDataTx) Keys() []string {
-	return txTagKeys
-}
diff --git a/execution/events/type.go b/execution/events/type.go
deleted file mode 100644
index 8fe49f60df52439f06d14a9b12473601a9133119..0000000000000000000000000000000000000000
--- a/execution/events/type.go
+++ /dev/null
@@ -1,47 +0,0 @@
-package events
-
-type Type int8
-
-// Execution event types
-const (
-	TypeCall          = Type(0x00)
-	TypeLog           = Type(0x01)
-	TypeAccountInput  = Type(0x02)
-	TypeAccountOutput = Type(0x03)
-)
-
-var nameFromType = map[Type]string{
-	TypeCall:          "CallEvent",
-	TypeLog:           "LogEvent",
-	TypeAccountInput:  "AccountInputEvent",
-	TypeAccountOutput: "AccountOutputEvent",
-}
-
-var typeFromName = make(map[string]Type)
-
-func init() {
-	for t, n := range nameFromType {
-		typeFromName[n] = t
-	}
-}
-
-func EventTypeFromString(name string) Type {
-	return typeFromName[name]
-}
-
-func (typ Type) String() string {
-	name, ok := nameFromType[typ]
-	if ok {
-		return name
-	}
-	return "UnknownTx"
-}
-
-func (typ Type) MarshalText() ([]byte, error) {
-	return []byte(typ.String()), nil
-}
-
-func (typ *Type) UnmarshalText(data []byte) error {
-	*typ = EventTypeFromString(string(data))
-	return nil
-}
diff --git a/execution/evm/accounts.go b/execution/evm/accounts.go
index 1bd61df33a38a91f98fa338e4023c163c71e5053..65c578e375a9485f05d3976484e414240954fe88 100644
--- a/execution/evm/accounts.go
+++ b/execution/evm/accounts.go
@@ -1,16 +1,16 @@
 package evm
 
 import (
-	acm "github.com/hyperledger/burrow/account"
+	"github.com/hyperledger/burrow/acm"
 	"github.com/hyperledger/burrow/crypto"
 	"github.com/hyperledger/burrow/logging"
-	ptypes "github.com/hyperledger/burrow/permission/types"
+	"github.com/hyperledger/burrow/permission"
 )
 
 // Create a new account from a parent 'creator' account. The creator account will have its
 // sequence number incremented
-func DeriveNewAccount(creator acm.MutableAccount, permissions ptypes.AccountPermissions,
-	logger *logging.Logger) acm.MutableAccount {
+func DeriveNewAccount(creator *acm.MutableAccount, permissions permission.AccountPermissions,
+	logger *logging.Logger) *acm.MutableAccount {
 	// Generate an address
 	sequence := creator.Sequence()
 	logger.TraceMsg("Incrementing sequence number in DeriveNewAccount()",
diff --git a/execution/evm/asm/opcodes.go b/execution/evm/asm/opcodes.go
index 3017c213862a4dbbe7baa498115a73b56126c264..4467b7aebc2ba02adc5d26314d70c2593438b9c9 100644
--- a/execution/evm/asm/opcodes.go
+++ b/execution/evm/asm/opcodes.go
@@ -368,7 +368,7 @@ func (o OpCode) String() string {
 func (o OpCode) Name() string {
 	str := opCodeNames[o]
 	if len(str) == 0 {
-		return fmt.Sprintf("Missing opcode 0x%x", int(o))
+		return fmt.Sprintf("Non-opcode 0x%x", int(o))
 	}
 
 	return str
diff --git a/execution/evm/fake_app_state.go b/execution/evm/fake_app_state.go
index 8b1bd9ac473eedcee79134b1a33a10016bc7de09..eb2dbd3acefb11eef58bb3b9dff11359202a4954 100644
--- a/execution/evm/fake_app_state.go
+++ b/execution/evm/fake_app_state.go
@@ -19,8 +19,8 @@ import (
 
 	"bytes"
 
-	acm "github.com/hyperledger/burrow/account"
-	"github.com/hyperledger/burrow/account/state"
+	"github.com/hyperledger/burrow/acm"
+	"github.com/hyperledger/burrow/acm/state"
 	. "github.com/hyperledger/burrow/binary"
 	"github.com/hyperledger/burrow/crypto"
 )
diff --git a/execution/evm/log_event_test.go b/execution/evm/log_event_test.go
index 7789c3b96824859001cd3d5573b0fd209ff6364e..2d2ba41ef5fcfd458639f79690f8ff648a47df6f 100644
--- a/execution/evm/log_event_test.go
+++ b/execution/evm/log_event_test.go
@@ -15,20 +15,17 @@
 package evm
 
 import (
+	"testing"
+
 	"bytes"
-	"context"
 	"reflect"
-	"testing"
-	"time"
 
-	acm "github.com/hyperledger/burrow/account"
-	"github.com/hyperledger/burrow/account/state"
+	"github.com/hyperledger/burrow/acm"
+	"github.com/hyperledger/burrow/acm/state"
 	. "github.com/hyperledger/burrow/binary"
 	"github.com/hyperledger/burrow/crypto"
-	"github.com/hyperledger/burrow/event"
-	"github.com/hyperledger/burrow/execution/events"
 	. "github.com/hyperledger/burrow/execution/evm/asm"
-	"github.com/hyperledger/burrow/logging"
+	"github.com/hyperledger/burrow/execution/exec"
 	"github.com/stretchr/testify/require"
 )
 
@@ -56,13 +53,8 @@ func TestLog4(t *testing.T) {
 
 	ourVm := NewVM(newParams(), crypto.ZeroAddress, nil, logger)
 
-	emitter := event.NewEmitter(logging.NewNoopLogger())
-
-	ch := make(chan *events.EventDataLog)
-
-	require.NoError(t, events.SubscribeLogEvent(context.Background(), emitter, "test", account2.Address(), ch))
-
-	ourVm.SetPublisher(emitter)
+	txe := new(exec.TxExecution)
+	ourVm.SetEventSink(txe)
 
 	var gas uint64 = 100000
 
@@ -87,18 +79,20 @@ func TestLog4(t *testing.T) {
 
 	_, err := ourVm.Call(cache, account1, account2, code, []byte{}, 0, &gas)
 	require.NoError(t, err)
-	select {
-	case <-time.After(5 * time.Second):
-		t.Fatalf("timedout waiting for EventDataLog")
-	case eventDataLog := <-ch:
-		if !reflect.DeepEqual(eventDataLog.Topics, expectedTopics) {
-			t.Errorf("Event topics are wrong. Got: %v. Expected: %v", eventDataLog.Topics, expectedTopics)
-		}
-		if !bytes.Equal(eventDataLog.Data, expectedData) {
-			t.Errorf("Event data is wrong. Got: %s. Expected: %s", eventDataLog.Data, expectedData)
-		}
-		if eventDataLog.Height != expectedHeight {
-			t.Errorf("Event block height is wrong. Got: %d. Expected: %d", eventDataLog.Height, expectedHeight)
+
+	for _, ev := range txe.Events {
+		if ev.Log != nil {
+			if !reflect.DeepEqual(ev.Log.Topics, expectedTopics) {
+				t.Errorf("Event topics are wrong. Got: %v. Expected: %v", ev.Log.Topics, expectedTopics)
+			}
+			if !bytes.Equal(ev.Log.Data, expectedData) {
+				t.Errorf("Event data is wrong. Got: %s. Expected: %s", ev.Log.Data, expectedData)
+			}
+			if ev.Header.Height != expectedHeight {
+				t.Errorf("Event block height is wrong. Got: %d. Expected: %d", ev.Header.Height, expectedHeight)
+			}
+			return
 		}
 	}
+	t.Fatalf("Did not see LogEvent")
 }
diff --git a/execution/evm/native.go b/execution/evm/native.go
index c4577ea901995f82eeb8a5577825c70ad5cb18ec..74f072aab77370c7e9f4865f91a154074a2d3fda 100644
--- a/execution/evm/native.go
+++ b/execution/evm/native.go
@@ -17,8 +17,8 @@ package evm
 import (
 	"crypto/sha256"
 
-	acm "github.com/hyperledger/burrow/account"
-	"github.com/hyperledger/burrow/account/state"
+	"github.com/hyperledger/burrow/acm"
+	"github.com/hyperledger/burrow/acm/state"
 	. "github.com/hyperledger/burrow/binary"
 	"github.com/hyperledger/burrow/crypto"
 	"github.com/hyperledger/burrow/execution/errors"
diff --git a/execution/evm/snative.go b/execution/evm/snative.go
index 234cfb1a547b18c4882a3df4c7f748daf6de77a9..06254915bdccdf5a4ee94fa7ff814cf24ae487ce 100644
--- a/execution/evm/snative.go
+++ b/execution/evm/snative.go
@@ -19,8 +19,8 @@ import (
 
 	"strings"
 
-	acm "github.com/hyperledger/burrow/account"
-	"github.com/hyperledger/burrow/account/state"
+	"github.com/hyperledger/burrow/acm"
+	"github.com/hyperledger/burrow/acm/state"
 	. "github.com/hyperledger/burrow/binary"
 	"github.com/hyperledger/burrow/crypto"
 	"github.com/hyperledger/burrow/execution/errors"
@@ -28,7 +28,7 @@ import (
 	"github.com/hyperledger/burrow/execution/evm/sha3"
 	"github.com/hyperledger/burrow/logging"
 	"github.com/hyperledger/burrow/logging/structure"
-	ptypes "github.com/hyperledger/burrow/permission/types"
+	"github.com/hyperledger/burrow/permission"
 )
 
 //
@@ -61,7 +61,7 @@ type SNativeFunctionDescription struct {
 	// Function return value
 	Return abi.Return
 	// Permissions required to call function
-	PermFlag ptypes.PermFlag
+	PermFlag permission.PermFlag
 	// Native function to which calls will be dispatched when a containing
 	// contract is called with a FunctionSelector matching this NativeContract
 	F NativeContract
@@ -98,7 +98,7 @@ func SNativeContracts() map[string]*SNativeContractDescription {
 					abiArg("_role", roleTypeName),
 				},
 				abiReturn("result", abi.BoolTypeName),
-				ptypes.AddRole,
+				permission.AddRole,
 				addRole},
 
 			&SNativeFunctionDescription{`
@@ -113,7 +113,7 @@ func SNativeContracts() map[string]*SNativeContractDescription {
 					abiArg("_role", roleTypeName),
 				},
 				abiReturn("result", abi.BoolTypeName),
-				ptypes.RemoveRole,
+				permission.RemoveRole,
 				removeRole},
 
 			&SNativeFunctionDescription{`
@@ -128,7 +128,7 @@ func SNativeContracts() map[string]*SNativeContractDescription {
 					abiArg("_role", roleTypeName),
 				},
 				abiReturn("result", abi.BoolTypeName),
-				ptypes.HasRole,
+				permission.HasRole,
 				hasRole},
 
 			&SNativeFunctionDescription{`
@@ -145,7 +145,7 @@ func SNativeContracts() map[string]*SNativeContractDescription {
 					abiArg("_set", abi.BoolTypeName),
 				},
 				abiReturn("result", permFlagTypeName),
-				ptypes.SetBase,
+				permission.SetBase,
 				setBase},
 
 			&SNativeFunctionDescription{`
@@ -159,7 +159,7 @@ func SNativeContracts() map[string]*SNativeContractDescription {
 					abiArg("_account", abi.AddressTypeName),
 					abiArg("_permission", permFlagTypeName)},
 				abiReturn("result", permFlagTypeName),
-				ptypes.UnsetBase,
+				permission.UnsetBase,
 				unsetBase},
 
 			&SNativeFunctionDescription{`
@@ -173,7 +173,7 @@ func SNativeContracts() map[string]*SNativeContractDescription {
 					abiArg("_account", abi.AddressTypeName),
 					abiArg("_permission", permFlagTypeName)},
 				abiReturn("result", abi.BoolTypeName),
-				ptypes.HasBase,
+				permission.HasBase,
 				hasBase},
 
 			&SNativeFunctionDescription{`
@@ -187,7 +187,7 @@ func SNativeContracts() map[string]*SNativeContractDescription {
 					abiArg("_permission", permFlagTypeName),
 					abiArg("_set", abi.BoolTypeName)},
 				abiReturn("result", permFlagTypeName),
-				ptypes.SetGlobal,
+				permission.SetGlobal,
 				setGlobal},
 		),
 	}
@@ -355,9 +355,9 @@ func hasBase(state state.ReaderWriter, caller acm.Account, args []byte, gas *uin
 	if acc == nil {
 		return nil, fmt.Errorf("unknown account %s", address)
 	}
-	permN := ptypes.PermFlag(Uint64FromWord256(permNum)) // already shifted
+	permN := permission.PermFlag(Uint64FromWord256(permNum)) // already shifted
 	if !ValidPermN(permN) {
-		return nil, ptypes.ErrInvalidPermission(permN)
+		return nil, permission.ErrInvalidPermission(permN)
 	}
 	hasPermission := HasPermission(state, acc, permN)
 	permInt := byteFromBool(hasPermission)
@@ -381,9 +381,9 @@ func setBase(stateWriter state.ReaderWriter, caller acm.Account, args []byte, ga
 	if acc == nil {
 		return nil, fmt.Errorf("unknown account %s", address)
 	}
-	permN := ptypes.PermFlag(Uint64FromWord256(permNum))
+	permN := permission.PermFlag(Uint64FromWord256(permNum))
 	if !ValidPermN(permN) {
-		return nil, ptypes.ErrInvalidPermission(permN)
+		return nil, permission.ErrInvalidPermission(permN)
 	}
 	permV := !permVal.IsZero()
 	if err = acc.MutablePermissions().Base.Set(permN, permV); err != nil {
@@ -408,9 +408,9 @@ func unsetBase(stateWriter state.ReaderWriter, caller acm.Account, args []byte,
 	if acc == nil {
 		return nil, fmt.Errorf("unknown account %s", address)
 	}
-	permN := ptypes.PermFlag(Uint64FromWord256(permNum))
+	permN := permission.PermFlag(Uint64FromWord256(permNum))
 	if !ValidPermN(permN) {
-		return nil, ptypes.ErrInvalidPermission(permN)
+		return nil, permission.ErrInvalidPermission(permN)
 	}
 	if err = acc.MutablePermissions().Base.Unset(permN); err != nil {
 		return nil, err
@@ -434,9 +434,9 @@ func setGlobal(stateWriter state.ReaderWriter, caller acm.Account, args []byte,
 	if acc == nil {
 		panic("cant find the global permissions account")
 	}
-	permN := ptypes.PermFlag(Uint64FromWord256(permNum))
+	permN := permission.PermFlag(Uint64FromWord256(permNum))
 	if !ValidPermN(permN) {
-		return nil, ptypes.ErrInvalidPermission(permN)
+		return nil, permission.ErrInvalidPermission(permN)
 	}
 	permV := !permVal.IsZero()
 	if err = acc.MutablePermissions().Base.Set(permN, permV); err != nil {
@@ -518,23 +518,23 @@ func removeRole(stateWriter state.ReaderWriter, caller acm.Account, args []byte,
 // Errors and utility funcs
 
 // Checks if a permission flag is valid (a known base chain or snative permission)
-func ValidPermN(n ptypes.PermFlag) bool {
-	return n <= ptypes.AllPermFlags
+func ValidPermN(n permission.PermFlag) bool {
+	return n <= permission.AllPermFlags
 }
 
 // Get the global BasePermissions
-func globalPerms(stateWriter state.ReaderWriter) ptypes.BasePermissions {
+func globalPerms(stateWriter state.ReaderWriter) permission.BasePermissions {
 	return state.GlobalAccountPermissions(stateWriter).Base
 }
 
 // Compute the effective permissions from an acm.Account's BasePermissions by
 // taking the bitwise or with the global BasePermissions resultant permissions
-func effectivePermBytes(basePerms ptypes.BasePermissions,
-	globalPerms ptypes.BasePermissions) []byte {
+func effectivePermBytes(basePerms permission.BasePermissions,
+	globalPerms permission.BasePermissions) []byte {
 	return permBytes(basePerms.ResultantPerms() | globalPerms.ResultantPerms())
 }
 
-func permBytes(basePerms ptypes.PermFlag) []byte {
+func permBytes(basePerms permission.PermFlag) []byte {
 	return Uint64ToWord256(uint64(basePerms)).Bytes()
 }
 
diff --git a/execution/evm/snative_test.go b/execution/evm/snative_test.go
index e9b4150db7256f160dede1eaab8e73962fae5cb1..ed02ab80ad498d0888a0fa81a1f81912c820a5e0 100644
--- a/execution/evm/snative_test.go
+++ b/execution/evm/snative_test.go
@@ -20,15 +20,14 @@ import (
 
 	"strings"
 
-	acm "github.com/hyperledger/burrow/account"
+	"github.com/hyperledger/burrow/acm"
 	. "github.com/hyperledger/burrow/binary"
 	"github.com/hyperledger/burrow/crypto"
 	"github.com/hyperledger/burrow/execution/errors"
 	"github.com/hyperledger/burrow/execution/evm/abi"
 	"github.com/hyperledger/burrow/execution/evm/asm/bc"
 	"github.com/hyperledger/burrow/execution/evm/sha3"
-	permission "github.com/hyperledger/burrow/permission/types"
-	ptypes "github.com/hyperledger/burrow/permission/types"
+	"github.com/hyperledger/burrow/permission"
 	"github.com/stretchr/testify/assert"
 )
 
@@ -128,13 +127,13 @@ func funcIDFromHex(t *testing.T, hexString string) abi.FunctionSelector {
 	return abi.FirstFourBytes(bs)
 }
 
-func permFlagToWord256(permFlag ptypes.PermFlag) Word256 {
+func permFlagToWord256(permFlag permission.PermFlag) Word256 {
 	return Uint64ToWord256(uint64(permFlag))
 }
 
-func allAccountPermissions() ptypes.AccountPermissions {
-	return ptypes.AccountPermissions{
-		Base: ptypes.BasePermissions{
+func allAccountPermissions() permission.AccountPermissions {
+	return permission.AccountPermissions{
+		Base: permission.BasePermissions{
 			Perms:  permission.AllPermFlags,
 			SetBit: permission.AllPermFlags,
 		},
diff --git a/execution/evm/vm.go b/execution/evm/vm.go
index dda39f001067077667307c895ba50cdd76cc4db1..53d9b1ebc68667bd5955e2af2aa49dea279dae64 100644
--- a/execution/evm/vm.go
+++ b/execution/evm/vm.go
@@ -21,17 +21,16 @@ import (
 	"math/big"
 	"strings"
 
-	acm "github.com/hyperledger/burrow/account"
-	"github.com/hyperledger/burrow/account/state"
+	"github.com/hyperledger/burrow/acm"
+	"github.com/hyperledger/burrow/acm/state"
 	. "github.com/hyperledger/burrow/binary"
 	"github.com/hyperledger/burrow/crypto"
-	"github.com/hyperledger/burrow/event"
 	"github.com/hyperledger/burrow/execution/errors"
-	"github.com/hyperledger/burrow/execution/events"
 	. "github.com/hyperledger/burrow/execution/evm/asm"
 	"github.com/hyperledger/burrow/execution/evm/sha3"
+	"github.com/hyperledger/burrow/execution/exec"
 	"github.com/hyperledger/burrow/logging"
-	ptypes "github.com/hyperledger/burrow/permission/types"
+	"github.com/hyperledger/burrow/permission"
 	"github.com/hyperledger/burrow/txs"
 )
 
@@ -40,6 +39,16 @@ const (
 	callStackCapacity = 100 // TODO ensure usage.
 )
 
+type EventSink interface {
+	Call(call *exec.CallEvent, exception *errors.Exception)
+	Log(log *exec.LogEvent)
+}
+
+type noopEventSink struct{}
+
+func (*noopEventSink) Call(call *exec.CallEvent, exception *errors.Exception) {}
+func (*noopEventSink) Log(log *exec.LogEvent)                                 {}
+
 type Params struct {
 	BlockHeight uint64
 	BlockHash   Word256
@@ -54,7 +63,7 @@ type VM struct {
 	tx               *txs.Tx
 	stackDepth       uint64
 	nestedCallErrors []errors.NestedCall
-	publisher        event.Publisher
+	eventSink        EventSink
 	logger           *logging.Logger
 	returnData       []byte
 	debugOpcodes     bool
@@ -68,6 +77,7 @@ func NewVM(params Params, origin crypto.Address, tx *txs.Tx, logger *logging.Log
 		origin:         origin,
 		stackDepth:     0,
 		tx:             tx,
+		eventSink:      &noopEventSink{},
 		logger:         logger.WithScope("NewVM"),
 	}
 	for _, option := range options {
@@ -82,9 +92,9 @@ func (vm *VM) Debugf(format string, a ...interface{}) {
 	}
 }
 
-// satisfies go_events.Eventable
-func (vm *VM) SetPublisher(publisher event.Publisher) {
-	vm.publisher = publisher
+// Set EventSink destination for events - can be unset if events generation is not required
+func (vm *VM) SetEventSink(em EventSink) {
+	vm.eventSink = em
 }
 
 // CONTRACT: it is the duty of the contract writer to call known permissions
@@ -93,29 +103,25 @@ func (vm *VM) SetPublisher(publisher event.Publisher) {
 // on known permissions and panics else)
 // If the perm is not defined in the acc nor set by default in GlobalPermissions,
 // this function returns false.
-func HasPermission(stateWriter state.ReaderWriter, acc acm.Account, perm ptypes.PermFlag) bool {
+func HasPermission(stateWriter state.ReaderWriter, acc acm.Account, perm permission.PermFlag) bool {
 	value, _ := acc.Permissions().Base.Compose(state.GlobalAccountPermissions(stateWriter).Base).Get(perm)
 	return value
 }
 
 func (vm *VM) fireCallEvent(exception *errors.CodedError, output *[]byte, callerAddress, calleeAddress crypto.Address, input []byte, value uint64, gas *uint64) {
 	// fire the post call event (including exception if applicable)
-	if vm.publisher != nil {
-		events.PublishAccountCall(vm.publisher, vm.tx, vm.params.BlockHeight,
-			&events.EventDataCall{
-				CallData: &events.CallData{
-					Caller: callerAddress,
-					Callee: calleeAddress,
-					Data:   input,
-					Value:  value,
-					Gas:    *gas,
-				},
-				Origin:     vm.origin,
-				StackDepth: vm.stackDepth,
-				Return:     *output,
-				Exception:  errors.AsCodedError(*exception),
-			})
-	}
+	vm.eventSink.Call(&exec.CallEvent{
+		CallData: &exec.CallData{
+			Caller: callerAddress,
+			Callee: calleeAddress,
+			Data:   input,
+			Value:  value,
+			Gas:    *gas,
+		},
+		Origin:     vm.origin,
+		StackDepth: vm.stackDepth,
+		Return:     *output,
+	}, errors.AsException(*exception))
 }
 
 // CONTRACT state is aware of caller and callee, so we can just mutate them.
@@ -124,7 +130,7 @@ func (vm *VM) fireCallEvent(exception *errors.CodedError, output *[]byte, caller
 // value: To be transferred from caller to callee. Refunded upon errors.CodedError.
 // gas:   Available gas. No refunds for gas.
 // code: May be nil, since the CALL opcode may be used to send value from contracts to accounts
-func (vm *VM) Call(callState *state.Cache, caller, callee acm.MutableAccount, code, input []byte, value uint64, gas *uint64) (output []byte, err errors.CodedError) {
+func (vm *VM) Call(callState *state.Cache, caller, callee *acm.MutableAccount, code, input []byte, value uint64, gas *uint64) (output []byte, err errors.CodedError) {
 
 	exception := new(errors.CodedError)
 	// fire the post call event (including exception if applicable)
@@ -168,7 +174,7 @@ func (vm *VM) Call(callState *state.Cache, caller, callee acm.MutableAccount, co
 // The intent of delegate call is to run the code of the callee in the storage context of the caller;
 // while preserving the original caller to the previous callee.
 // Different to the normal CALL or CALLCODE, the value does not need to be transferred to the callee.
-func (vm *VM) DelegateCall(callState *state.Cache, caller acm.Account, callee acm.MutableAccount, code, input []byte, value uint64, gas *uint64) (output []byte, err errors.CodedError) {
+func (vm *VM) DelegateCall(callState *state.Cache, caller acm.Account, callee *acm.MutableAccount, code, input []byte, value uint64, gas *uint64) (output []byte, err errors.CodedError) {
 
 	exception := new(string)
 	// fire the post call event (including exception if applicable)
@@ -208,7 +214,7 @@ func useGasNegative(gasLeft *uint64, gasToUse uint64, err *errors.CodedError) bo
 }
 
 // Just like Call() but does not transfer 'value' or modify the callDepth.
-func (vm *VM) call(callState *state.Cache, caller acm.Account, callee acm.MutableAccount, code, input []byte, value uint64, gas *uint64) (output []byte, err errors.CodedError) {
+func (vm *VM) call(callState *state.Cache, caller acm.Account, callee *acm.MutableAccount, code, input []byte, value uint64, gas *uint64) (output []byte, err errors.CodedError) {
 	vm.Debugf("(%d) (%X) %X (code=%d) gas: %v (d) %X\n", vm.stackDepth, caller.Address().Bytes()[:4], callee.Address(),
 		len(callee.Code()), *gas, input)
 
@@ -838,25 +844,18 @@ func (vm *VM) call(callState *state.Cache, caller acm.Account, callee acm.Mutabl
 				vm.Debugf(" => Memory err: %s", memErr)
 				return nil, firstErr(err, errors.ErrorCodeMemoryOutOfBounds)
 			}
-			if vm.publisher != nil {
-				publishErr := events.PublishLogEvent(vm.publisher, vm.tx, &events.EventDataLog{
-					Height:  vm.params.BlockHeight,
-					Address: callee.Address(),
-					Topics:  topics,
-					Data:    data,
-				})
-				if publishErr != nil {
-					vm.Debugf(" => Log event publish err: %s", publishErr)
-					return nil, firstErr(err, errors.ErrorCodeEventPublish)
-				}
-			}
+			vm.eventSink.Log(&exec.LogEvent{
+				Address: callee.Address(),
+				Topics:  topics,
+				Data:    data,
+			})
 			vm.Debugf(" => T:%X D:%X\n", topics, data)
 
 		case CREATE: // 0xF0
 			vm.returnData = nil
 
-			if !HasPermission(callState, callee, ptypes.CreateContract) {
-				return nil, errors.PermissionDenied{Perm: ptypes.CreateContract}
+			if !HasPermission(callState, callee, permission.CreateContract) {
+				return nil, errors.PermissionDenied{Perm: permission.CreateContract}
 			}
 			contractValue, popErr := stack.PopU64()
 			if popErr != nil {
@@ -902,8 +901,8 @@ func (vm *VM) call(callState *state.Cache, caller acm.Account, callee acm.Mutabl
 		case CALL, CALLCODE, DELEGATECALL: // 0xF1, 0xF2, 0xF4
 			vm.returnData = nil
 
-			if !HasPermission(callState, callee, ptypes.Call) {
-				return nil, errors.PermissionDenied{Perm: ptypes.Call}
+			if !HasPermission(callState, callee, permission.Call) {
+				return nil, errors.PermissionDenied{Perm: permission.Call}
 			}
 			gasLimit, popErr := stack.PopU64()
 			if popErr != nil {
@@ -982,8 +981,8 @@ func (vm *VM) call(callState *state.Cache, caller acm.Account, callee acm.Mutabl
 				} else {
 					// nil account means we're sending funds to a new account
 					if acc == nil {
-						if !HasPermission(callState, caller, ptypes.CreateAccount) {
-							return nil, errors.PermissionDenied{Perm: ptypes.CreateAccount}
+						if !HasPermission(callState, caller, permission.CreateAccount) {
+							return nil, errors.PermissionDenied{Perm: permission.CreateAccount}
 						}
 						acc = acm.ConcreteAccount{Address: crypto.AddressFromWord256(addr)}.MutableAccount()
 					}
@@ -1077,8 +1076,8 @@ func (vm *VM) call(callState *state.Cache, caller acm.Account, callee acm.Mutabl
 				if useGasNegative(gas, GasCreateAccount, &gasErr) {
 					return nil, firstErr(err, gasErr)
 				}
-				if !HasPermission(callState, callee, ptypes.CreateContract) {
-					return nil, firstErr(err, errors.PermissionDenied{Perm: ptypes.CreateContract})
+				if !HasPermission(callState, callee, permission.CreateContract) {
+					return nil, firstErr(err, errors.PermissionDenied{Perm: permission.CreateContract})
 				}
 				var createErr errors.CodedError
 				receiver, createErr = vm.createAccount(callState, callee, logger)
@@ -1088,7 +1087,7 @@ func (vm *VM) call(callState *state.Cache, caller acm.Account, callee acm.Mutabl
 
 			}
 
-			receiver, errAdd := receiver.AddToBalance(callee.Balance())
+			errAdd := receiver.AddToBalance(callee.Balance())
 			if errAdd != nil {
 				return nil, firstErr(err, errAdd)
 			}
@@ -1101,25 +1100,25 @@ func (vm *VM) call(callState *state.Cache, caller acm.Account, callee acm.Mutabl
 			return nil, nil
 
 		case STATICCALL, CREATE2:
-			return nil, errors.Errorf("%s not yet implemented", op.Name())
+			return nil, errors.Errorf("%v not yet implemented", op)
 
 		default:
-			vm.Debugf("(pc) %-3v Unknown opcode %X\n", pc, op)
-			return nil, errors.Errorf("unknown opcode %X", op)
+			vm.Debugf("(pc) %-3v Unknown opcode %v\n", pc, op)
+			return nil, errors.Errorf("unknown opcode %v", op)
 		}
 		pc++
 	}
 }
 
-func (vm *VM) createAccount(callState *state.Cache, callee acm.MutableAccount, logger *logging.Logger) (acm.MutableAccount, errors.CodedError) {
+func (vm *VM) createAccount(callState *state.Cache, callee *acm.MutableAccount, logger *logging.Logger) (*acm.MutableAccount, errors.CodedError) {
 	newAccount := DeriveNewAccount(callee, state.GlobalAccountPermissions(callState), logger)
 	err := callState.UpdateAccount(newAccount)
 	if err != nil {
-		return nil, errors.AsCodedError(err)
+		return nil, errors.AsException(err)
 	}
 	err = callState.UpdateAccount(callee)
 	if err != nil {
-		return nil, errors.AsCodedError(err)
+		return nil, errors.AsException(err)
 	}
 	return newAccount, nil
 }
@@ -1168,20 +1167,20 @@ func (vm *VM) jump(code []byte, to int64, pc *int64) (err errors.CodedError) {
 
 func firstErr(errA, errB error) errors.CodedError {
 	if errA != nil {
-		return errors.AsCodedError(errA)
+		return errors.AsException(errA)
 	} else {
-		return errors.AsCodedError(errB)
+		return errors.AsException(errB)
 	}
 }
 
-func transfer(from, to acm.MutableAccount, amount uint64) errors.CodedError {
+func transfer(from, to *acm.MutableAccount, amount uint64) errors.CodedError {
 	if from.Balance() < amount {
 		return errors.ErrorCodeInsufficientBalance
 	} else {
 		from.SubtractFromBalance(amount)
-		_, err := to.AddToBalance(amount)
+		err := to.AddToBalance(amount)
 		if err != nil {
-			return errors.AsCodedError(err)
+			return errors.AsException(err)
 		}
 	}
 	return nil
diff --git a/execution/evm/vm_test.go b/execution/evm/vm_test.go
index 62d1ca3b816631af52709aa0eb0ea6f5eefec4db..5b7224d1765f08d34a9bde7c5b4b8a6dbf8af550 100644
--- a/execution/evm/vm_test.go
+++ b/execution/evm/vm_test.go
@@ -15,25 +15,22 @@
 package evm
 
 import (
-	"context"
 	"encoding/hex"
 	"fmt"
 	"strconv"
 	"testing"
 	"time"
 
-	acm "github.com/hyperledger/burrow/account"
-	"github.com/hyperledger/burrow/account/state"
+	"github.com/hyperledger/burrow/acm"
+	"github.com/hyperledger/burrow/acm/state"
 	. "github.com/hyperledger/burrow/binary"
 	"github.com/hyperledger/burrow/crypto"
-	"github.com/hyperledger/burrow/event"
 	"github.com/hyperledger/burrow/execution/errors"
-	"github.com/hyperledger/burrow/execution/events"
 	. "github.com/hyperledger/burrow/execution/evm/asm"
 	. "github.com/hyperledger/burrow/execution/evm/asm/bc"
+	"github.com/hyperledger/burrow/execution/exec"
 	"github.com/hyperledger/burrow/logging"
 	"github.com/hyperledger/burrow/permission"
-	ptypes "github.com/hyperledger/burrow/permission/types"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
 	"golang.org/x/crypto/ripemd160"
@@ -65,7 +62,7 @@ func newParams() Params {
 	}
 }
 
-func newAccount(seed ...byte) acm.MutableAccount {
+func newAccount(seed ...byte) *acm.MutableAccount {
 	hasher := ripemd160.New()
 	hasher.Write(seed)
 	return acm.ConcreteAccount{
@@ -697,14 +694,16 @@ func TestSendCall(t *testing.T) {
 
 	//----------------------------------------------
 	// give account2 sufficient balance, should pass
-	account2, err = newAccount(2).AddToBalance(100000)
+	account2 = newAccount(2)
+	err = account2.AddToBalance(100000)
 	require.NoError(t, err)
 	_, err = runVMWaitError(cache, ourVm, account1, account2, addr, contractCode, 1000)
 	assert.NoError(t, err, "Should have sufficient balance")
 
 	//----------------------------------------------
 	// insufficient gas, should fail
-	account2, err = newAccount(2).AddToBalance(100000)
+	account2 = newAccount(2)
+	err = account2.AddToBalance(100000)
 	require.NoError(t, err)
 	_, err = runVMWaitError(cache, ourVm, account1, account2, addr, contractCode, 100)
 	assert.NoError(t, err, "Expected insufficient gas error")
@@ -996,7 +995,7 @@ func returnWord() []byte {
 }
 
 func makeAccountWithCode(accountUpdater state.AccountUpdater, name string,
-	code []byte) (acm.MutableAccount, crypto.Address) {
+	code []byte) (*acm.MutableAccount, crypto.Address) {
 	address, _ := crypto.AddressFromBytes([]byte(name))
 	account := acm.ConcreteAccount{
 		Address:  address,
@@ -1012,43 +1011,34 @@ func makeAccountWithCode(accountUpdater state.AccountUpdater, name string,
 // and then waits for any exceptions transmitted by Data in the AccCall
 // event (in the case of no direct error from call we will block waiting for
 // at least 1 AccCall event)
-func runVMWaitError(vmCache *state.Cache, ourVm *VM, caller, callee acm.MutableAccount, subscribeAddr crypto.Address,
+func runVMWaitError(vmCache *state.Cache, ourVm *VM, caller, callee *acm.MutableAccount, subscribeAddr crypto.Address,
 	contractCode []byte, gas uint64) ([]byte, error) {
-	eventCh := make(chan *events.EventDataCall)
-	output, err := runVM(eventCh, vmCache, ourVm, caller, callee, subscribeAddr, contractCode, gas)
+	txe := new(exec.TxExecution)
+	output, err := runVM(txe, vmCache, ourVm, caller, callee, subscribeAddr, contractCode, gas)
 	if err != nil {
 		return output, err
 	}
-	select {
-	case eventDataCall := <-eventCh:
-		if eventDataCall.Exception != nil {
-			return output, eventDataCall.Exception
+	if len(txe.Events) > 0 {
+		ex := txe.Events[0].Header.Exception
+		if ex != nil {
+			return output, ex
 		}
-		return output, nil
 	}
+	return output, nil
 }
 
 // Subscribes to an AccCall, runs the vm, returns the output and any direct
 // exception
-func runVM(eventCh chan<- *events.EventDataCall, vmCache *state.Cache, ourVm *VM, caller, callee acm.MutableAccount,
+func runVM(sink EventSink, vmCache *state.Cache, ourVm *VM, caller, callee *acm.MutableAccount,
 	subscribeAddr crypto.Address, contractCode []byte, gas uint64) ([]byte, error) {
 
-	// we need to catch the event from the CALL to check for exceptions
-	em := event.NewEmitter(logging.NewNoopLogger())
 	fmt.Printf("subscribe to %s\n", subscribeAddr)
 
-	err := events.SubscribeAccountCall(context.Background(), em, "test", subscribeAddr,
-		nil, -1, eventCh)
-	if err != nil {
-		return nil, err
-	}
-	evc := event.NewCache()
-	ourVm.SetPublisher(evc)
+	ourVm.SetEventSink(sink)
 	start := time.Now()
 	output, err := ourVm.Call(vmCache, caller, callee, contractCode, []byte{}, 0, &gas)
 	fmt.Printf("Output: %v Error: %v\n", output, err)
 	fmt.Println("Call took:", time.Since(start))
-	evc.Flush(em)
 	return output, err
 }
 
@@ -1155,7 +1145,7 @@ func TestSubslice(t *testing.T) {
 func TestHasPermission(t *testing.T) {
 	st := newAppState()
 	acc := acm.ConcreteAccount{
-		Permissions: ptypes.AccountPermissions{
+		Permissions: permission.AccountPermissions{
 			Base: BasePermissionsFromStrings(t,
 				"00100001000111",
 				"11011110111000"),
@@ -1165,15 +1155,15 @@ func TestHasPermission(t *testing.T) {
 	assert.True(t, HasPermission(st, acc, PermFlagFromString(t, "100001000110")))
 }
 
-func BasePermissionsFromStrings(t *testing.T, perms, setBit string) ptypes.BasePermissions {
-	return ptypes.BasePermissions{
+func BasePermissionsFromStrings(t *testing.T, perms, setBit string) permission.BasePermissions {
+	return permission.BasePermissions{
 		Perms:  PermFlagFromString(t, perms),
 		SetBit: PermFlagFromString(t, setBit),
 	}
 }
 
-func PermFlagFromString(t *testing.T, binaryString string) ptypes.PermFlag {
+func PermFlagFromString(t *testing.T, binaryString string) permission.PermFlag {
 	permFlag, err := strconv.ParseUint(binaryString, 2, 64)
 	require.NoError(t, err)
-	return ptypes.PermFlag(permFlag)
+	return permission.PermFlag(permFlag)
 }
diff --git a/execution/exec/block_execution.go b/execution/exec/block_execution.go
new file mode 100644
index 0000000000000000000000000000000000000000..3fc8a905de6d74e5177928981e1ddeb89d6f4b2a
--- /dev/null
+++ b/execution/exec/block_execution.go
@@ -0,0 +1,99 @@
+package exec
+
+import (
+	"fmt"
+
+	"encoding/json"
+
+	"github.com/gogo/protobuf/proto"
+	"github.com/hyperledger/burrow/event"
+	"github.com/hyperledger/burrow/event/query"
+	"github.com/hyperledger/burrow/txs"
+	abciTypes "github.com/tendermint/abci/types"
+)
+
+func EventStringBlockExecution(height uint64) string { return fmt.Sprintf("Execution/Block/%v", height) }
+
+func DecodeBlockExecution(bs []byte) (*BlockExecution, error) {
+	be := new(BlockExecution)
+	err := cdc.UnmarshalBinary(bs, be)
+	if err != nil {
+		return nil, err
+	}
+	return be, nil
+}
+
+func (be *BlockExecution) Encode() ([]byte, error) {
+	return cdc.MarshalBinary(be)
+}
+
+func (*BlockExecution) EventType() EventType {
+	return TypeBlockExecution
+}
+
+func (be *BlockExecution) Tx(txEnv *txs.Envelope) *TxExecution {
+	txe := NewTxExecution(txEnv)
+	be.Append(txe)
+	return txe
+}
+
+func (be *BlockExecution) Append(tail ...*TxExecution) {
+	for i, txe := range tail {
+		txe.Index = uint64(len(be.TxExecutions) + i)
+		txe.Height = be.Height
+	}
+	be.TxExecutions = append(be.TxExecutions, tail...)
+}
+
+// Tags
+type TaggedBlockExecution struct {
+	query.Tagged
+	*BlockExecution
+}
+
+func (be *BlockExecution) Tagged() *TaggedBlockExecution {
+	return &TaggedBlockExecution{
+		Tagged: query.MergeTags(
+			query.TagMap{
+				event.EventIDKey:   EventStringBlockExecution(be.Height),
+				event.EventTypeKey: be.EventType(),
+			},
+			query.MustReflectTags(be),
+			query.MustReflectTags(be.BlockHeader),
+		),
+		BlockExecution: be,
+	}
+}
+
+// TODO remove when Header gogo protobuf fixed in Tendermint
+func BlockHeaderFromHeader(header *abciTypes.Header) *BlockHeader {
+	if header == nil {
+		return nil
+	}
+	bs, _ := json.Marshal(header)
+	return &BlockHeader{
+		JSON:   string(bs),
+		NumTxs: header.NumTxs,
+	}
+}
+
+type ABCIHeader struct {
+	*abciTypes.Header
+}
+
+// Gogo proto support
+func (h *ABCIHeader) Marshal() ([]byte, error) {
+	return proto.Marshal(h.Header)
+}
+
+func (h *ABCIHeader) Unmarshal(data []byte) error {
+	return proto.Unmarshal(data, h.Header)
+}
+
+func QueryForBlockExecutionFromHeight(height uint64) *query.Builder {
+	return QueryForBlockExecution().AndGreaterThanOrEqual(event.HeightKey, height)
+}
+
+func QueryForBlockExecution() *query.Builder {
+	return query.NewBuilder().AndEquals(event.EventTypeKey, TypeBlockExecution)
+}
diff --git a/execution/exec/block_execution_test.go b/execution/exec/block_execution_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..5a02fd56416ee18d49ae9ef5d59c8d07ed92ab94
--- /dev/null
+++ b/execution/exec/block_execution_test.go
@@ -0,0 +1,24 @@
+package exec
+
+import (
+	"testing"
+
+	"github.com/stretchr/testify/require"
+)
+
+func TestBlockExecution_Marshal(t *testing.T) {
+	be := &BlockExecution{
+		// TODO: reenable when tendermint Header works GRPC
+		//BlockHeader: &abciTypes.Header{
+		//	Height:  3,
+		//	AppHash: []byte{2},
+		//	Proposer: abciTypes.Validator{
+		//		Power: 34,
+		//	},
+		//},
+	}
+	bs, err := be.Marshal()
+	require.NoError(t, err)
+	beOut := new(BlockExecution)
+	require.NoError(t, beOut.Unmarshal(bs))
+}
diff --git a/execution/exec/codec.go b/execution/exec/codec.go
new file mode 100644
index 0000000000000000000000000000000000000000..beb9d32a79998e585b37aec9c3d7abd0acf620c3
--- /dev/null
+++ b/execution/exec/codec.go
@@ -0,0 +1,5 @@
+package exec
+
+import "github.com/hyperledger/burrow/txs"
+
+var cdc = txs.NewAminoCodec()
diff --git a/execution/exec/event.go b/execution/exec/event.go
new file mode 100644
index 0000000000000000000000000000000000000000..b629a265ce93a9cee8f22ce9037bfe9cdb30260c
--- /dev/null
+++ b/execution/exec/event.go
@@ -0,0 +1,120 @@
+package exec
+
+import (
+	"reflect"
+
+	"fmt"
+
+	"github.com/hyperledger/burrow/event"
+	"github.com/hyperledger/burrow/event/query"
+)
+
+var eventMessageTag = query.TagMap{event.MessageTypeKey: reflect.TypeOf(&Event{}).String()}
+
+type EventType uint32
+
+// Execution event types
+const (
+	TypeCall           = EventType(0x00)
+	TypeLog            = EventType(0x01)
+	TypeAccountInput   = EventType(0x02)
+	TypeAccountOutput  = EventType(0x03)
+	TypeTxExecution    = EventType(0x04)
+	TypeBlockExecution = EventType(0x05)
+)
+
+var nameFromType = map[EventType]string{
+	TypeCall:           "CallEvent",
+	TypeLog:            "LogEvent",
+	TypeAccountInput:   "AccountInputEvent",
+	TypeAccountOutput:  "AccountOutputEvent",
+	TypeTxExecution:    "TxExecutionEvent",
+	TypeBlockExecution: "BlockExecutionEvent",
+}
+
+var typeFromName = make(map[string]EventType)
+
+func init() {
+	for t, n := range nameFromType {
+		typeFromName[n] = t
+	}
+}
+
+func EventTypeFromString(name string) EventType {
+	return typeFromName[name]
+}
+
+func (ev *Event) EventType() EventType {
+	return ev.Header.EventType
+}
+
+func (typ EventType) String() string {
+	name, ok := nameFromType[typ]
+	if ok {
+		return name
+	}
+	return "UnknownTx"
+}
+
+func (typ EventType) MarshalText() ([]byte, error) {
+	return []byte(typ.String()), nil
+}
+
+func (typ *EventType) UnmarshalText(data []byte) error {
+	*typ = EventTypeFromString(string(data))
+	return nil
+}
+
+// Event
+
+func (ev *Event) String() string {
+	return fmt.Sprintf("ExecutionEvent{%v: %s}", ev.Header.String(), ev.Body())
+}
+
+func (ev *Event) Body() string {
+	if ev.Input != nil {
+		return ev.Input.String()
+	}
+	if ev.Output != nil {
+		return ev.Output.String()
+	}
+	if ev.Log != nil {
+		return ev.Log.String()
+	}
+	if ev.Call != nil {
+		return ev.Call.String()
+	}
+	return "<empty>"
+}
+
+// Tags
+type TaggedEvent struct {
+	query.Tagged
+	*Event
+}
+
+type TaggedEvents []*TaggedEvent
+
+func (ev *Event) Tagged() *TaggedEvent {
+	return &TaggedEvent{
+		Tagged: query.MergeTags(
+			query.MustReflectTags(ev.Header),
+			eventMessageTag,
+			query.MustReflectTags(ev.Input),
+			query.MustReflectTags(ev.Output),
+			query.MustReflectTags(ev.Call),
+			ev.Log,
+		),
+		Event: ev,
+	}
+}
+
+func (tevs TaggedEvents) Filter(qry query.Query) TaggedEvents {
+	var filtered TaggedEvents
+	for _, tev := range tevs {
+		if qry.Matches(tev) {
+			filtered = append(filtered, tev)
+		}
+	}
+	return filtered
+}
diff --git a/execution/exec/event_test.go b/execution/exec/event_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..e1e12072f2f6f6d45bd439f320cb5c1ce60582d9
--- /dev/null
+++ b/execution/exec/event_test.go
@@ -0,0 +1,72 @@
+package exec
+
+import (
+	"testing"
+
+	"github.com/hyperledger/burrow/binary"
+	"github.com/hyperledger/burrow/crypto"
+	"github.com/hyperledger/burrow/event"
+	"github.com/hyperledger/burrow/event/query"
+	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/require"
+	"github.com/tmthrgd/go-hex"
+)
+
+func TestEventTagQueries(t *testing.T) {
+	addressHex := "DEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEF"
+	address, err := crypto.AddressFromHexString(addressHex)
+	require.NoError(t, err)
+	ev := &Event{
+		Header: &Header{
+			EventType: TypeLog,
+			EventID:   "foo/bar",
+			TxHash:    []byte{2, 3, 4},
+			Height:    34,
+			Index:     2,
+		},
+		Log: &LogEvent{
+			Address: address,
+			Topics:  []binary.Word256{binary.RightPadWord256([]byte("marmot"))},
+		},
+	}
+
+	tev := ev.Tagged()
+
+	qb := query.NewBuilder().AndEquals(event.EventTypeKey, TypeLog.String())
+	qry, err := qb.Query()
+	require.NoError(t, err)
+	assert.True(t, qry.Matches(tev))
+
+	qb = qb.AndContains(event.EventIDKey, "bar")
+	qry, err = qb.Query()
+	require.NoError(t, err)
+	assert.True(t, qry.Matches(tev))
+
+	qb = qb.AndEquals(event.TxHashKey, hex.EncodeUpperToString(tev.Header.TxHash))
+	qry, err = qb.Query()
+	require.NoError(t, err)
+	assert.True(t, qry.Matches(tev))
+
+	qb = qb.AndGreaterThanOrEqual(event.HeightKey, tev.Header.Height)
+	qry, err = qb.Query()
+	require.NoError(t, err)
+	assert.True(t, qry.Matches(tev))
+
+	qb = qb.AndStrictlyLessThan(event.IndexKey, tev.Header.Index+1)
+	qry, err = qb.Query()
+	require.NoError(t, err)
+	assert.True(t, qry.Matches(tev))
+
+	qb = qb.AndEquals(event.AddressKey, addressHex)
+	qry, err = qb.Query()
+	require.NoError(t, err)
+	assert.True(t, qry.Matches(tev))
+
+	qb = qb.AndEquals(LogNTextKey(0), "marmot")
+	qry, err = qb.Query()
+	require.NoError(t, err)
+	assert.True(t, qry.Matches(tev))
+
+	t.Logf("Query: %v", qry)
+	t.Logf("Keys: %v", tev.Keys())
+}
diff --git a/execution/exec/exec.pb.go b/execution/exec/exec.pb.go
new file mode 100644
index 0000000000000000000000000000000000000000..6c7cfe26c6fb967a2b217cc76ed5d08fcf0d45e0
--- /dev/null
+++ b/execution/exec/exec.pb.go
@@ -0,0 +1,3216 @@
+// Code generated by protoc-gen-gogo. DO NOT EDIT.
+// source: exec.proto
+
+/*
+	Package exec is a generated protocol buffer package.
+
+	It is generated from these files:
+		exec.proto
+
+	It has these top-level messages:
+		BlockExecution
+		BlockHeader
+		TxExecution
+		Header
+		Event
+		Result
+		LogEvent
+		CallEvent
+		InputEvent
+		OutputEvent
+		CallData
+*/
+package exec
+
+import proto "github.com/gogo/protobuf/proto"
+import golang_proto "github.com/golang/protobuf/proto"
+import fmt "fmt"
+import math "math"
+import _ "github.com/gogo/protobuf/gogoproto"
+import _ "github.com/tendermint/abci/types"
+import errors "github.com/hyperledger/burrow/execution/errors"
+import names "github.com/hyperledger/burrow/execution/names"
+import txs "github.com/hyperledger/burrow/txs"
+import permission "github.com/hyperledger/burrow/permission"
+
+import github_com_hyperledger_burrow_txs_payload "github.com/hyperledger/burrow/txs/payload"
+import github_com_hyperledger_burrow_binary "github.com/hyperledger/burrow/binary"
+import github_com_hyperledger_burrow_txs "github.com/hyperledger/burrow/txs"
+import github_com_hyperledger_burrow_crypto "github.com/hyperledger/burrow/crypto"
+
+import io "io"
+
+// Reference imports to suppress errors if they are not otherwise used.
+var _ = proto.Marshal
+var _ = golang_proto.Marshal
+var _ = fmt.Errorf
+var _ = math.Inf
+
+// This is a compile-time assertion to ensure that this generated file
+// is compatible with the proto package it is being compiled against.
+// A compilation error at this line likely means your copy of the
+// proto package needs to be updated.
+const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package
+
+type BlockExecution struct {
+	// The height of this block
+	Height uint64 `protobuf:"varint,1,opt,name=Height,proto3" json:"Height,omitempty"`
+	// TODO: reintroduce this when upstream merges: https://github.com/tendermint/tendermint/pull/1987
+	//    types.Header BlockHeader = 2;
+	BlockHeader  *BlockHeader   `protobuf:"bytes,2,opt,name=BlockHeader" json:"BlockHeader,omitempty"`
+	TxExecutions []*TxExecution `protobuf:"bytes,3,rep,name=TxExecutions" json:"TxExecutions,omitempty"`
+}
+
+func (m *BlockExecution) Reset()                    { *m = BlockExecution{} }
+func (m *BlockExecution) String() string            { return proto.CompactTextString(m) }
+func (*BlockExecution) ProtoMessage()               {}
+func (*BlockExecution) Descriptor() ([]byte, []int) { return fileDescriptorExec, []int{0} }
+
+func (m *BlockExecution) GetHeight() uint64 {
+	if m != nil {
+		return m.Height
+	}
+	return 0
+}
+
+func (m *BlockExecution) GetBlockHeader() *BlockHeader {
+	if m != nil {
+		return m.BlockHeader
+	}
+	return nil
+}
+
+func (m *BlockExecution) GetTxExecutions() []*TxExecution {
+	if m != nil {
+		return m.TxExecutions
+	}
+	return nil
+}
+
+func (*BlockExecution) XXX_MessageName() string {
+	return "exec.BlockExecution"
+}
+
+type BlockHeader struct {
+	JSON   string `protobuf:"bytes,1,opt,name=JSON,proto3" json:"JSON,omitempty"`
+	NumTxs int32  `protobuf:"varint,2,opt,name=NumTxs,proto3" json:"NumTxs,omitempty"`
+}
+
+func (m *BlockHeader) Reset()                    { *m = BlockHeader{} }
+func (m *BlockHeader) String() string            { return proto.CompactTextString(m) }
+func (*BlockHeader) ProtoMessage()               {}
+func (*BlockHeader) Descriptor() ([]byte, []int) { return fileDescriptorExec, []int{1} }
+
+func (m *BlockHeader) GetJSON() string {
+	if m != nil {
+		return m.JSON
+	}
+	return ""
+}
+
+func (m *BlockHeader) GetNumTxs() int32 {
+	if m != nil {
+		return m.NumTxs
+	}
+	return 0
+}
+
+func (*BlockHeader) XXX_MessageName() string {
+	return "exec.BlockHeader"
+}
+
+type TxExecution struct {
+	// Transaction type
+	TxType github_com_hyperledger_burrow_txs_payload.Type `protobuf:"varint,2,opt,name=TxType,proto3,casttype=github.com/hyperledger/burrow/txs/payload.Type" json:"TxType,omitempty"`
+	// The hash of the transaction that caused this event to be generated
+	TxHash github_com_hyperledger_burrow_binary.HexBytes `protobuf:"bytes,3,opt,name=TxHash,proto3,customtype=github.com/hyperledger/burrow/binary.HexBytes" json:"TxHash"`
+	// The block height at which this Tx was included
+	Height uint64 `protobuf:"varint,4,opt,name=Height,proto3" json:"Height,omitempty"`
+	// The index of this transaction within the block
+	Index uint64 `protobuf:"varint,5,opt,name=Index,proto3" json:"Index,omitempty"`
+	// Signed Tx that triggered this execution
+	Envelope *github_com_hyperledger_burrow_txs.Envelope `protobuf:"bytes,6,opt,name=Envelope,customtype=github.com/hyperledger/burrow/txs.Envelope" json:"Envelope,omitempty"`
+	// Execution events
+	Events []*Event `protobuf:"bytes,7,rep,name=Events" json:"Events,omitempty"`
+	// The execution results
+	Result *Result `protobuf:"bytes,8,opt,name=Result" json:"Result,omitempty"`
+	// The transaction receipt
+	Receipt *txs.Receipt `protobuf:"bytes,9,opt,name=Receipt" json:"Receipt,omitempty"`
+	// If execution was an exception
+	Exception *errors.Exception `protobuf:"bytes,10,opt,name=Exception" json:"Exception,omitempty"`
+}
+
+func (m *TxExecution) Reset()                    { *m = TxExecution{} }
+func (m *TxExecution) String() string            { return proto.CompactTextString(m) }
+func (*TxExecution) ProtoMessage()               {}
+func (*TxExecution) Descriptor() ([]byte, []int) { return fileDescriptorExec, []int{2} }
+
+func (m *TxExecution) GetTxType() github_com_hyperledger_burrow_txs_payload.Type {
+	if m != nil {
+		return m.TxType
+	}
+	return 0
+}
+
+func (m *TxExecution) GetHeight() uint64 {
+	if m != nil {
+		return m.Height
+	}
+	return 0
+}
+
+func (m *TxExecution) GetIndex() uint64 {
+	if m != nil {
+		return m.Index
+	}
+	return 0
+}
+
+func (m *TxExecution) GetEvents() []*Event {
+	if m != nil {
+		return m.Events
+	}
+	return nil
+}
+
+func (m *TxExecution) GetResult() *Result {
+	if m != nil {
+		return m.Result
+	}
+	return nil
+}
+
+func (m *TxExecution) GetReceipt() *txs.Receipt {
+	if m != nil {
+		return m.Receipt
+	}
+	return nil
+}
+
+func (m *TxExecution) GetException() *errors.Exception {
+	if m != nil {
+		return m.Exception
+	}
+	return nil
+}
+
+func (*TxExecution) XXX_MessageName() string {
+	return "exec.TxExecution"
+}
+
+type Header struct {
+	// Transaction type
+	TxType github_com_hyperledger_burrow_txs_payload.Type `protobuf:"varint,1,opt,name=TxType,proto3,casttype=github.com/hyperledger/burrow/txs/payload.Type" json:"TxType,omitempty"`
+	// The hash of the transaction that caused this event to be generated
+	TxHash github_com_hyperledger_burrow_binary.HexBytes `protobuf:"bytes,2,opt,name=TxHash,proto3,customtype=github.com/hyperledger/burrow/binary.HexBytes" json:"TxHash"`
+	// The type of event
+	EventType EventType `protobuf:"varint,3,opt,name=EventType,proto3,casttype=EventType" json:"EventType,omitempty"`
+	// EventID published with event
+	EventID string `protobuf:"bytes,4,opt,name=EventID,proto3" json:"EventID,omitempty"`
+	// The block height at which this event was emitted
+	Height uint64 `protobuf:"varint,5,opt,name=Height,proto3" json:"Height,omitempty"`
+	// The index of this event relative to other events generated by the same transaction
+	Index uint64 `protobuf:"varint,6,opt,name=Index,proto3" json:"Index,omitempty"`
+	// If event is exception
+	Exception *errors.Exception `protobuf:"bytes,7,opt,name=Exception" json:"Exception,omitempty"`
+}
+
+func (m *Header) Reset()                    { *m = Header{} }
+func (*Header) ProtoMessage()               {}
+func (*Header) Descriptor() ([]byte, []int) { return fileDescriptorExec, []int{3} }
+
+func (m *Header) GetTxType() github_com_hyperledger_burrow_txs_payload.Type {
+	if m != nil {
+		return m.TxType
+	}
+	return 0
+}
+
+func (m *Header) GetEventType() EventType {
+	if m != nil {
+		return m.EventType
+	}
+	return 0
+}
+
+func (m *Header) GetEventID() string {
+	if m != nil {
+		return m.EventID
+	}
+	return ""
+}
+
+func (m *Header) GetHeight() uint64 {
+	if m != nil {
+		return m.Height
+	}
+	return 0
+}
+
+func (m *Header) GetIndex() uint64 {
+	if m != nil {
+		return m.Index
+	}
+	return 0
+}
+
+func (m *Header) GetException() *errors.Exception {
+	if m != nil {
+		return m.Exception
+	}
+	return nil
+}
+
+func (*Header) XXX_MessageName() string {
+	return "exec.Header"
+}
+
+type Event struct {
+	Header *Header      `protobuf:"bytes,1,opt,name=Header" json:"Header,omitempty"`
+	Input  *InputEvent  `protobuf:"bytes,2,opt,name=Input" json:"Input,omitempty"`
+	Output *OutputEvent `protobuf:"bytes,3,opt,name=Output" json:"Output,omitempty"`
+	Call   *CallEvent   `protobuf:"bytes,4,opt,name=Call" json:"Call,omitempty"`
+	Log    *LogEvent    `protobuf:"bytes,5,opt,name=Log" json:"Log,omitempty"`
+}
+
+func (m *Event) Reset()                    { *m = Event{} }
+func (*Event) ProtoMessage()               {}
+func (*Event) Descriptor() ([]byte, []int) { return fileDescriptorExec, []int{4} }
+
+func (m *Event) GetHeader() *Header {
+	if m != nil {
+		return m.Header
+	}
+	return nil
+}
+
+func (m *Event) GetInput() *InputEvent {
+	if m != nil {
+		return m.Input
+	}
+	return nil
+}
+
+func (m *Event) GetOutput() *OutputEvent {
+	if m != nil {
+		return m.Output
+	}
+	return nil
+}
+
+func (m *Event) GetCall() *CallEvent {
+	if m != nil {
+		return m.Call
+	}
+	return nil
+}
+
+func (m *Event) GetLog() *LogEvent {
+	if m != nil {
+		return m.Log
+	}
+	return nil
+}
+
+func (*Event) XXX_MessageName() string {
+	return "exec.Event"
+}
+
+// Could structure this further if needed - sum type of various results relevant to different transaction types
+type Result struct {
+	// EVM execution return
+	Return []byte `protobuf:"bytes,1,opt,name=Return,proto3" json:"Return,omitempty"`
+	// Gas used in computation
+	GasUsed uint64 `protobuf:"varint,2,opt,name=GasUsed,proto3" json:"GasUsed,omitempty"`
+	// Name entry created
+	NameEntry *names.Entry `protobuf:"bytes,3,opt,name=NameEntry" json:"NameEntry,omitempty"`
+	// Permission update performed
+	PermArgs *permission.PermArgs `protobuf:"bytes,4,opt,name=PermArgs" json:"PermArgs,omitempty"`
+}
+
+func (m *Result) Reset()                    { *m = Result{} }
+func (m *Result) String() string            { return proto.CompactTextString(m) }
+func (*Result) ProtoMessage()               {}
+func (*Result) Descriptor() ([]byte, []int) { return fileDescriptorExec, []int{5} }
+
+func (m *Result) GetReturn() []byte {
+	if m != nil {
+		return m.Return
+	}
+	return nil
+}
+
+func (m *Result) GetGasUsed() uint64 {
+	if m != nil {
+		return m.GasUsed
+	}
+	return 0
+}
+
+func (m *Result) GetNameEntry() *names.Entry {
+	if m != nil {
+		return m.NameEntry
+	}
+	return nil
+}
+
+func (m *Result) GetPermArgs() *permission.PermArgs {
+	if m != nil {
+		return m.PermArgs
+	}
+	return nil
+}
+
+func (*Result) XXX_MessageName() string {
+	return "exec.Result"
+}
+
+type LogEvent struct {
+	Address github_com_hyperledger_burrow_crypto.Address   `protobuf:"bytes,1,opt,name=Address,proto3,customtype=github.com/hyperledger/burrow/crypto.Address" json:"Address"`
+	Data    github_com_hyperledger_burrow_binary.HexBytes  `protobuf:"bytes,2,opt,name=Data,proto3,customtype=github.com/hyperledger/burrow/binary.HexBytes" json:"Data"`
+	Topics  []github_com_hyperledger_burrow_binary.Word256 `protobuf:"bytes,3,rep,name=Topics,customtype=github.com/hyperledger/burrow/binary.Word256" json:"Topics"`
+}
+
+func (m *LogEvent) Reset()                    { *m = LogEvent{} }
+func (m *LogEvent) String() string            { return proto.CompactTextString(m) }
+func (*LogEvent) ProtoMessage()               {}
+func (*LogEvent) Descriptor() ([]byte, []int) { return fileDescriptorExec, []int{6} }
+
+func (*LogEvent) XXX_MessageName() string {
+	return "exec.LogEvent"
+}
+
+type CallEvent struct {
+	CallData   *CallData                                     `protobuf:"bytes,1,opt,name=CallData" json:"CallData,omitempty"`
+	Origin     github_com_hyperledger_burrow_crypto.Address  `protobuf:"bytes,2,opt,name=Origin,proto3,customtype=github.com/hyperledger/burrow/crypto.Address" json:"Origin"`
+	StackDepth uint64                                        `protobuf:"varint,3,opt,name=StackDepth,proto3" json:"StackDepth,omitempty"`
+	Return     github_com_hyperledger_burrow_binary.HexBytes `protobuf:"bytes,4,opt,name=Return,proto3,customtype=github.com/hyperledger/burrow/binary.HexBytes" json:"Return"`
+}
+
+func (m *CallEvent) Reset()                    { *m = CallEvent{} }
+func (m *CallEvent) String() string            { return proto.CompactTextString(m) }
+func (*CallEvent) ProtoMessage()               {}
+func (*CallEvent) Descriptor() ([]byte, []int) { return fileDescriptorExec, []int{7} }
+
+func (m *CallEvent) GetCallData() *CallData {
+	if m != nil {
+		return m.CallData
+	}
+	return nil
+}
+
+func (m *CallEvent) GetStackDepth() uint64 {
+	if m != nil {
+		return m.StackDepth
+	}
+	return 0
+}
+
+func (*CallEvent) XXX_MessageName() string {
+	return "exec.CallEvent"
+}
+
+type InputEvent struct {
+	Address github_com_hyperledger_burrow_crypto.Address `protobuf:"bytes,1,opt,name=Address,proto3,customtype=github.com/hyperledger/burrow/crypto.Address" json:"Address"`
+}
+
+func (m *InputEvent) Reset()                    { *m = InputEvent{} }
+func (m *InputEvent) String() string            { return proto.CompactTextString(m) }
+func (*InputEvent) ProtoMessage()               {}
+func (*InputEvent) Descriptor() ([]byte, []int) { return fileDescriptorExec, []int{8} }
+
+func (*InputEvent) XXX_MessageName() string {
+	return "exec.InputEvent"
+}
+
+type OutputEvent struct {
+	Address github_com_hyperledger_burrow_crypto.Address `protobuf:"bytes,1,opt,name=Address,proto3,customtype=github.com/hyperledger/burrow/crypto.Address" json:"Address"`
+}
+
+func (m *OutputEvent) Reset()                    { *m = OutputEvent{} }
+func (m *OutputEvent) String() string            { return proto.CompactTextString(m) }
+func (*OutputEvent) ProtoMessage()               {}
+func (*OutputEvent) Descriptor() ([]byte, []int) { return fileDescriptorExec, []int{9} }
+
+func (*OutputEvent) XXX_MessageName() string {
+	return "exec.OutputEvent"
+}
+
+type CallData struct {
+	Caller github_com_hyperledger_burrow_crypto.Address  `protobuf:"bytes,1,opt,name=Caller,proto3,customtype=github.com/hyperledger/burrow/crypto.Address" json:"Caller"`
+	Callee github_com_hyperledger_burrow_crypto.Address  `protobuf:"bytes,2,opt,name=Callee,proto3,customtype=github.com/hyperledger/burrow/crypto.Address" json:"Callee"`
+	Data   github_com_hyperledger_burrow_binary.HexBytes `protobuf:"bytes,3,opt,name=Data,proto3,customtype=github.com/hyperledger/burrow/binary.HexBytes" json:"Data"`
+	Value  uint64                                        `protobuf:"varint,4,opt,name=Value,proto3" json:"Value,omitempty"`
+	Gas    uint64                                        `protobuf:"varint,5,opt,name=Gas,proto3" json:"Gas,omitempty"`
+}
+
+func (m *CallData) Reset()                    { *m = CallData{} }
+func (m *CallData) String() string            { return proto.CompactTextString(m) }
+func (*CallData) ProtoMessage()               {}
+func (*CallData) Descriptor() ([]byte, []int) { return fileDescriptorExec, []int{10} }
+
+func (m *CallData) GetValue() uint64 {
+	if m != nil {
+		return m.Value
+	}
+	return 0
+}
+
+func (m *CallData) GetGas() uint64 {
+	if m != nil {
+		return m.Gas
+	}
+	return 0
+}
+
+func (*CallData) XXX_MessageName() string {
+	return "exec.CallData"
+}
+func init() {
+	proto.RegisterType((*BlockExecution)(nil), "exec.BlockExecution")
+	golang_proto.RegisterType((*BlockExecution)(nil), "exec.BlockExecution")
+	proto.RegisterType((*BlockHeader)(nil), "exec.BlockHeader")
+	golang_proto.RegisterType((*BlockHeader)(nil), "exec.BlockHeader")
+	proto.RegisterType((*TxExecution)(nil), "exec.TxExecution")
+	golang_proto.RegisterType((*TxExecution)(nil), "exec.TxExecution")
+	proto.RegisterType((*Header)(nil), "exec.Header")
+	golang_proto.RegisterType((*Header)(nil), "exec.Header")
+	proto.RegisterType((*Event)(nil), "exec.Event")
+	golang_proto.RegisterType((*Event)(nil), "exec.Event")
+	proto.RegisterType((*Result)(nil), "exec.Result")
+	golang_proto.RegisterType((*Result)(nil), "exec.Result")
+	proto.RegisterType((*LogEvent)(nil), "exec.LogEvent")
+	golang_proto.RegisterType((*LogEvent)(nil), "exec.LogEvent")
+	proto.RegisterType((*CallEvent)(nil), "exec.CallEvent")
+	golang_proto.RegisterType((*CallEvent)(nil), "exec.CallEvent")
+	proto.RegisterType((*InputEvent)(nil), "exec.InputEvent")
+	golang_proto.RegisterType((*InputEvent)(nil), "exec.InputEvent")
+	proto.RegisterType((*OutputEvent)(nil), "exec.OutputEvent")
+	golang_proto.RegisterType((*OutputEvent)(nil), "exec.OutputEvent")
+	proto.RegisterType((*CallData)(nil), "exec.CallData")
+	golang_proto.RegisterType((*CallData)(nil), "exec.CallData")
+}
+func (m *BlockExecution) Marshal() (dAtA []byte, err error) {
+	size := m.Size()
+	dAtA = make([]byte, size)
+	n, err := m.MarshalTo(dAtA)
+	if err != nil {
+		return nil, err
+	}
+	return dAtA[:n], nil
+}
+
+func (m *BlockExecution) MarshalTo(dAtA []byte) (int, error) {
+	var i int
+	_ = i
+	var l int
+	_ = l
+	if m.Height != 0 {
+		dAtA[i] = 0x8
+		i++
+		i = encodeVarintExec(dAtA, i, uint64(m.Height))
+	}
+	if m.BlockHeader != nil {
+		dAtA[i] = 0x12
+		i++
+		i = encodeVarintExec(dAtA, i, uint64(m.BlockHeader.Size()))
+		n1, err := m.BlockHeader.MarshalTo(dAtA[i:])
+		if err != nil {
+			return 0, err
+		}
+		i += n1
+	}
+	if len(m.TxExecutions) > 0 {
+		for _, msg := range m.TxExecutions {
+			dAtA[i] = 0x1a
+			i++
+			i = encodeVarintExec(dAtA, i, uint64(msg.Size()))
+			n, err := msg.MarshalTo(dAtA[i:])
+			if err != nil {
+				return 0, err
+			}
+			i += n
+		}
+	}
+	return i, nil
+}
+
+func (m *BlockHeader) Marshal() (dAtA []byte, err error) {
+	size := m.Size()
+	dAtA = make([]byte, size)
+	n, err := m.MarshalTo(dAtA)
+	if err != nil {
+		return nil, err
+	}
+	return dAtA[:n], nil
+}
+
+func (m *BlockHeader) MarshalTo(dAtA []byte) (int, error) {
+	var i int
+	_ = i
+	var l int
+	_ = l
+	if len(m.JSON) > 0 {
+		dAtA[i] = 0xa
+		i++
+		i = encodeVarintExec(dAtA, i, uint64(len(m.JSON)))
+		i += copy(dAtA[i:], m.JSON)
+	}
+	if m.NumTxs != 0 {
+		dAtA[i] = 0x10
+		i++
+		i = encodeVarintExec(dAtA, i, uint64(m.NumTxs))
+	}
+	return i, nil
+}
+
+func (m *TxExecution) Marshal() (dAtA []byte, err error) {
+	size := m.Size()
+	dAtA = make([]byte, size)
+	n, err := m.MarshalTo(dAtA)
+	if err != nil {
+		return nil, err
+	}
+	return dAtA[:n], nil
+}
+
+func (m *TxExecution) MarshalTo(dAtA []byte) (int, error) {
+	var i int
+	_ = i
+	var l int
+	_ = l
+	if m.TxType != 0 {
+		dAtA[i] = 0x10
+		i++
+		i = encodeVarintExec(dAtA, i, uint64(m.TxType))
+	}
+	dAtA[i] = 0x1a
+	i++
+	i = encodeVarintExec(dAtA, i, uint64(m.TxHash.Size()))
+	n2, err := m.TxHash.MarshalTo(dAtA[i:])
+	if err != nil {
+		return 0, err
+	}
+	i += n2
+	if m.Height != 0 {
+		dAtA[i] = 0x20
+		i++
+		i = encodeVarintExec(dAtA, i, uint64(m.Height))
+	}
+	if m.Index != 0 {
+		dAtA[i] = 0x28
+		i++
+		i = encodeVarintExec(dAtA, i, uint64(m.Index))
+	}
+	if m.Envelope != nil {
+		dAtA[i] = 0x32
+		i++
+		i = encodeVarintExec(dAtA, i, uint64(m.Envelope.Size()))
+		n3, err := m.Envelope.MarshalTo(dAtA[i:])
+		if err != nil {
+			return 0, err
+		}
+		i += n3
+	}
+	if len(m.Events) > 0 {
+		for _, msg := range m.Events {
+			dAtA[i] = 0x3a
+			i++
+			i = encodeVarintExec(dAtA, i, uint64(msg.Size()))
+			n, err := msg.MarshalTo(dAtA[i:])
+			if err != nil {
+				return 0, err
+			}
+			i += n
+		}
+	}
+	if m.Result != nil {
+		dAtA[i] = 0x42
+		i++
+		i = encodeVarintExec(dAtA, i, uint64(m.Result.Size()))
+		n4, err := m.Result.MarshalTo(dAtA[i:])
+		if err != nil {
+			return 0, err
+		}
+		i += n4
+	}
+	if m.Receipt != nil {
+		dAtA[i] = 0x4a
+		i++
+		i = encodeVarintExec(dAtA, i, uint64(m.Receipt.Size()))
+		n5, err := m.Receipt.MarshalTo(dAtA[i:])
+		if err != nil {
+			return 0, err
+		}
+		i += n5
+	}
+	if m.Exception != nil {
+		dAtA[i] = 0x52
+		i++
+		i = encodeVarintExec(dAtA, i, uint64(m.Exception.Size()))
+		n6, err := m.Exception.MarshalTo(dAtA[i:])
+		if err != nil {
+			return 0, err
+		}
+		i += n6
+	}
+	return i, nil
+}
+
+func (m *Header) Marshal() (dAtA []byte, err error) {
+	size := m.Size()
+	dAtA = make([]byte, size)
+	n, err := m.MarshalTo(dAtA)
+	if err != nil {
+		return nil, err
+	}
+	return dAtA[:n], nil
+}
+
+func (m *Header) MarshalTo(dAtA []byte) (int, error) {
+	var i int
+	_ = i
+	var l int
+	_ = l
+	if m.TxType != 0 {
+		dAtA[i] = 0x8
+		i++
+		i = encodeVarintExec(dAtA, i, uint64(m.TxType))
+	}
+	dAtA[i] = 0x12
+	i++
+	i = encodeVarintExec(dAtA, i, uint64(m.TxHash.Size()))
+	n7, err := m.TxHash.MarshalTo(dAtA[i:])
+	if err != nil {
+		return 0, err
+	}
+	i += n7
+	if m.EventType != 0 {
+		dAtA[i] = 0x18
+		i++
+		i = encodeVarintExec(dAtA, i, uint64(m.EventType))
+	}
+	if len(m.EventID) > 0 {
+		dAtA[i] = 0x22
+		i++
+		i = encodeVarintExec(dAtA, i, uint64(len(m.EventID)))
+		i += copy(dAtA[i:], m.EventID)
+	}
+	if m.Height != 0 {
+		dAtA[i] = 0x28
+		i++
+		i = encodeVarintExec(dAtA, i, uint64(m.Height))
+	}
+	if m.Index != 0 {
+		dAtA[i] = 0x30
+		i++
+		i = encodeVarintExec(dAtA, i, uint64(m.Index))
+	}
+	if m.Exception != nil {
+		dAtA[i] = 0x3a
+		i++
+		i = encodeVarintExec(dAtA, i, uint64(m.Exception.Size()))
+		n8, err := m.Exception.MarshalTo(dAtA[i:])
+		if err != nil {
+			return 0, err
+		}
+		i += n8
+	}
+	return i, nil
+}
+
+func (m *Event) Marshal() (dAtA []byte, err error) {
+	size := m.Size()
+	dAtA = make([]byte, size)
+	n, err := m.MarshalTo(dAtA)
+	if err != nil {
+		return nil, err
+	}
+	return dAtA[:n], nil
+}
+
+func (m *Event) MarshalTo(dAtA []byte) (int, error) {
+	var i int
+	_ = i
+	var l int
+	_ = l
+	if m.Header != nil {
+		dAtA[i] = 0xa
+		i++
+		i = encodeVarintExec(dAtA, i, uint64(m.Header.Size()))
+		n9, err := m.Header.MarshalTo(dAtA[i:])
+		if err != nil {
+			return 0, err
+		}
+		i += n9
+	}
+	if m.Input != nil {
+		dAtA[i] = 0x12
+		i++
+		i = encodeVarintExec(dAtA, i, uint64(m.Input.Size()))
+		n10, err := m.Input.MarshalTo(dAtA[i:])
+		if err != nil {
+			return 0, err
+		}
+		i += n10
+	}
+	if m.Output != nil {
+		dAtA[i] = 0x1a
+		i++
+		i = encodeVarintExec(dAtA, i, uint64(m.Output.Size()))
+		n11, err := m.Output.MarshalTo(dAtA[i:])
+		if err != nil {
+			return 0, err
+		}
+		i += n11
+	}
+	if m.Call != nil {
+		dAtA[i] = 0x22
+		i++
+		i = encodeVarintExec(dAtA, i, uint64(m.Call.Size()))
+		n12, err := m.Call.MarshalTo(dAtA[i:])
+		if err != nil {
+			return 0, err
+		}
+		i += n12
+	}
+	if m.Log != nil {
+		dAtA[i] = 0x2a
+		i++
+		i = encodeVarintExec(dAtA, i, uint64(m.Log.Size()))
+		n13, err := m.Log.MarshalTo(dAtA[i:])
+		if err != nil {
+			return 0, err
+		}
+		i += n13
+	}
+	return i, nil
+}
+
+func (m *Result) Marshal() (dAtA []byte, err error) {
+	size := m.Size()
+	dAtA = make([]byte, size)
+	n, err := m.MarshalTo(dAtA)
+	if err != nil {
+		return nil, err
+	}
+	return dAtA[:n], nil
+}
+
+func (m *Result) MarshalTo(dAtA []byte) (int, error) {
+	var i int
+	_ = i
+	var l int
+	_ = l
+	if len(m.Return) > 0 {
+		dAtA[i] = 0xa
+		i++
+		i = encodeVarintExec(dAtA, i, uint64(len(m.Return)))
+		i += copy(dAtA[i:], m.Return)
+	}
+	if m.GasUsed != 0 {
+		dAtA[i] = 0x10
+		i++
+		i = encodeVarintExec(dAtA, i, uint64(m.GasUsed))
+	}
+	if m.NameEntry != nil {
+		dAtA[i] = 0x1a
+		i++
+		i = encodeVarintExec(dAtA, i, uint64(m.NameEntry.Size()))
+		n14, err := m.NameEntry.MarshalTo(dAtA[i:])
+		if err != nil {
+			return 0, err
+		}
+		i += n14
+	}
+	if m.PermArgs != nil {
+		dAtA[i] = 0x22
+		i++
+		i = encodeVarintExec(dAtA, i, uint64(m.PermArgs.Size()))
+		n15, err := m.PermArgs.MarshalTo(dAtA[i:])
+		if err != nil {
+			return 0, err
+		}
+		i += n15
+	}
+	return i, nil
+}
+
+func (m *LogEvent) Marshal() (dAtA []byte, err error) {
+	size := m.Size()
+	dAtA = make([]byte, size)
+	n, err := m.MarshalTo(dAtA)
+	if err != nil {
+		return nil, err
+	}
+	return dAtA[:n], nil
+}
+
+func (m *LogEvent) MarshalTo(dAtA []byte) (int, error) {
+	var i int
+	_ = i
+	var l int
+	_ = l
+	dAtA[i] = 0xa
+	i++
+	i = encodeVarintExec(dAtA, i, uint64(m.Address.Size()))
+	n16, err := m.Address.MarshalTo(dAtA[i:])
+	if err != nil {
+		return 0, err
+	}
+	i += n16
+	dAtA[i] = 0x12
+	i++
+	i = encodeVarintExec(dAtA, i, uint64(m.Data.Size()))
+	n17, err := m.Data.MarshalTo(dAtA[i:])
+	if err != nil {
+		return 0, err
+	}
+	i += n17
+	if len(m.Topics) > 0 {
+		for _, msg := range m.Topics {
+			dAtA[i] = 0x1a
+			i++
+			i = encodeVarintExec(dAtA, i, uint64(msg.Size()))
+			n, err := msg.MarshalTo(dAtA[i:])
+			if err != nil {
+				return 0, err
+			}
+			i += n
+		}
+	}
+	return i, nil
+}
+
+func (m *CallEvent) Marshal() (dAtA []byte, err error) {
+	size := m.Size()
+	dAtA = make([]byte, size)
+	n, err := m.MarshalTo(dAtA)
+	if err != nil {
+		return nil, err
+	}
+	return dAtA[:n], nil
+}
+
+func (m *CallEvent) MarshalTo(dAtA []byte) (int, error) {
+	var i int
+	_ = i
+	var l int
+	_ = l
+	if m.CallData != nil {
+		dAtA[i] = 0xa
+		i++
+		i = encodeVarintExec(dAtA, i, uint64(m.CallData.Size()))
+		n18, err := m.CallData.MarshalTo(dAtA[i:])
+		if err != nil {
+			return 0, err
+		}
+		i += n18
+	}
+	dAtA[i] = 0x12
+	i++
+	i = encodeVarintExec(dAtA, i, uint64(m.Origin.Size()))
+	n19, err := m.Origin.MarshalTo(dAtA[i:])
+	if err != nil {
+		return 0, err
+	}
+	i += n19
+	if m.StackDepth != 0 {
+		dAtA[i] = 0x18
+		i++
+		i = encodeVarintExec(dAtA, i, uint64(m.StackDepth))
+	}
+	dAtA[i] = 0x22
+	i++
+	i = encodeVarintExec(dAtA, i, uint64(m.Return.Size()))
+	n20, err := m.Return.MarshalTo(dAtA[i:])
+	if err != nil {
+		return 0, err
+	}
+	i += n20
+	return i, nil
+}
+
+func (m *InputEvent) Marshal() (dAtA []byte, err error) {
+	size := m.Size()
+	dAtA = make([]byte, size)
+	n, err := m.MarshalTo(dAtA)
+	if err != nil {
+		return nil, err
+	}
+	return dAtA[:n], nil
+}
+
+func (m *InputEvent) MarshalTo(dAtA []byte) (int, error) {
+	var i int
+	_ = i
+	var l int
+	_ = l
+	dAtA[i] = 0xa
+	i++
+	i = encodeVarintExec(dAtA, i, uint64(m.Address.Size()))
+	n21, err := m.Address.MarshalTo(dAtA[i:])
+	if err != nil {
+		return 0, err
+	}
+	i += n21
+	return i, nil
+}
+
+func (m *OutputEvent) Marshal() (dAtA []byte, err error) {
+	size := m.Size()
+	dAtA = make([]byte, size)
+	n, err := m.MarshalTo(dAtA)
+	if err != nil {
+		return nil, err
+	}
+	return dAtA[:n], nil
+}
+
+func (m *OutputEvent) MarshalTo(dAtA []byte) (int, error) {
+	var i int
+	_ = i
+	var l int
+	_ = l
+	dAtA[i] = 0xa
+	i++
+	i = encodeVarintExec(dAtA, i, uint64(m.Address.Size()))
+	n22, err := m.Address.MarshalTo(dAtA[i:])
+	if err != nil {
+		return 0, err
+	}
+	i += n22
+	return i, nil
+}
+
+func (m *CallData) Marshal() (dAtA []byte, err error) {
+	size := m.Size()
+	dAtA = make([]byte, size)
+	n, err := m.MarshalTo(dAtA)
+	if err != nil {
+		return nil, err
+	}
+	return dAtA[:n], nil
+}
+
+func (m *CallData) MarshalTo(dAtA []byte) (int, error) {
+	var i int
+	_ = i
+	var l int
+	_ = l
+	dAtA[i] = 0xa
+	i++
+	i = encodeVarintExec(dAtA, i, uint64(m.Caller.Size()))
+	n23, err := m.Caller.MarshalTo(dAtA[i:])
+	if err != nil {
+		return 0, err
+	}
+	i += n23
+	dAtA[i] = 0x12
+	i++
+	i = encodeVarintExec(dAtA, i, uint64(m.Callee.Size()))
+	n24, err := m.Callee.MarshalTo(dAtA[i:])
+	if err != nil {
+		return 0, err
+	}
+	i += n24
+	dAtA[i] = 0x1a
+	i++
+	i = encodeVarintExec(dAtA, i, uint64(m.Data.Size()))
+	n25, err := m.Data.MarshalTo(dAtA[i:])
+	if err != nil {
+		return 0, err
+	}
+	i += n25
+	if m.Value != 0 {
+		dAtA[i] = 0x20
+		i++
+		i = encodeVarintExec(dAtA, i, uint64(m.Value))
+	}
+	if m.Gas != 0 {
+		dAtA[i] = 0x28
+		i++
+		i = encodeVarintExec(dAtA, i, uint64(m.Gas))
+	}
+	return i, nil
+}
+
+func encodeVarintExec(dAtA []byte, offset int, v uint64) int {
+	for v >= 1<<7 {
+		dAtA[offset] = uint8(v&0x7f | 0x80)
+		v >>= 7
+		offset++
+	}
+	dAtA[offset] = uint8(v)
+	return offset + 1
+}
+func (m *BlockExecution) Size() (n int) {
+	var l int
+	_ = l
+	if m.Height != 0 {
+		n += 1 + sovExec(uint64(m.Height))
+	}
+	if m.BlockHeader != nil {
+		l = m.BlockHeader.Size()
+		n += 1 + l + sovExec(uint64(l))
+	}
+	if len(m.TxExecutions) > 0 {
+		for _, e := range m.TxExecutions {
+			l = e.Size()
+			n += 1 + l + sovExec(uint64(l))
+		}
+	}
+	return n
+}
+
+func (m *BlockHeader) Size() (n int) {
+	var l int
+	_ = l
+	l = len(m.JSON)
+	if l > 0 {
+		n += 1 + l + sovExec(uint64(l))
+	}
+	if m.NumTxs != 0 {
+		n += 1 + sovExec(uint64(m.NumTxs))
+	}
+	return n
+}
+
+func (m *TxExecution) Size() (n int) {
+	var l int
+	_ = l
+	if m.TxType != 0 {
+		n += 1 + sovExec(uint64(m.TxType))
+	}
+	l = m.TxHash.Size()
+	n += 1 + l + sovExec(uint64(l))
+	if m.Height != 0 {
+		n += 1 + sovExec(uint64(m.Height))
+	}
+	if m.Index != 0 {
+		n += 1 + sovExec(uint64(m.Index))
+	}
+	if m.Envelope != nil {
+		l = m.Envelope.Size()
+		n += 1 + l + sovExec(uint64(l))
+	}
+	if len(m.Events) > 0 {
+		for _, e := range m.Events {
+			l = e.Size()
+			n += 1 + l + sovExec(uint64(l))
+		}
+	}
+	if m.Result != nil {
+		l = m.Result.Size()
+		n += 1 + l + sovExec(uint64(l))
+	}
+	if m.Receipt != nil {
+		l = m.Receipt.Size()
+		n += 1 + l + sovExec(uint64(l))
+	}
+	if m.Exception != nil {
+		l = m.Exception.Size()
+		n += 1 + l + sovExec(uint64(l))
+	}
+	return n
+}
+
+func (m *Header) Size() (n int) {
+	var l int
+	_ = l
+	if m.TxType != 0 {
+		n += 1 + sovExec(uint64(m.TxType))
+	}
+	l = m.TxHash.Size()
+	n += 1 + l + sovExec(uint64(l))
+	if m.EventType != 0 {
+		n += 1 + sovExec(uint64(m.EventType))
+	}
+	l = len(m.EventID)
+	if l > 0 {
+		n += 1 + l + sovExec(uint64(l))
+	}
+	if m.Height != 0 {
+		n += 1 + sovExec(uint64(m.Height))
+	}
+	if m.Index != 0 {
+		n += 1 + sovExec(uint64(m.Index))
+	}
+	if m.Exception != nil {
+		l = m.Exception.Size()
+		n += 1 + l + sovExec(uint64(l))
+	}
+	return n
+}
+
+func (m *Event) Size() (n int) {
+	var l int
+	_ = l
+	if m.Header != nil {
+		l = m.Header.Size()
+		n += 1 + l + sovExec(uint64(l))
+	}
+	if m.Input != nil {
+		l = m.Input.Size()
+		n += 1 + l + sovExec(uint64(l))
+	}
+	if m.Output != nil {
+		l = m.Output.Size()
+		n += 1 + l + sovExec(uint64(l))
+	}
+	if m.Call != nil {
+		l = m.Call.Size()
+		n += 1 + l + sovExec(uint64(l))
+	}
+	if m.Log != nil {
+		l = m.Log.Size()
+		n += 1 + l + sovExec(uint64(l))
+	}
+	return n
+}
+
+func (m *Result) Size() (n int) {
+	var l int
+	_ = l
+	l = len(m.Return)
+	if l > 0 {
+		n += 1 + l + sovExec(uint64(l))
+	}
+	if m.GasUsed != 0 {
+		n += 1 + sovExec(uint64(m.GasUsed))
+	}
+	if m.NameEntry != nil {
+		l = m.NameEntry.Size()
+		n += 1 + l + sovExec(uint64(l))
+	}
+	if m.PermArgs != nil {
+		l = m.PermArgs.Size()
+		n += 1 + l + sovExec(uint64(l))
+	}
+	return n
+}
+
+func (m *LogEvent) Size() (n int) {
+	var l int
+	_ = l
+	l = m.Address.Size()
+	n += 1 + l + sovExec(uint64(l))
+	l = m.Data.Size()
+	n += 1 + l + sovExec(uint64(l))
+	if len(m.Topics) > 0 {
+		for _, e := range m.Topics {
+			l = e.Size()
+			n += 1 + l + sovExec(uint64(l))
+		}
+	}
+	return n
+}
+
+func (m *CallEvent) Size() (n int) {
+	var l int
+	_ = l
+	if m.CallData != nil {
+		l = m.CallData.Size()
+		n += 1 + l + sovExec(uint64(l))
+	}
+	l = m.Origin.Size()
+	n += 1 + l + sovExec(uint64(l))
+	if m.StackDepth != 0 {
+		n += 1 + sovExec(uint64(m.StackDepth))
+	}
+	l = m.Return.Size()
+	n += 1 + l + sovExec(uint64(l))
+	return n
+}
+
+func (m *InputEvent) Size() (n int) {
+	var l int
+	_ = l
+	l = m.Address.Size()
+	n += 1 + l + sovExec(uint64(l))
+	return n
+}
+
+func (m *OutputEvent) Size() (n int) {
+	var l int
+	_ = l
+	l = m.Address.Size()
+	n += 1 + l + sovExec(uint64(l))
+	return n
+}
+
+func (m *CallData) Size() (n int) {
+	var l int
+	_ = l
+	l = m.Caller.Size()
+	n += 1 + l + sovExec(uint64(l))
+	l = m.Callee.Size()
+	n += 1 + l + sovExec(uint64(l))
+	l = m.Data.Size()
+	n += 1 + l + sovExec(uint64(l))
+	if m.Value != 0 {
+		n += 1 + sovExec(uint64(m.Value))
+	}
+	if m.Gas != 0 {
+		n += 1 + sovExec(uint64(m.Gas))
+	}
+	return n
+}
+
+func sovExec(x uint64) (n int) {
+	for {
+		n++
+		x >>= 7
+		if x == 0 {
+			break
+		}
+	}
+	return n
+}
+func sozExec(x uint64) (n int) {
+	return sovExec(uint64((x << 1) ^ uint64((int64(x) >> 63))))
+}
+func (m *BlockExecution) Unmarshal(dAtA []byte) error {
+	l := len(dAtA)
+	iNdEx := 0
+	for iNdEx < l {
+		preIndex := iNdEx
+		var wire uint64
+		for shift := uint(0); ; shift += 7 {
+			if shift >= 64 {
+				return ErrIntOverflowExec
+			}
+			if iNdEx >= l {
+				return io.ErrUnexpectedEOF
+			}
+			b := dAtA[iNdEx]
+			iNdEx++
+			wire |= (uint64(b) & 0x7F) << shift
+			if b < 0x80 {
+				break
+			}
+		}
+		fieldNum := int32(wire >> 3)
+		wireType := int(wire & 0x7)
+		if wireType == 4 {
+			return fmt.Errorf("proto: BlockExecution: wiretype end group for non-group")
+		}
+		if fieldNum <= 0 {
+			return fmt.Errorf("proto: BlockExecution: illegal tag %d (wire type %d)", fieldNum, wire)
+		}
+		switch fieldNum {
+		case 1:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Height", wireType)
+			}
+			m.Height = 0
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowExec
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				m.Height |= (uint64(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+		case 2:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field BlockHeader", wireType)
+			}
+			var msglen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowExec
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				msglen |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if msglen < 0 {
+				return ErrInvalidLengthExec
+			}
+			postIndex := iNdEx + msglen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			if m.BlockHeader == nil {
+				m.BlockHeader = &BlockHeader{}
+			}
+			if err := m.BlockHeader.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+				return err
+			}
+			iNdEx = postIndex
+		case 3:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field TxExecutions", wireType)
+			}
+			var msglen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowExec
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				msglen |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if msglen < 0 {
+				return ErrInvalidLengthExec
+			}
+			postIndex := iNdEx + msglen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			m.TxExecutions = append(m.TxExecutions, &TxExecution{})
+			if err := m.TxExecutions[len(m.TxExecutions)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+				return err
+			}
+			iNdEx = postIndex
+		default:
+			iNdEx = preIndex
+			skippy, err := skipExec(dAtA[iNdEx:])
+			if err != nil {
+				return err
+			}
+			if skippy < 0 {
+				return ErrInvalidLengthExec
+			}
+			if (iNdEx + skippy) > l {
+				return io.ErrUnexpectedEOF
+			}
+			iNdEx += skippy
+		}
+	}
+
+	if iNdEx > l {
+		return io.ErrUnexpectedEOF
+	}
+	return nil
+}
+func (m *BlockHeader) Unmarshal(dAtA []byte) error {
+	l := len(dAtA)
+	iNdEx := 0
+	for iNdEx < l {
+		preIndex := iNdEx
+		var wire uint64
+		for shift := uint(0); ; shift += 7 {
+			if shift >= 64 {
+				return ErrIntOverflowExec
+			}
+			if iNdEx >= l {
+				return io.ErrUnexpectedEOF
+			}
+			b := dAtA[iNdEx]
+			iNdEx++
+			wire |= (uint64(b) & 0x7F) << shift
+			if b < 0x80 {
+				break
+			}
+		}
+		fieldNum := int32(wire >> 3)
+		wireType := int(wire & 0x7)
+		if wireType == 4 {
+			return fmt.Errorf("proto: BlockHeader: wiretype end group for non-group")
+		}
+		if fieldNum <= 0 {
+			return fmt.Errorf("proto: BlockHeader: illegal tag %d (wire type %d)", fieldNum, wire)
+		}
+		switch fieldNum {
+		case 1:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field JSON", wireType)
+			}
+			var stringLen uint64
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowExec
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				stringLen |= (uint64(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			intStringLen := int(stringLen)
+			if intStringLen < 0 {
+				return ErrInvalidLengthExec
+			}
+			postIndex := iNdEx + intStringLen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			m.JSON = string(dAtA[iNdEx:postIndex])
+			iNdEx = postIndex
+		case 2:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field NumTxs", wireType)
+			}
+			m.NumTxs = 0
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowExec
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				m.NumTxs |= (int32(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+		default:
+			iNdEx = preIndex
+			skippy, err := skipExec(dAtA[iNdEx:])
+			if err != nil {
+				return err
+			}
+			if skippy < 0 {
+				return ErrInvalidLengthExec
+			}
+			if (iNdEx + skippy) > l {
+				return io.ErrUnexpectedEOF
+			}
+			iNdEx += skippy
+		}
+	}
+
+	if iNdEx > l {
+		return io.ErrUnexpectedEOF
+	}
+	return nil
+}
+func (m *TxExecution) Unmarshal(dAtA []byte) error {
+	l := len(dAtA)
+	iNdEx := 0
+	for iNdEx < l {
+		preIndex := iNdEx
+		var wire uint64
+		for shift := uint(0); ; shift += 7 {
+			if shift >= 64 {
+				return ErrIntOverflowExec
+			}
+			if iNdEx >= l {
+				return io.ErrUnexpectedEOF
+			}
+			b := dAtA[iNdEx]
+			iNdEx++
+			wire |= (uint64(b) & 0x7F) << shift
+			if b < 0x80 {
+				break
+			}
+		}
+		fieldNum := int32(wire >> 3)
+		wireType := int(wire & 0x7)
+		if wireType == 4 {
+			return fmt.Errorf("proto: TxExecution: wiretype end group for non-group")
+		}
+		if fieldNum <= 0 {
+			return fmt.Errorf("proto: TxExecution: illegal tag %d (wire type %d)", fieldNum, wire)
+		}
+		switch fieldNum {
+		case 2:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field TxType", wireType)
+			}
+			m.TxType = 0
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowExec
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				m.TxType |= (github_com_hyperledger_burrow_txs_payload.Type(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+		case 3:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field TxHash", wireType)
+			}
+			var byteLen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowExec
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				byteLen |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if byteLen < 0 {
+				return ErrInvalidLengthExec
+			}
+			postIndex := iNdEx + byteLen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			if err := m.TxHash.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+				return err
+			}
+			iNdEx = postIndex
+		case 4:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Height", wireType)
+			}
+			m.Height = 0
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowExec
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				m.Height |= (uint64(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+		case 5:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Index", wireType)
+			}
+			m.Index = 0
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowExec
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				m.Index |= (uint64(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+		case 6:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Envelope", wireType)
+			}
+			var msglen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowExec
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				msglen |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if msglen < 0 {
+				return ErrInvalidLengthExec
+			}
+			postIndex := iNdEx + msglen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			if m.Envelope == nil {
+				m.Envelope = &github_com_hyperledger_burrow_txs.Envelope{}
+			}
+			if err := m.Envelope.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+				return err
+			}
+			iNdEx = postIndex
+		case 7:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Events", wireType)
+			}
+			var msglen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowExec
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				msglen |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if msglen < 0 {
+				return ErrInvalidLengthExec
+			}
+			postIndex := iNdEx + msglen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			m.Events = append(m.Events, &Event{})
+			if err := m.Events[len(m.Events)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+				return err
+			}
+			iNdEx = postIndex
+		case 8:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Result", wireType)
+			}
+			var msglen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowExec
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				msglen |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if msglen < 0 {
+				return ErrInvalidLengthExec
+			}
+			postIndex := iNdEx + msglen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			if m.Result == nil {
+				m.Result = &Result{}
+			}
+			if err := m.Result.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+				return err
+			}
+			iNdEx = postIndex
+		case 9:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Receipt", wireType)
+			}
+			var msglen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowExec
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				msglen |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if msglen < 0 {
+				return ErrInvalidLengthExec
+			}
+			postIndex := iNdEx + msglen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			if m.Receipt == nil {
+				m.Receipt = &txs.Receipt{}
+			}
+			if err := m.Receipt.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+				return err
+			}
+			iNdEx = postIndex
+		case 10:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Exception", wireType)
+			}
+			var msglen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowExec
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				msglen |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if msglen < 0 {
+				return ErrInvalidLengthExec
+			}
+			postIndex := iNdEx + msglen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			if m.Exception == nil {
+				m.Exception = &errors.Exception{}
+			}
+			if err := m.Exception.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+				return err
+			}
+			iNdEx = postIndex
+		default:
+			iNdEx = preIndex
+			skippy, err := skipExec(dAtA[iNdEx:])
+			if err != nil {
+				return err
+			}
+			if skippy < 0 {
+				return ErrInvalidLengthExec
+			}
+			if (iNdEx + skippy) > l {
+				return io.ErrUnexpectedEOF
+			}
+			iNdEx += skippy
+		}
+	}
+
+	if iNdEx > l {
+		return io.ErrUnexpectedEOF
+	}
+	return nil
+}
+func (m *Header) Unmarshal(dAtA []byte) error {
+	l := len(dAtA)
+	iNdEx := 0
+	for iNdEx < l {
+		preIndex := iNdEx
+		var wire uint64
+		for shift := uint(0); ; shift += 7 {
+			if shift >= 64 {
+				return ErrIntOverflowExec
+			}
+			if iNdEx >= l {
+				return io.ErrUnexpectedEOF
+			}
+			b := dAtA[iNdEx]
+			iNdEx++
+			wire |= (uint64(b) & 0x7F) << shift
+			if b < 0x80 {
+				break
+			}
+		}
+		fieldNum := int32(wire >> 3)
+		wireType := int(wire & 0x7)
+		if wireType == 4 {
+			return fmt.Errorf("proto: Header: wiretype end group for non-group")
+		}
+		if fieldNum <= 0 {
+			return fmt.Errorf("proto: Header: illegal tag %d (wire type %d)", fieldNum, wire)
+		}
+		switch fieldNum {
+		case 1:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field TxType", wireType)
+			}
+			m.TxType = 0
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowExec
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				m.TxType |= (github_com_hyperledger_burrow_txs_payload.Type(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+		case 2:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field TxHash", wireType)
+			}
+			var byteLen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowExec
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				byteLen |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if byteLen < 0 {
+				return ErrInvalidLengthExec
+			}
+			postIndex := iNdEx + byteLen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			if err := m.TxHash.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+				return err
+			}
+			iNdEx = postIndex
+		case 3:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field EventType", wireType)
+			}
+			m.EventType = 0
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowExec
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				m.EventType |= (EventType(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+		case 4:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field EventID", wireType)
+			}
+			var stringLen uint64
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowExec
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				stringLen |= (uint64(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			intStringLen := int(stringLen)
+			if intStringLen < 0 {
+				return ErrInvalidLengthExec
+			}
+			postIndex := iNdEx + intStringLen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			m.EventID = string(dAtA[iNdEx:postIndex])
+			iNdEx = postIndex
+		case 5:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Height", wireType)
+			}
+			m.Height = 0
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowExec
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				m.Height |= (uint64(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+		case 6:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Index", wireType)
+			}
+			m.Index = 0
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowExec
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				m.Index |= (uint64(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+		case 7:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Exception", wireType)
+			}
+			var msglen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowExec
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				msglen |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if msglen < 0 {
+				return ErrInvalidLengthExec
+			}
+			postIndex := iNdEx + msglen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			if m.Exception == nil {
+				m.Exception = &errors.Exception{}
+			}
+			if err := m.Exception.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+				return err
+			}
+			iNdEx = postIndex
+		default:
+			iNdEx = preIndex
+			skippy, err := skipExec(dAtA[iNdEx:])
+			if err != nil {
+				return err
+			}
+			if skippy < 0 {
+				return ErrInvalidLengthExec
+			}
+			if (iNdEx + skippy) > l {
+				return io.ErrUnexpectedEOF
+			}
+			iNdEx += skippy
+		}
+	}
+
+	if iNdEx > l {
+		return io.ErrUnexpectedEOF
+	}
+	return nil
+}
+func (m *Event) Unmarshal(dAtA []byte) error {
+	l := len(dAtA)
+	iNdEx := 0
+	for iNdEx < l {
+		preIndex := iNdEx
+		var wire uint64
+		for shift := uint(0); ; shift += 7 {
+			if shift >= 64 {
+				return ErrIntOverflowExec
+			}
+			if iNdEx >= l {
+				return io.ErrUnexpectedEOF
+			}
+			b := dAtA[iNdEx]
+			iNdEx++
+			wire |= (uint64(b) & 0x7F) << shift
+			if b < 0x80 {
+				break
+			}
+		}
+		fieldNum := int32(wire >> 3)
+		wireType := int(wire & 0x7)
+		if wireType == 4 {
+			return fmt.Errorf("proto: Event: wiretype end group for non-group")
+		}
+		if fieldNum <= 0 {
+			return fmt.Errorf("proto: Event: illegal tag %d (wire type %d)", fieldNum, wire)
+		}
+		switch fieldNum {
+		case 1:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Header", wireType)
+			}
+			var msglen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowExec
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				msglen |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if msglen < 0 {
+				return ErrInvalidLengthExec
+			}
+			postIndex := iNdEx + msglen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			if m.Header == nil {
+				m.Header = &Header{}
+			}
+			if err := m.Header.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+				return err
+			}
+			iNdEx = postIndex
+		case 2:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Input", wireType)
+			}
+			var msglen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowExec
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				msglen |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if msglen < 0 {
+				return ErrInvalidLengthExec
+			}
+			postIndex := iNdEx + msglen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			if m.Input == nil {
+				m.Input = &InputEvent{}
+			}
+			if err := m.Input.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+				return err
+			}
+			iNdEx = postIndex
+		case 3:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Output", wireType)
+			}
+			var msglen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowExec
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				msglen |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if msglen < 0 {
+				return ErrInvalidLengthExec
+			}
+			postIndex := iNdEx + msglen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			if m.Output == nil {
+				m.Output = &OutputEvent{}
+			}
+			if err := m.Output.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+				return err
+			}
+			iNdEx = postIndex
+		case 4:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Call", wireType)
+			}
+			var msglen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowExec
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				msglen |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if msglen < 0 {
+				return ErrInvalidLengthExec
+			}
+			postIndex := iNdEx + msglen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			if m.Call == nil {
+				m.Call = &CallEvent{}
+			}
+			if err := m.Call.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+				return err
+			}
+			iNdEx = postIndex
+		case 5:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Log", wireType)
+			}
+			var msglen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowExec
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				msglen |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if msglen < 0 {
+				return ErrInvalidLengthExec
+			}
+			postIndex := iNdEx + msglen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			if m.Log == nil {
+				m.Log = &LogEvent{}
+			}
+			if err := m.Log.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+				return err
+			}
+			iNdEx = postIndex
+		default:
+			iNdEx = preIndex
+			skippy, err := skipExec(dAtA[iNdEx:])
+			if err != nil {
+				return err
+			}
+			if skippy < 0 {
+				return ErrInvalidLengthExec
+			}
+			if (iNdEx + skippy) > l {
+				return io.ErrUnexpectedEOF
+			}
+			iNdEx += skippy
+		}
+	}
+
+	if iNdEx > l {
+		return io.ErrUnexpectedEOF
+	}
+	return nil
+}
+func (m *Result) Unmarshal(dAtA []byte) error {
+	l := len(dAtA)
+	iNdEx := 0
+	for iNdEx < l {
+		preIndex := iNdEx
+		var wire uint64
+		for shift := uint(0); ; shift += 7 {
+			if shift >= 64 {
+				return ErrIntOverflowExec
+			}
+			if iNdEx >= l {
+				return io.ErrUnexpectedEOF
+			}
+			b := dAtA[iNdEx]
+			iNdEx++
+			wire |= (uint64(b) & 0x7F) << shift
+			if b < 0x80 {
+				break
+			}
+		}
+		fieldNum := int32(wire >> 3)
+		wireType := int(wire & 0x7)
+		if wireType == 4 {
+			return fmt.Errorf("proto: Result: wiretype end group for non-group")
+		}
+		if fieldNum <= 0 {
+			return fmt.Errorf("proto: Result: illegal tag %d (wire type %d)", fieldNum, wire)
+		}
+		switch fieldNum {
+		case 1:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Return", wireType)
+			}
+			var byteLen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowExec
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				byteLen |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if byteLen < 0 {
+				return ErrInvalidLengthExec
+			}
+			postIndex := iNdEx + byteLen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			m.Return = append(m.Return[:0], dAtA[iNdEx:postIndex]...)
+			if m.Return == nil {
+				m.Return = []byte{}
+			}
+			iNdEx = postIndex
+		case 2:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field GasUsed", wireType)
+			}
+			m.GasUsed = 0
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowExec
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				m.GasUsed |= (uint64(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+		case 3:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field NameEntry", wireType)
+			}
+			var msglen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowExec
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				msglen |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if msglen < 0 {
+				return ErrInvalidLengthExec
+			}
+			postIndex := iNdEx + msglen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			if m.NameEntry == nil {
+				m.NameEntry = &names.Entry{}
+			}
+			if err := m.NameEntry.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+				return err
+			}
+			iNdEx = postIndex
+		case 4:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field PermArgs", wireType)
+			}
+			var msglen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowExec
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				msglen |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if msglen < 0 {
+				return ErrInvalidLengthExec
+			}
+			postIndex := iNdEx + msglen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			if m.PermArgs == nil {
+				m.PermArgs = &permission.PermArgs{}
+			}
+			if err := m.PermArgs.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+				return err
+			}
+			iNdEx = postIndex
+		default:
+			iNdEx = preIndex
+			skippy, err := skipExec(dAtA[iNdEx:])
+			if err != nil {
+				return err
+			}
+			if skippy < 0 {
+				return ErrInvalidLengthExec
+			}
+			if (iNdEx + skippy) > l {
+				return io.ErrUnexpectedEOF
+			}
+			iNdEx += skippy
+		}
+	}
+
+	if iNdEx > l {
+		return io.ErrUnexpectedEOF
+	}
+	return nil
+}
+func (m *LogEvent) Unmarshal(dAtA []byte) error {
+	l := len(dAtA)
+	iNdEx := 0
+	for iNdEx < l {
+		preIndex := iNdEx
+		var wire uint64
+		for shift := uint(0); ; shift += 7 {
+			if shift >= 64 {
+				return ErrIntOverflowExec
+			}
+			if iNdEx >= l {
+				return io.ErrUnexpectedEOF
+			}
+			b := dAtA[iNdEx]
+			iNdEx++
+			wire |= (uint64(b) & 0x7F) << shift
+			if b < 0x80 {
+				break
+			}
+		}
+		fieldNum := int32(wire >> 3)
+		wireType := int(wire & 0x7)
+		if wireType == 4 {
+			return fmt.Errorf("proto: LogEvent: wiretype end group for non-group")
+		}
+		if fieldNum <= 0 {
+			return fmt.Errorf("proto: LogEvent: illegal tag %d (wire type %d)", fieldNum, wire)
+		}
+		switch fieldNum {
+		case 1:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Address", wireType)
+			}
+			var byteLen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowExec
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				byteLen |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if byteLen < 0 {
+				return ErrInvalidLengthExec
+			}
+			postIndex := iNdEx + byteLen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			if err := m.Address.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+				return err
+			}
+			iNdEx = postIndex
+		case 2:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Data", wireType)
+			}
+			var byteLen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowExec
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				byteLen |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if byteLen < 0 {
+				return ErrInvalidLengthExec
+			}
+			postIndex := iNdEx + byteLen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			if err := m.Data.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+				return err
+			}
+			iNdEx = postIndex
+		case 3:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Topics", wireType)
+			}
+			var byteLen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowExec
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				byteLen |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if byteLen < 0 {
+				return ErrInvalidLengthExec
+			}
+			postIndex := iNdEx + byteLen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			var v github_com_hyperledger_burrow_binary.Word256
+			m.Topics = append(m.Topics, v)
+			if err := m.Topics[len(m.Topics)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+				return err
+			}
+			iNdEx = postIndex
+		default:
+			iNdEx = preIndex
+			skippy, err := skipExec(dAtA[iNdEx:])
+			if err != nil {
+				return err
+			}
+			if skippy < 0 {
+				return ErrInvalidLengthExec
+			}
+			if (iNdEx + skippy) > l {
+				return io.ErrUnexpectedEOF
+			}
+			iNdEx += skippy
+		}
+	}
+
+	if iNdEx > l {
+		return io.ErrUnexpectedEOF
+	}
+	return nil
+}
+func (m *CallEvent) Unmarshal(dAtA []byte) error {
+	l := len(dAtA)
+	iNdEx := 0
+	for iNdEx < l {
+		preIndex := iNdEx
+		var wire uint64
+		for shift := uint(0); ; shift += 7 {
+			if shift >= 64 {
+				return ErrIntOverflowExec
+			}
+			if iNdEx >= l {
+				return io.ErrUnexpectedEOF
+			}
+			b := dAtA[iNdEx]
+			iNdEx++
+			wire |= (uint64(b) & 0x7F) << shift
+			if b < 0x80 {
+				break
+			}
+		}
+		fieldNum := int32(wire >> 3)
+		wireType := int(wire & 0x7)
+		if wireType == 4 {
+			return fmt.Errorf("proto: CallEvent: wiretype end group for non-group")
+		}
+		if fieldNum <= 0 {
+			return fmt.Errorf("proto: CallEvent: illegal tag %d (wire type %d)", fieldNum, wire)
+		}
+		switch fieldNum {
+		case 1:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field CallData", wireType)
+			}
+			var msglen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowExec
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				msglen |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if msglen < 0 {
+				return ErrInvalidLengthExec
+			}
+			postIndex := iNdEx + msglen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			if m.CallData == nil {
+				m.CallData = &CallData{}
+			}
+			if err := m.CallData.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+				return err
+			}
+			iNdEx = postIndex
+		case 2:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Origin", wireType)
+			}
+			var byteLen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowExec
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				byteLen |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if byteLen < 0 {
+				return ErrInvalidLengthExec
+			}
+			postIndex := iNdEx + byteLen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			if err := m.Origin.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+				return err
+			}
+			iNdEx = postIndex
+		case 3:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field StackDepth", wireType)
+			}
+			m.StackDepth = 0
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowExec
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				m.StackDepth |= (uint64(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+		case 4:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Return", wireType)
+			}
+			var byteLen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowExec
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				byteLen |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if byteLen < 0 {
+				return ErrInvalidLengthExec
+			}
+			postIndex := iNdEx + byteLen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			if err := m.Return.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+				return err
+			}
+			iNdEx = postIndex
+		default:
+			iNdEx = preIndex
+			skippy, err := skipExec(dAtA[iNdEx:])
+			if err != nil {
+				return err
+			}
+			if skippy < 0 {
+				return ErrInvalidLengthExec
+			}
+			if (iNdEx + skippy) > l {
+				return io.ErrUnexpectedEOF
+			}
+			iNdEx += skippy
+		}
+	}
+
+	if iNdEx > l {
+		return io.ErrUnexpectedEOF
+	}
+	return nil
+}
+func (m *InputEvent) Unmarshal(dAtA []byte) error {
+	l := len(dAtA)
+	iNdEx := 0
+	for iNdEx < l {
+		preIndex := iNdEx
+		var wire uint64
+		for shift := uint(0); ; shift += 7 {
+			if shift >= 64 {
+				return ErrIntOverflowExec
+			}
+			if iNdEx >= l {
+				return io.ErrUnexpectedEOF
+			}
+			b := dAtA[iNdEx]
+			iNdEx++
+			wire |= (uint64(b) & 0x7F) << shift
+			if b < 0x80 {
+				break
+			}
+		}
+		fieldNum := int32(wire >> 3)
+		wireType := int(wire & 0x7)
+		if wireType == 4 {
+			return fmt.Errorf("proto: InputEvent: wiretype end group for non-group")
+		}
+		if fieldNum <= 0 {
+			return fmt.Errorf("proto: InputEvent: illegal tag %d (wire type %d)", fieldNum, wire)
+		}
+		switch fieldNum {
+		case 1:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Address", wireType)
+			}
+			var byteLen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowExec
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				byteLen |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if byteLen < 0 {
+				return ErrInvalidLengthExec
+			}
+			postIndex := iNdEx + byteLen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			if err := m.Address.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+				return err
+			}
+			iNdEx = postIndex
+		default:
+			iNdEx = preIndex
+			skippy, err := skipExec(dAtA[iNdEx:])
+			if err != nil {
+				return err
+			}
+			if skippy < 0 {
+				return ErrInvalidLengthExec
+			}
+			if (iNdEx + skippy) > l {
+				return io.ErrUnexpectedEOF
+			}
+			iNdEx += skippy
+		}
+	}
+
+	if iNdEx > l {
+		return io.ErrUnexpectedEOF
+	}
+	return nil
+}
+func (m *OutputEvent) Unmarshal(dAtA []byte) error {
+	l := len(dAtA)
+	iNdEx := 0
+	for iNdEx < l {
+		preIndex := iNdEx
+		var wire uint64
+		for shift := uint(0); ; shift += 7 {
+			if shift >= 64 {
+				return ErrIntOverflowExec
+			}
+			if iNdEx >= l {
+				return io.ErrUnexpectedEOF
+			}
+			b := dAtA[iNdEx]
+			iNdEx++
+			wire |= (uint64(b) & 0x7F) << shift
+			if b < 0x80 {
+				break
+			}
+		}
+		fieldNum := int32(wire >> 3)
+		wireType := int(wire & 0x7)
+		if wireType == 4 {
+			return fmt.Errorf("proto: OutputEvent: wiretype end group for non-group")
+		}
+		if fieldNum <= 0 {
+			return fmt.Errorf("proto: OutputEvent: illegal tag %d (wire type %d)", fieldNum, wire)
+		}
+		switch fieldNum {
+		case 1:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Address", wireType)
+			}
+			var byteLen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowExec
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				byteLen |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if byteLen < 0 {
+				return ErrInvalidLengthExec
+			}
+			postIndex := iNdEx + byteLen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			if err := m.Address.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+				return err
+			}
+			iNdEx = postIndex
+		default:
+			iNdEx = preIndex
+			skippy, err := skipExec(dAtA[iNdEx:])
+			if err != nil {
+				return err
+			}
+			if skippy < 0 {
+				return ErrInvalidLengthExec
+			}
+			if (iNdEx + skippy) > l {
+				return io.ErrUnexpectedEOF
+			}
+			iNdEx += skippy
+		}
+	}
+
+	if iNdEx > l {
+		return io.ErrUnexpectedEOF
+	}
+	return nil
+}
+func (m *CallData) Unmarshal(dAtA []byte) error {
+	l := len(dAtA)
+	iNdEx := 0
+	for iNdEx < l {
+		preIndex := iNdEx
+		var wire uint64
+		for shift := uint(0); ; shift += 7 {
+			if shift >= 64 {
+				return ErrIntOverflowExec
+			}
+			if iNdEx >= l {
+				return io.ErrUnexpectedEOF
+			}
+			b := dAtA[iNdEx]
+			iNdEx++
+			wire |= (uint64(b) & 0x7F) << shift
+			if b < 0x80 {
+				break
+			}
+		}
+		fieldNum := int32(wire >> 3)
+		wireType := int(wire & 0x7)
+		if wireType == 4 {
+			return fmt.Errorf("proto: CallData: wiretype end group for non-group")
+		}
+		if fieldNum <= 0 {
+			return fmt.Errorf("proto: CallData: illegal tag %d (wire type %d)", fieldNum, wire)
+		}
+		switch fieldNum {
+		case 1:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Caller", wireType)
+			}
+			var byteLen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowExec
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				byteLen |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if byteLen < 0 {
+				return ErrInvalidLengthExec
+			}
+			postIndex := iNdEx + byteLen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			if err := m.Caller.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+				return err
+			}
+			iNdEx = postIndex
+		case 2:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Callee", wireType)
+			}
+			var byteLen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowExec
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				byteLen |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if byteLen < 0 {
+				return ErrInvalidLengthExec
+			}
+			postIndex := iNdEx + byteLen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			if err := m.Callee.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+				return err
+			}
+			iNdEx = postIndex
+		case 3:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Data", wireType)
+			}
+			var byteLen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowExec
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				byteLen |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if byteLen < 0 {
+				return ErrInvalidLengthExec
+			}
+			postIndex := iNdEx + byteLen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			if err := m.Data.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+				return err
+			}
+			iNdEx = postIndex
+		case 4:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Value", wireType)
+			}
+			m.Value = 0
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowExec
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				m.Value |= (uint64(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+		case 5:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Gas", wireType)
+			}
+			m.Gas = 0
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowExec
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				m.Gas |= (uint64(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+		default:
+			iNdEx = preIndex
+			skippy, err := skipExec(dAtA[iNdEx:])
+			if err != nil {
+				return err
+			}
+			if skippy < 0 {
+				return ErrInvalidLengthExec
+			}
+			if (iNdEx + skippy) > l {
+				return io.ErrUnexpectedEOF
+			}
+			iNdEx += skippy
+		}
+	}
+
+	if iNdEx > l {
+		return io.ErrUnexpectedEOF
+	}
+	return nil
+}
+func skipExec(dAtA []byte) (n int, err error) {
+	l := len(dAtA)
+	iNdEx := 0
+	for iNdEx < l {
+		var wire uint64
+		for shift := uint(0); ; shift += 7 {
+			if shift >= 64 {
+				return 0, ErrIntOverflowExec
+			}
+			if iNdEx >= l {
+				return 0, io.ErrUnexpectedEOF
+			}
+			b := dAtA[iNdEx]
+			iNdEx++
+			wire |= (uint64(b) & 0x7F) << shift
+			if b < 0x80 {
+				break
+			}
+		}
+		wireType := int(wire & 0x7)
+		switch wireType {
+		case 0:
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return 0, ErrIntOverflowExec
+				}
+				if iNdEx >= l {
+					return 0, io.ErrUnexpectedEOF
+				}
+				iNdEx++
+				if dAtA[iNdEx-1] < 0x80 {
+					break
+				}
+			}
+			return iNdEx, nil
+		case 1:
+			iNdEx += 8
+			return iNdEx, nil
+		case 2:
+			var length int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return 0, ErrIntOverflowExec
+				}
+				if iNdEx >= l {
+					return 0, io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				length |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			iNdEx += length
+			if length < 0 {
+				return 0, ErrInvalidLengthExec
+			}
+			return iNdEx, nil
+		case 3:
+			for {
+				var innerWire uint64
+				var start int = iNdEx
+				for shift := uint(0); ; shift += 7 {
+					if shift >= 64 {
+						return 0, ErrIntOverflowExec
+					}
+					if iNdEx >= l {
+						return 0, io.ErrUnexpectedEOF
+					}
+					b := dAtA[iNdEx]
+					iNdEx++
+					innerWire |= (uint64(b) & 0x7F) << shift
+					if b < 0x80 {
+						break
+					}
+				}
+				innerWireType := int(innerWire & 0x7)
+				if innerWireType == 4 {
+					break
+				}
+				next, err := skipExec(dAtA[start:])
+				if err != nil {
+					return 0, err
+				}
+				iNdEx = start + next
+			}
+			return iNdEx, nil
+		case 4:
+			return iNdEx, nil
+		case 5:
+			iNdEx += 4
+			return iNdEx, nil
+		default:
+			return 0, fmt.Errorf("proto: illegal wireType %d", wireType)
+		}
+	}
+	panic("unreachable")
+}
+
+var (
+	ErrInvalidLengthExec = fmt.Errorf("proto: negative length found during unmarshaling")
+	ErrIntOverflowExec   = fmt.Errorf("proto: integer overflow")
+)
+
+func init() { proto.RegisterFile("exec.proto", fileDescriptorExec) }
+func init() { golang_proto.RegisterFile("exec.proto", fileDescriptorExec) }
+
+var fileDescriptorExec = []byte{
+	// 963 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x56, 0xcd, 0x6f, 0x1b, 0x45,
+	0x14, 0xef, 0xf8, 0x63, 0x6d, 0x3f, 0x3b, 0x25, 0x8c, 0x22, 0xb4, 0xea, 0xc1, 0x6b, 0xa5, 0xa8,
+	0x0a, 0xa1, 0x5d, 0x23, 0x97, 0x20, 0xc1, 0xad, 0x26, 0x56, 0x93, 0x2a, 0x24, 0x68, 0x6a, 0x40,
+	0x70, 0x5b, 0xef, 0x0e, 0x9b, 0x25, 0xf6, 0xee, 0x6a, 0x76, 0xb6, 0xac, 0x8f, 0x70, 0xe2, 0xc8,
+	0x81, 0x03, 0xc7, 0xe6, 0x02, 0xff, 0x06, 0xc7, 0x1c, 0xb9, 0x52, 0x24, 0x0b, 0x25, 0xff, 0x45,
+	0x4f, 0x68, 0x3e, 0x76, 0xbd, 0x8e, 0xaa, 0xb6, 0x6a, 0xd2, 0x4b, 0x34, 0xef, 0xbd, 0xdf, 0xfe,
+	0xe6, 0x7d, 0xfc, 0xe6, 0xc5, 0x00, 0x34, 0xa3, 0xae, 0x1d, 0xb3, 0x88, 0x47, 0xb8, 0x26, 0xce,
+	0xb7, 0xee, 0xf9, 0x01, 0x3f, 0x4e, 0x27, 0xb6, 0x1b, 0xcd, 0xfa, 0x7e, 0xe4, 0x47, 0x7d, 0x19,
+	0x9c, 0xa4, 0xdf, 0x4b, 0x4b, 0x1a, 0xf2, 0xa4, 0x3e, 0xba, 0x75, 0xb7, 0x04, 0xe7, 0x34, 0xf4,
+	0x28, 0x9b, 0x05, 0x21, 0xef, 0x3b, 0x13, 0x37, 0xe8, 0xf3, 0x79, 0x4c, 0x13, 0xf5, 0x57, 0xa3,
+	0x3b, 0x94, 0xb1, 0x88, 0xe5, 0x56, 0x3b, 0x74, 0x66, 0x45, 0xa8, 0xc5, 0xb3, 0xfc, 0xb8, 0x1e,
+	0x0b, 0x96, 0x24, 0x09, 0xa2, 0x50, 0x79, 0x36, 0x7f, 0x43, 0x70, 0x73, 0x38, 0x8d, 0xdc, 0x93,
+	0x51, 0x46, 0xdd, 0x94, 0x07, 0x51, 0x88, 0xdf, 0x03, 0x63, 0x8f, 0x06, 0xfe, 0x31, 0x37, 0x51,
+	0x0f, 0x6d, 0xd5, 0x88, 0xb6, 0xf0, 0x7d, 0x68, 0x4b, 0xe4, 0x1e, 0x75, 0x3c, 0xca, 0xcc, 0x4a,
+	0x0f, 0x6d, 0xb5, 0x07, 0xef, 0xda, 0xb2, 0xce, 0x52, 0x80, 0x94, 0x51, 0x78, 0x07, 0x3a, 0xe3,
+	0xac, 0xe0, 0x4e, 0xcc, 0x6a, 0xaf, 0xba, 0xfc, 0xaa, 0x14, 0x21, 0x2b, 0xb0, 0xcd, 0x4f, 0x57,
+	0xee, 0xc2, 0x18, 0x6a, 0x8f, 0x1e, 0x1f, 0x1d, 0xca, 0x84, 0x5a, 0x44, 0x9e, 0x45, 0x9a, 0x87,
+	0xe9, 0x6c, 0x9c, 0x25, 0x32, 0x93, 0x3a, 0xd1, 0xd6, 0xe6, 0x45, 0x15, 0xda, 0x25, 0x2e, 0xfc,
+	0x08, 0x8c, 0x71, 0x36, 0x9e, 0xc7, 0x54, 0xe2, 0xd6, 0x86, 0x83, 0xe7, 0x0b, 0xcb, 0x2e, 0xf5,
+	0xf6, 0x78, 0x1e, 0x53, 0x36, 0xa5, 0x9e, 0x4f, 0x59, 0x7f, 0x92, 0x32, 0x16, 0xfd, 0xd8, 0xe7,
+	0x59, 0xd2, 0x8f, 0x9d, 0xf9, 0x34, 0x72, 0x3c, 0x5b, 0x7c, 0x49, 0x34, 0x03, 0xfe, 0x42, 0x70,
+	0xed, 0x39, 0xc9, 0xb1, 0x59, 0xed, 0xa1, 0xad, 0xce, 0x70, 0xe7, 0x6c, 0x61, 0xdd, 0x78, 0xb6,
+	0xb0, 0xee, 0xbd, 0x9c, 0x6f, 0x12, 0x84, 0x0e, 0x9b, 0xdb, 0x7b, 0x34, 0x1b, 0xce, 0x39, 0x4d,
+	0x88, 0x26, 0x29, 0x75, 0xba, 0xb6, 0xd2, 0xe9, 0x0d, 0xa8, 0xef, 0x87, 0x1e, 0xcd, 0xcc, 0xba,
+	0x74, 0x2b, 0x03, 0x7f, 0x0b, 0xcd, 0x51, 0xf8, 0x84, 0x4e, 0xa3, 0x98, 0x9a, 0x86, 0x6c, 0xfe,
+	0x9a, 0x2d, 0x46, 0x9b, 0x3b, 0x87, 0xf6, 0xb3, 0x85, 0xb5, 0xfd, 0xca, 0xca, 0x0a, 0x3c, 0x29,
+	0xe8, 0xf0, 0x6d, 0x30, 0x46, 0x4f, 0x68, 0xc8, 0x13, 0xb3, 0x21, 0xe7, 0xd3, 0x56, 0xf3, 0x91,
+	0x3e, 0xa2, 0x43, 0xf8, 0x7d, 0x30, 0x08, 0x4d, 0xd2, 0x29, 0x37, 0x9b, 0xf2, 0xf6, 0x8e, 0x02,
+	0x29, 0x1f, 0xd1, 0x31, 0x7c, 0x07, 0x1a, 0x84, 0xba, 0x34, 0x88, 0xb9, 0xd9, 0xd2, 0x30, 0x71,
+	0xa9, 0xf6, 0x91, 0x3c, 0x88, 0xfb, 0xd0, 0x1a, 0x65, 0x2e, 0x8d, 0xc5, 0x8c, 0x4c, 0xc8, 0xb5,
+	0xa4, 0x44, 0x5c, 0x04, 0xc8, 0x12, 0xf3, 0x59, 0xe7, 0x97, 0x53, 0x0b, 0xfd, 0x7a, 0x6a, 0xa1,
+	0xa7, 0xa7, 0x16, 0xda, 0xfc, 0xb7, 0x22, 0x7a, 0x27, 0xc5, 0xb1, 0x1c, 0x30, 0xba, 0xc6, 0x01,
+	0x57, 0xae, 0x63, 0xc0, 0x1f, 0x42, 0x4b, 0x36, 0x4f, 0x66, 0x57, 0x95, 0xd9, 0xad, 0x3d, 0x5f,
+	0x58, 0x4b, 0x27, 0x59, 0x1e, 0xb1, 0x09, 0x0d, 0x69, 0xec, 0xef, 0x4a, 0x39, 0xb4, 0x48, 0x6e,
+	0x96, 0x74, 0x52, 0x7f, 0xb1, 0x4e, 0x8c, 0xb2, 0x4e, 0x56, 0x3a, 0xdb, 0x78, 0x8d, 0xce, 0xae,
+	0xff, 0xfe, 0xd4, 0xba, 0xb1, 0xd2, 0xdd, 0x7f, 0x10, 0xd4, 0xe5, 0xe5, 0x62, 0xe8, 0xfa, 0xbd,
+	0xa3, 0xf2, 0xd0, 0xf5, 0x53, 0xcf, 0x47, 0x70, 0x47, 0x24, 0x12, 0xa7, 0x5c, 0x2f, 0x85, 0x75,
+	0x05, 0x92, 0x2e, 0xa5, 0x21, 0x15, 0xc6, 0x1f, 0x80, 0x71, 0x94, 0x72, 0x01, 0xac, 0x96, 0xb7,
+	0x87, 0xf2, 0x69, 0xb5, 0x29, 0x03, 0xdf, 0x86, 0xda, 0xe7, 0xce, 0x74, 0x2a, 0x5b, 0xd1, 0x1e,
+	0xbc, 0xa3, 0x80, 0xc2, 0xa3, 0x60, 0x32, 0x88, 0x7b, 0x50, 0x3d, 0x88, 0x7c, 0xd9, 0x95, 0xf6,
+	0xe0, 0xa6, 0xc2, 0x1c, 0x44, 0xbe, 0x82, 0x88, 0xd0, 0x0b, 0x6a, 0xfb, 0x03, 0xe5, 0x3a, 0x16,
+	0x7d, 0x25, 0x94, 0xa7, 0x2c, 0x94, 0xc5, 0x75, 0x88, 0xb6, 0xc4, 0x24, 0x1e, 0x3a, 0xc9, 0x57,
+	0x09, 0xf5, 0x64, 0x41, 0x35, 0x92, 0x9b, 0x78, 0x1b, 0x5a, 0x87, 0xce, 0x8c, 0x8e, 0x42, 0xce,
+	0xe6, 0xba, 0x86, 0x8e, 0xad, 0x96, 0xad, 0xf4, 0x91, 0x65, 0x18, 0x7f, 0x04, 0xcd, 0x2f, 0x29,
+	0x9b, 0x3d, 0x60, 0x7e, 0xa2, 0xab, 0xd8, 0xb0, 0x4b, 0xfb, 0x37, 0x8f, 0x91, 0x02, 0x75, 0x49,
+	0xe2, 0x3f, 0x55, 0xa0, 0x99, 0x17, 0x83, 0x0f, 0xa1, 0xf1, 0xc0, 0xf3, 0x18, 0x4d, 0x12, 0x95,
+	0xeb, 0xf0, 0x63, 0xad, 0xcc, 0xbb, 0x2f, 0x57, 0xa6, 0xcb, 0xe6, 0x31, 0x8f, 0x6c, 0xfd, 0x2d,
+	0xc9, 0x49, 0xf0, 0x3e, 0xd4, 0x76, 0x1d, 0xee, 0x5c, 0x4d, 0xe6, 0x92, 0x02, 0x1f, 0x80, 0x31,
+	0x8e, 0xe2, 0xc0, 0x55, 0xcb, 0xfd, 0xb5, 0x33, 0xd3, 0x64, 0xdf, 0x44, 0xcc, 0x1b, 0xec, 0x7c,
+	0x42, 0x34, 0xc7, 0xa5, 0x1e, 0xfc, 0x5c, 0x81, 0x56, 0x31, 0x74, 0xbc, 0x0d, 0x4d, 0x61, 0xc8,
+	0xc4, 0x51, 0x79, 0xe6, 0xb9, 0x97, 0x14, 0x71, 0x91, 0xd5, 0x11, 0x0b, 0xfc, 0x20, 0xd4, 0x25,
+	0xbe, 0x59, 0xbf, 0x34, 0x07, 0xee, 0x02, 0x3c, 0xe6, 0x8e, 0x7b, 0xb2, 0x4b, 0x63, 0xae, 0x96,
+	0x7f, 0x8d, 0x94, 0x3c, 0x62, 0x6f, 0x68, 0x25, 0xd5, 0xae, 0xb4, 0x37, 0x14, 0xc9, 0xa5, 0x26,
+	0xfc, 0x00, 0xb0, 0x7c, 0x4a, 0xd7, 0xad, 0x84, 0x4b, 0x77, 0x9d, 0x40, 0xbb, 0xf4, 0x1a, 0xdf,
+	0xf2, 0x65, 0x7f, 0x56, 0x60, 0x65, 0x60, 0xe2, 0xac, 0x37, 0xcd, 0x1b, 0x0f, 0x4c, 0x71, 0x14,
+	0x6c, 0xf4, 0x6a, 0xe3, 0x57, 0x1c, 0xc5, 0x6b, 0xa9, 0x5e, 0xfd, 0xb5, 0x6c, 0x40, 0xfd, 0x6b,
+	0x67, 0x9a, 0x52, 0xfd, 0x2f, 0x5f, 0x19, 0x78, 0x1d, 0xaa, 0x0f, 0x9d, 0x44, 0xaf, 0x77, 0x71,
+	0x5c, 0xed, 0xd4, 0x70, 0x78, 0x76, 0xde, 0x45, 0x7f, 0x9f, 0x77, 0xd1, 0x7f, 0xe7, 0x5d, 0xf4,
+	0xd7, 0x45, 0x17, 0x9d, 0x5d, 0x74, 0xd1, 0x77, 0xaf, 0x28, 0x86, 0xe6, 0xbf, 0x81, 0xe4, 0x69,
+	0x62, 0xc8, 0x5f, 0x7c, 0xf7, 0xff, 0x0f, 0x00, 0x00, 0xff, 0xff, 0x4c, 0xf0, 0xd7, 0x87, 0x9a,
+	0x0a, 0x00, 0x00,
+}
diff --git a/execution/exec/header.go b/execution/exec/header.go
new file mode 100644
index 0000000000000000000000000000000000000000..1ed0b5aac01e7748a56256e93612241a78ed945f
--- /dev/null
+++ b/execution/exec/header.go
@@ -0,0 +1,13 @@
+package exec
+
+import (
+	"fmt"
+)
+
+func (h *Header) String() string {
+	if h == nil {
+		return fmt.Sprintf("Header{<Empty>}")
+	}
+	return fmt.Sprintf("Header{Tx{%v}: %v; Event{%v}: %v; Height: %v; Index: %v}",
+		h.TxType, h.TxHash, h.EventType, h.EventID, h.Height, h.Index)
+}
diff --git a/execution/events/log.go b/execution/exec/log_event.go
similarity index 51%
rename from execution/events/log.go
rename to execution/exec/log_event.go
index b41fad89fcc24db4a431e64fdf4dd8013bd8b30a..ea1aa02295844c0397fd7ee44c1d0bc504bedc54 100644
--- a/execution/events/log.go
+++ b/execution/exec/log_event.go
@@ -12,78 +12,39 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package events
+package exec
 
 import (
-	"context"
-	"fmt"
-
 	"strings"
 
-	"github.com/hyperledger/burrow/binary"
+	"fmt"
+
 	. "github.com/hyperledger/burrow/binary"
-	"github.com/hyperledger/burrow/crypto"
 	"github.com/hyperledger/burrow/event"
 	"github.com/hyperledger/burrow/event/query"
-	"github.com/hyperledger/burrow/txs"
 	"github.com/tmthrgd/go-hex"
 )
 
-// Functions to generate eventId strings
-
-func EventStringLogEvent(addr crypto.Address) string { return fmt.Sprintf("Log/%s", addr) }
-
-//----------------------------------------
-
-// EventDataLog fires when a contract executes the LOG opcode
-type EventDataLog struct {
-	Height  uint64
-	Address crypto.Address
-	Topics  []Word256
-	Data    binary.HexBytes
-}
+const logNTextTopicCutset = "\x00"
+const LogNKeyPrefix = "Log"
 
-// Publish/Subscribe
-func PublishLogEvent(publisher event.Publisher, tx *txs.Tx, log *EventDataLog) error {
-	ev := &Event{
-		Header: &Header{
-			TxType:    tx.Type(),
-			TxHash:    tx.Hash(),
-			EventType: TypeLog,
-			EventID:   EventStringLogEvent(log.Address),
-			Height:    log.Height,
-		},
-		Log: log,
-	}
-	return publisher.Publish(context.Background(), ev, ev.Tags())
+func LogNKey(topic int) string {
+	return fmt.Sprintf("%s%d", LogNKeyPrefix, topic)
 }
 
-func SubscribeLogEvent(ctx context.Context, subscribable event.Subscribable, subscriber string, address crypto.Address,
-	ch chan<- *EventDataLog) error {
-
-	qry := event.QueryForEventID(EventStringLogEvent(address))
-
-	return event.SubscribeCallback(ctx, subscribable, subscriber, qry, func(message interface{}) (stop bool) {
-		ev, ok := message.(*Event)
-		if ok && ev.Log != nil {
-			ch <- ev.Log
-		}
-		return
-	})
+func LogNTextKey(topic int) string {
+	return fmt.Sprintf("%s%dText", LogNKeyPrefix, topic)
 }
 
-// Tags
-const logNTextTopicCutset = "\x00"
-
 var logTagKeys []string
 var logNTopicIndex = make(map[string]int, 5)
 var logNTextTopicIndex = make(map[string]int, 5)
 
 func init() {
 	for i := 0; i <= 4; i++ {
-		logN := event.LogNKey(i)
-		logTagKeys = append(logTagKeys, event.LogNKey(i))
-		logNText := event.LogNTextKey(i)
+		logN := LogNKey(i)
+		logTagKeys = append(logTagKeys, LogNKey(i))
+		logNText := LogNTextKey(i)
 		logTagKeys = append(logTagKeys, logNText)
 		logNTopicIndex[logN] = i
 		logNTextTopicIndex[logNText] = i
@@ -91,7 +52,7 @@ func init() {
 	logTagKeys = append(logTagKeys, event.AddressKey)
 }
 
-func (log *EventDataLog) Get(key string) (string, bool) {
+func (log *LogEvent) Get(key string) (string, bool) {
 	var value interface{}
 	switch key {
 	case event.AddressKey:
@@ -108,17 +69,17 @@ func (log *EventDataLog) Get(key string) (string, bool) {
 	return query.StringFromValue(value), true
 }
 
-func (log *EventDataLog) GetTopic(i int) Word256 {
+func (log *LogEvent) GetTopic(i int) Word256 {
 	if i < len(log.Topics) {
 		return log.Topics[i]
 	}
 	return Word256{}
 }
 
-func (log *EventDataLog) Len() int {
+func (log *LogEvent) Len() int {
 	return len(logTagKeys)
 }
 
-func (log *EventDataLog) Keys() []string {
+func (log *LogEvent) Keys() []string {
 	return logTagKeys
 }
diff --git a/execution/exec/tx_execution.go b/execution/exec/tx_execution.go
new file mode 100644
index 0000000000000000000000000000000000000000..493af29207bd8bf63f40c1091f6cae7c41cd91c9
--- /dev/null
+++ b/execution/exec/tx_execution.go
@@ -0,0 +1,154 @@
+package exec
+
+import (
+	"fmt"
+
+	"github.com/hyperledger/burrow/crypto"
+	"github.com/hyperledger/burrow/event"
+	"github.com/hyperledger/burrow/event/query"
+	"github.com/hyperledger/burrow/execution/errors"
+	"github.com/hyperledger/burrow/execution/names"
+	"github.com/hyperledger/burrow/permission"
+	"github.com/hyperledger/burrow/txs"
+)
+
+func EventStringAccountInput(addr crypto.Address) string  { return fmt.Sprintf("Acc/%s/Input", addr) }
+func EventStringAccountOutput(addr crypto.Address) string { return fmt.Sprintf("Acc/%s/Output", addr) }
+
+func EventStringAccountCall(addr crypto.Address) string { return fmt.Sprintf("Acc/%s/Call", addr) }
+func EventStringLogEvent(addr crypto.Address) string    { return fmt.Sprintf("Log/%s", addr) }
+func EventStringTxExecution(txHash []byte) string       { return fmt.Sprintf("Execution/Tx/%X", txHash) }
+
+func NewTxExecution(txEnv *txs.Envelope) *TxExecution {
+	return &TxExecution{
+		TxHash:   txEnv.Tx.Hash(),
+		TxType:   txEnv.Tx.Type(),
+		Envelope: txEnv,
+		Receipt:  txEnv.Tx.GenerateReceipt(),
+	}
+}
+
+func DecodeTxExecution(bs []byte) (*TxExecution, error) {
+	txe := new(TxExecution)
+	err := cdc.UnmarshalBinary(bs, txe)
+	if err != nil {
+		return nil, err
+	}
+	return txe, nil
+}
+
+func (txe *TxExecution) Encode() ([]byte, error) {
+	return cdc.MarshalBinary(txe)
+}
+
+func (*TxExecution) EventType() EventType {
+	return TypeTxExecution
+}
+
+func (txe *TxExecution) Header(eventType EventType, eventID string, exception *errors.Exception) *Header {
+	return &Header{
+		TxType:    txe.TxType,
+		TxHash:    txe.TxHash,
+		EventType: eventType,
+		EventID:   eventID,
+		Height:    txe.Height,
+		Exception: exception,
+	}
+}
+
+// Emit events
+func (txe *TxExecution) Input(address crypto.Address, exception *errors.Exception) {
+	txe.Append(&Event{
+		Header: txe.Header(TypeAccountInput, EventStringAccountInput(address), exception),
+		Input: &InputEvent{
+			Address: address,
+		},
+	})
+}
+
+func (txe *TxExecution) Output(address crypto.Address, exception *errors.Exception) {
+	txe.Append(&Event{
+		Header: txe.Header(TypeAccountOutput, EventStringAccountOutput(address), exception),
+		Output: &OutputEvent{
+			Address: address,
+		},
+	})
+}
+
+func (txe *TxExecution) Log(log *LogEvent) {
+	txe.Append(&Event{
+		Header: txe.Header(TypeLog, EventStringLogEvent(log.Address), nil),
+		Log:    log,
+	})
+}
+
+func (txe *TxExecution) Call(call *CallEvent, exception *errors.Exception) {
+	txe.Append(&Event{
+		Header: txe.Header(TypeCall, EventStringAccountCall(call.CallData.Callee), exception),
+		Call:   call,
+	})
+}
+
+// Set result
+func (txe *TxExecution) Return(returnValue []byte, gasUsed uint64) {
+	if txe.Result == nil {
+		txe.Result = &Result{}
+	}
+	txe.Result.Return = returnValue
+	txe.Result.GasUsed = gasUsed
+}
+
+func (txe *TxExecution) Name(entry *names.Entry) {
+	if txe.Result == nil {
+		txe.Result = &Result{}
+	}
+	txe.Result.NameEntry = entry
+}
+
+func (txe *TxExecution) Permission(permArgs *permission.PermArgs) {
+	if txe.Result == nil {
+		txe.Result = &Result{}
+	}
+	txe.Result.PermArgs = permArgs
+}
+
+func (txe *TxExecution) Append(tail ...*Event) {
+	for i, ev := range tail {
+		if ev != nil && ev.Header != nil {
+			ev.Header.Index = uint64(len(txe.Events) + i)
+			ev.Header.Height = txe.Height
+		}
+	}
+	txe.Events = append(txe.Events, tail...)
+}
+
+// Tags
+type TaggedTxExecution struct {
+	query.Tagged
+	*TxExecution
+}
+
+func (txe *TxExecution) Tagged() *TaggedTxExecution {
+	return &TaggedTxExecution{
+		Tagged: query.MergeTags(
+			query.TagMap{
+				event.EventIDKey:   EventStringTxExecution(txe.TxHash),
+				event.EventTypeKey: txe.EventType()},
+			query.MustReflectTags(txe),
+			txe.Envelope.Tagged(),
+		),
+		TxExecution: txe,
+	}
+}
+
+func (txe *TxExecution) TaggedEvents() TaggedEvents {
+	tevs := make(TaggedEvents, len(txe.Events))
+	for i, ev := range txe.Events {
+		tevs[i] = ev.Tagged()
+	}
+	return tevs
+}
+
+func QueryForTxExecution(txHash []byte) query.Queryable {
+	return query.NewBuilder().AndEquals(event.EventIDKey, EventStringTxExecution(txHash))
+}
diff --git a/execution/execution.go b/execution/execution.go
index 22eff6e9b33dc219c5ddbd90e267533a2bd2dcf8..23412014eddc452a9260e697a073403f8e87c123 100644
--- a/execution/execution.go
+++ b/execution/execution.go
@@ -19,23 +19,31 @@ import (
 	"runtime/debug"
 	"sync"
 
-	acm "github.com/hyperledger/burrow/account"
-	"github.com/hyperledger/burrow/account/state"
+	"context"
+
+	"github.com/hyperledger/burrow/acm"
+	"github.com/hyperledger/burrow/acm/state"
 	"github.com/hyperledger/burrow/binary"
 	bcm "github.com/hyperledger/burrow/blockchain"
 	"github.com/hyperledger/burrow/crypto"
 	"github.com/hyperledger/burrow/event"
 	"github.com/hyperledger/burrow/execution/evm"
+	"github.com/hyperledger/burrow/execution/exec"
 	"github.com/hyperledger/burrow/execution/executors"
 	"github.com/hyperledger/burrow/execution/names"
 	"github.com/hyperledger/burrow/logging"
 	"github.com/hyperledger/burrow/logging/structure"
 	"github.com/hyperledger/burrow/txs"
 	"github.com/hyperledger/burrow/txs/payload"
+	abciTypes "github.com/tendermint/abci/types"
 )
 
 type Executor interface {
-	Execute(txEnv *txs.Envelope) error
+	Execute(txEnv *txs.Envelope) (*exec.TxExecution, error)
+}
+
+type Context interface {
+	Execute(txe *exec.TxExecution) error
 }
 
 type ExecutorState interface {
@@ -59,20 +67,21 @@ type BatchCommitter interface {
 	BatchExecutor
 	// Commit execution results to underlying State and provide opportunity
 	// to mutate state before it is saved
-	Commit() (stateHash []byte, err error)
+	Commit(*abciTypes.Header) (stateHash []byte, err error)
 }
 
 type executor struct {
 	sync.RWMutex
-	runCall      bool
-	publisher    event.Publisher
-	state        ExecutorState
-	stateCache   *state.Cache
-	nameRegCache *names.Cache
-	eventCache   *event.Cache
-	logger       *logging.Logger
-	vmOptions    []func(*evm.VM)
-	txExecutors  map[payload.Type]Executor
+	runCall        bool
+	tip            bcm.TipInfo
+	state          ExecutorState
+	stateCache     *state.Cache
+	nameRegCache   *names.Cache
+	publisher      event.Publisher
+	blockExecution *exec.BlockExecution
+	logger         *logging.Logger
+	vmOptions      []func(*evm.VM)
+	txExecutors    map[payload.Type]Context
 }
 
 var _ BatchExecutor = (*executor)(nil)
@@ -85,10 +94,10 @@ func NewBatchChecker(backend ExecutorState, tip bcm.TipInfo, logger *logging.Log
 		logger.WithScope("NewBatchExecutor"), options...)
 }
 
-func NewBatchCommitter(backend ExecutorState, tip bcm.TipInfo, publisher event.Publisher, logger *logging.Logger,
+func NewBatchCommitter(backend ExecutorState, tip bcm.TipInfo, emitter event.Publisher, logger *logging.Logger,
 	options ...ExecutionOption) BatchCommitter {
 
-	return newExecutor("CommitCache", true, backend, tip, publisher,
+	return newExecutor("CommitCache", true, backend, tip, emitter,
 		logger.WithScope("NewBatchCommitter"), options...)
 }
 
@@ -98,42 +107,41 @@ func newExecutor(name string, runCall bool, backend ExecutorState, tip bcm.TipIn
 	exe := &executor{
 		runCall:      runCall,
 		state:        backend,
-		publisher:    publisher,
+		tip:          tip,
 		stateCache:   state.NewCache(backend, state.Name(name)),
-		eventCache:   event.NewCache(),
 		nameRegCache: names.NewCache(backend),
-		logger:       logger.With(structure.ComponentKey, "Executor"),
+		publisher:    publisher,
+		blockExecution: &exec.BlockExecution{
+			Height: tip.LastBlockHeight() + 1,
+		},
+		logger: logger.With(structure.ComponentKey, "Executor"),
 	}
 	for _, option := range options {
 		option(exe)
 	}
-	exe.txExecutors = map[payload.Type]Executor{
+	exe.txExecutors = map[payload.Type]Context{
 		payload.TypeSend: &executors.SendContext{
-			Tip:            tip,
-			StateWriter:    exe.stateCache,
-			EventPublisher: exe.eventCache,
-			Logger:         exe.logger,
+			Tip:         tip,
+			StateWriter: exe.stateCache,
+			Logger:      exe.logger,
 		},
 		payload.TypeCall: &executors.CallContext{
-			Tip:            tip,
-			StateWriter:    exe.stateCache,
-			EventPublisher: exe.eventCache,
-			RunCall:        runCall,
-			VMOptions:      exe.vmOptions,
-			Logger:         exe.logger,
+			Tip:         tip,
+			StateWriter: exe.stateCache,
+			RunCall:     runCall,
+			VMOptions:   exe.vmOptions,
+			Logger:      exe.logger,
 		},
 		payload.TypeName: &executors.NameContext{
-			Tip:            tip,
-			StateWriter:    exe.stateCache,
-			EventPublisher: exe.eventCache,
-			NameReg:        exe.nameRegCache,
-			Logger:         exe.logger,
+			Tip:         tip,
+			StateWriter: exe.stateCache,
+			NameReg:     exe.nameRegCache,
+			Logger:      exe.logger,
 		},
 		payload.TypePermissions: &executors.PermissionsContext{
-			Tip:            tip,
-			StateWriter:    exe.stateCache,
-			EventPublisher: exe.eventCache,
-			Logger:         exe.logger,
+			Tip:         tip,
+			StateWriter: exe.stateCache,
+			Logger:      exe.logger,
 		},
 	}
 	return exe
@@ -141,7 +149,7 @@ func newExecutor(name string, runCall bool, backend ExecutorState, tip bcm.TipIn
 
 // If the tx is invalid, an error will be returned.
 // Unlike ExecBlock(), state will not be altered.
-func (exe *executor) Execute(txEnv *txs.Envelope) (err error) {
+func (exe *executor) Execute(txEnv *txs.Envelope) (txe *exec.TxExecution, err error) {
 	defer func() {
 		if r := recover(); r != nil {
 			err = fmt.Errorf("recovered from panic in executor.Execute(%s): %v\n%s", txEnv.String(), r,
@@ -158,24 +166,53 @@ func (exe *executor) Execute(txEnv *txs.Envelope) (err error) {
 	// Verify transaction signature against inputs
 	err = txEnv.Verify(exe.stateCache)
 	if err != nil {
-		return err
+		return nil, err
 	}
 
 	if txExecutor, ok := exe.txExecutors[txEnv.Tx.Type()]; ok {
-		return txExecutor.Execute(txEnv)
+		// Establish new TxExecution
+		txe := exe.blockExecution.Tx(txEnv)
+		err = txExecutor.Execute(txe)
+		if err != nil {
+			return nil, err
+		}
+		// Return execution for this tx
+		return txe, err
+	}
+	return nil, fmt.Errorf("unknown transaction type: %v", txEnv.Tx.Type())
+}
+
+func (exe *executor) finaliseBlockExecution(header *abciTypes.Header) (*exec.BlockExecution, error) {
+	if header != nil && uint64(header.Height) != exe.blockExecution.Height {
+		return nil, fmt.Errorf("trying to finalise block execution with height %v but passed Tendermint"+
+			"block header at height %v", exe.blockExecution.Height, header.Height)
+	}
+	// Capture BlockExecution to return
+	be := exe.blockExecution
+	// Set the header when provided
+	be.BlockHeader = exec.BlockHeaderFromHeader(header)
+	// Start new execution for the next height
+	exe.blockExecution = &exec.BlockExecution{
+		Height: exe.blockExecution.Height + 1,
 	}
-	return fmt.Errorf("unknown transaction type: %v", txEnv.Tx.Type())
+	return be, nil
 }
 
-func (exe *executor) Commit() (_ []byte, err error) {
+func (exe *executor) Commit(header *abciTypes.Header) (_ []byte, err error) {
 	// The write lock to the executor is controlled by the caller (e.g. abci.App) so we do not acquire it here to avoid
 	// deadlock
 	defer func() {
 		if r := recover(); r != nil {
-			err = fmt.Errorf("recovered from panic in executor.Commit(): %v\n%v", r, debug.Stack())
+			err = fmt.Errorf("recovered from panic in executor.Commit(): %v\n%s", r, debug.Stack())
 		}
 	}()
-	return exe.state.Update(func(ws Updatable) error {
+	exe.logger.InfoMsg("Executor committing", "height", exe.blockExecution.Height)
+	// Form BlockExecution for this block from TxExecutions and Tendermint block header
+	blockExecution, err := exe.finaliseBlockExecution(header)
+	if err != nil {
+		return nil, err
+	}
+	hash, err := exe.state.Update(func(ws Updatable) error {
 		// flush the caches
 		err := exe.stateCache.Flush(ws, exe.state)
 		if err != nil {
@@ -185,17 +222,27 @@ func (exe *executor) Commit() (_ []byte, err error) {
 		if err != nil {
 			return err
 		}
-		err = exe.eventCache.Sync(ws)
-		if err != nil {
-			return err
-		}
-		// flush events to listeners
-		err = exe.eventCache.Flush(exe.publisher)
+		err = ws.AddBlock(blockExecution)
 		if err != nil {
 			return err
 		}
 		return nil
 	})
+	if err != nil {
+		return nil, err
+	}
+	// Now state is committed publish events
+	for _, txe := range blockExecution.TxExecutions {
+		publishErr := exe.publisher.Publish(context.Background(), txe, txe.Tagged())
+		exe.logger.InfoMsg("Error publishing TxExecution",
+			"tx_hash", txe.TxHash,
+			structure.ErrorKey, publishErr)
+	}
+	publishErr := exe.publisher.Publish(context.Background(), blockExecution, blockExecution.Tagged())
+	exe.logger.InfoMsg("Error publishing TxExecution",
+		"height", blockExecution.Height,
+		structure.ErrorKey, publishErr)
+	return hash, nil
 }
 
 func (exe *executor) Reset() error {
diff --git a/execution/execution_test.go b/execution/execution_test.go
index 74e5689ccf1f447032e88dd2b0eac57d09bc06c5..608da343cfbfdb99750fc30f747d7007ff0530a0 100644
--- a/execution/execution_test.go
+++ b/execution/execution_test.go
@@ -16,7 +16,6 @@ package execution
 
 import (
 	"bytes"
-	"context"
 	"fmt"
 	"strconv"
 	"testing"
@@ -24,24 +23,22 @@ import (
 
 	"runtime/debug"
 
-	acm "github.com/hyperledger/burrow/account"
-	"github.com/hyperledger/burrow/account/state"
+	"github.com/hyperledger/burrow/acm"
+	"github.com/hyperledger/burrow/acm/state"
 	. "github.com/hyperledger/burrow/binary"
 	bcm "github.com/hyperledger/burrow/blockchain"
 	"github.com/hyperledger/burrow/crypto"
 	"github.com/hyperledger/burrow/event"
 	"github.com/hyperledger/burrow/execution/errors"
-	"github.com/hyperledger/burrow/execution/events"
 	"github.com/hyperledger/burrow/execution/evm"
 	. "github.com/hyperledger/burrow/execution/evm/asm"
 	"github.com/hyperledger/burrow/execution/evm/asm/bc"
 	"github.com/hyperledger/burrow/execution/evm/sha3"
+	"github.com/hyperledger/burrow/execution/exec"
 	"github.com/hyperledger/burrow/execution/names"
 	"github.com/hyperledger/burrow/genesis"
 	"github.com/hyperledger/burrow/logging"
 	"github.com/hyperledger/burrow/permission"
-	"github.com/hyperledger/burrow/permission/snatives"
-	ptypes "github.com/hyperledger/burrow/permission/types"
 	"github.com/hyperledger/burrow/txs"
 	"github.com/hyperledger/burrow/txs/payload"
 	"github.com/stretchr/testify/require"
@@ -127,7 +124,32 @@ var testChainID = testGenesisDoc.ChainID()
 type testExecutor struct {
 	*executor
 	blockchain *bcm.Blockchain
-	event.Emitter
+}
+
+func makeExecutor(state *State) *testExecutor {
+	blockchain := newBlockchain(testGenesisDoc)
+	return &testExecutor{
+		executor: newExecutor("makeExecutorCache", true, state, blockchain.Tip, event.NewNoOpPublisher(),
+			logger),
+		blockchain: blockchain,
+	}
+}
+
+func (te *testExecutor) signExecuteCommit(tx payload.Payload, signer acm.AddressableSigner) error {
+	txEnv := txs.Enclose(testChainID, tx)
+	err := txEnv.Sign(signer)
+	if err != nil {
+		return err
+	}
+	_, err = te.Execute(txEnv)
+	if err != nil {
+		return err
+	}
+	appHash, err := te.Commit(nil)
+	if err != nil {
+		return err
+	}
+	return te.blockchain.CommitBlock(time.Now(), nil, appHash)
 }
 
 func makeUsers(n int) []acm.AddressableSigner {
@@ -145,17 +167,7 @@ func newBlockchain(genesisDoc *genesis.GenesisDoc) *bcm.Blockchain {
 	return bc
 }
 
-func makeExecutor(state *State) *testExecutor {
-	emitter := event.NewEmitter(logger)
-	blockchain := newBlockchain(testGenesisDoc)
-	return &testExecutor{
-		executor:   newExecutor("makeExecutorCache", true, state, blockchain.Tip, emitter, logger),
-		blockchain: blockchain,
-		Emitter:    emitter,
-	}
-}
-
-func newBaseGenDoc(globalPerm, accountPerm ptypes.AccountPermissions) genesis.GenesisDoc {
+func newBaseGenDoc(globalPerm, accountPerm permission.AccountPermissions) genesis.GenesisDoc {
 	var genAccounts []genesis.Account
 	for _, user := range users[:5] {
 		accountPermCopy := accountPerm // Create new instance for custom overridability.
@@ -189,18 +201,13 @@ func newBaseGenDoc(globalPerm, accountPerm ptypes.AccountPermissions) genesis.Ge
 	}
 }
 
-//func getAccount(state state.AccountGetter, address acm.Address) acm.MutableAccount {
-//	acc, _ := state.GetMutableAccount(state, address)
-//	return acc
-//}
-
 func TestSendFails(t *testing.T) {
 	stateDB := dbm.NewDB("state", dbBackend, dbDir)
 	defer stateDB.Close()
 	genDoc := newBaseGenDoc(permission.ZeroAccountPermissions, permission.ZeroAccountPermissions)
-	genDoc.Accounts[1].Permissions.Base.Set(ptypes.Send, true)
-	genDoc.Accounts[2].Permissions.Base.Set(ptypes.Call, true)
-	genDoc.Accounts[3].Permissions.Base.Set(ptypes.CreateContract, true)
+	genDoc.Accounts[1].Permissions.Base.Set(permission.Send, true)
+	genDoc.Accounts[2].Permissions.Base.Set(permission.Call, true)
+	genDoc.Accounts[3].Permissions.Base.Set(permission.CreateContract, true)
 	st, err := MakeGenesisState(stateDB, &genDoc)
 	require.NoError(t, err)
 	exe := makeExecutor(st)
@@ -235,7 +242,7 @@ func TestSendFails(t *testing.T) {
 
 	// simple send tx to unknown account without create_account perm should fail
 	acc := getAccount(exe.stateCache, users[3].Address())
-	acc.MutablePermissions().Base.Set(ptypes.Send, true)
+	acc.MutablePermissions().Base.Set(permission.Send, true)
 	exe.stateCache.UpdateAccount(acc)
 	tx = payload.NewSendTx()
 	if err := tx.AddInput(exe.stateCache, users[3].PublicKey(), 5); err != nil {
@@ -249,8 +256,8 @@ func TestName(t *testing.T) {
 	stateDB := dbm.NewDB("state", dbBackend, dbDir)
 	defer stateDB.Close()
 	genDoc := newBaseGenDoc(permission.ZeroAccountPermissions, permission.ZeroAccountPermissions)
-	genDoc.Accounts[0].Permissions.Base.Set(ptypes.Send, true)
-	genDoc.Accounts[1].Permissions.Base.Set(ptypes.Name, true)
+	genDoc.Accounts[0].Permissions.Base.Set(permission.Send, true)
+	genDoc.Accounts[1].Permissions.Base.Set(permission.Name, true)
 	st, err := MakeGenesisState(stateDB, &genDoc)
 	require.NoError(t, err)
 	batchCommitter := makeExecutor(st)
@@ -277,9 +284,9 @@ func TestCallFails(t *testing.T) {
 	stateDB := dbm.NewDB("state", dbBackend, dbDir)
 	defer stateDB.Close()
 	genDoc := newBaseGenDoc(permission.ZeroAccountPermissions, permission.ZeroAccountPermissions)
-	genDoc.Accounts[1].Permissions.Base.Set(ptypes.Send, true)
-	genDoc.Accounts[2].Permissions.Base.Set(ptypes.Call, true)
-	genDoc.Accounts[3].Permissions.Base.Set(ptypes.CreateContract, true)
+	genDoc.Accounts[1].Permissions.Base.Set(permission.Send, true)
+	genDoc.Accounts[2].Permissions.Base.Set(permission.Call, true)
+	genDoc.Accounts[3].Permissions.Base.Set(permission.CreateContract, true)
 	st, err := MakeGenesisState(stateDB, &genDoc)
 	require.NoError(t, err)
 	batchCommitter := makeExecutor(st)
@@ -320,7 +327,7 @@ func TestSendPermission(t *testing.T) {
 	stateDB := dbm.NewDB("state", dbBackend, dbDir)
 	defer stateDB.Close()
 	genDoc := newBaseGenDoc(permission.ZeroAccountPermissions, permission.ZeroAccountPermissions)
-	genDoc.Accounts[0].Permissions.Base.Set(ptypes.Send, true) // give the 0 account permission
+	genDoc.Accounts[0].Permissions.Base.Set(permission.Send, true) // give the 0 account permission
 	st, err := MakeGenesisState(stateDB, &genDoc)
 	require.NoError(t, err)
 	batchCommitter := makeExecutor(st)
@@ -345,7 +352,7 @@ func TestCallPermission(t *testing.T) {
 	stateDB := dbm.NewDB("state", dbBackend, dbDir)
 	defer stateDB.Close()
 	genDoc := newBaseGenDoc(permission.ZeroAccountPermissions, permission.ZeroAccountPermissions)
-	genDoc.Accounts[0].Permissions.Base.Set(ptypes.Call, true) // give the 0 account permission
+	genDoc.Accounts[0].Permissions.Base.Set(permission.Call, true) // give the 0 account permission
 	st, err := MakeGenesisState(stateDB, &genDoc)
 	require.NoError(t, err)
 	exe := makeExecutor(st)
@@ -361,7 +368,6 @@ func TestCallPermission(t *testing.T) {
 		Balance:     0,
 		Code:        []byte{0x60},
 		Sequence:    0,
-		StorageRoot: Zero256.Bytes(),
 		Permissions: permission.ZeroAccountPermissions,
 	}.MutableAccount()
 	st.writeState.UpdateAccount(simpleAcc)
@@ -382,7 +388,6 @@ func TestCallPermission(t *testing.T) {
 		Balance:     10000,
 		Code:        contractCode,
 		Sequence:    0,
-		StorageRoot: Zero256.Bytes(),
 		Permissions: permission.ZeroAccountPermissions,
 	}.MutableAccount()
 	exe.stateCache.UpdateAccount(caller1Acc)
@@ -401,14 +406,14 @@ func TestCallPermission(t *testing.T) {
 	fmt.Println("\n##### CALL TO SIMPLE CONTRACT (PASS)")
 
 	// A single input, having the permission, and the contract has permission
-	caller1Acc.MutablePermissions().Base.Set(ptypes.Call, true)
+	caller1Acc.MutablePermissions().Base.Set(permission.Call, true)
 	exe.stateCache.UpdateAccount(caller1Acc)
 	tx, _ = payload.NewCallTx(exe.stateCache, users[0].PublicKey(), &caller1ContractAddr, nil, 100, 10000, 100)
 	txEnv = txs.Enclose(testChainID, tx)
 	require.NoError(t, txEnv.Sign(users[0]))
 
 	// we need to subscribe to the Call event to detect the exception
-	_, err = execTxWaitAccountCall(t, exe, txEnv, caller1ContractAddr) //
+	_, err = execTxWaitAccountCall(t, exe, txEnv, caller1ContractAddr)
 	require.NoError(t, err)
 
 	//----------------------------------------------------------
@@ -424,11 +429,10 @@ func TestCallPermission(t *testing.T) {
 		Balance:     1000,
 		Code:        contractCode2,
 		Sequence:    0,
-		StorageRoot: Zero256.Bytes(),
 		Permissions: permission.ZeroAccountPermissions,
 	}.MutableAccount()
-	caller1Acc.MutablePermissions().Base.Set(ptypes.Call, false)
-	caller2Acc.MutablePermissions().Base.Set(ptypes.Call, true)
+	caller1Acc.MutablePermissions().Base.Set(permission.Call, false)
+	caller2Acc.MutablePermissions().Base.Set(permission.Call, true)
 	exe.stateCache.UpdateAccount(caller1Acc)
 	exe.stateCache.UpdateAccount(caller2Acc)
 
@@ -445,7 +449,7 @@ func TestCallPermission(t *testing.T) {
 	// both caller1 and caller2 have permission
 	fmt.Println("\n##### CALL TO CONTRACT CALLING SIMPLE CONTRACT (PASS)")
 
-	caller1Acc.MutablePermissions().Base.Set(ptypes.Call, true)
+	caller1Acc.MutablePermissions().Base.Set(permission.Call, true)
 	exe.stateCache.UpdateAccount(caller1Acc)
 
 	tx, _ = payload.NewCallTx(exe.stateCache, users[0].PublicKey(), &caller2ContractAddr, nil, 100, 10000, 100)
@@ -461,8 +465,8 @@ func TestCreatePermission(t *testing.T) {
 	stateDB := dbm.NewDB("state", dbBackend, dbDir)
 	defer stateDB.Close()
 	genDoc := newBaseGenDoc(permission.ZeroAccountPermissions, permission.ZeroAccountPermissions)
-	genDoc.Accounts[0].Permissions.Base.Set(ptypes.CreateContract, true) // give the 0 account permission
-	genDoc.Accounts[0].Permissions.Base.Set(ptypes.Call, true)           // give the 0 account permission
+	genDoc.Accounts[0].Permissions.Base.Set(permission.CreateContract, true) // give the 0 account permission
+	genDoc.Accounts[0].Permissions.Base.Set(permission.Call, true)           // give the 0 account permission
 	st, err := MakeGenesisState(stateDB, &genDoc)
 	require.NoError(t, err)
 	exe := makeExecutor(st)
@@ -527,7 +531,7 @@ func TestCreatePermission(t *testing.T) {
 	// call the contract (should PASS)
 	fmt.Println("\n###### CALL THE FACTORY (PASS)")
 
-	contractAcc.MutablePermissions().Base.Set(ptypes.CreateContract, true)
+	contractAcc.MutablePermissions().Base.Set(permission.CreateContract, true)
 	exe.stateCache.UpdateAccount(contractAcc)
 
 	// A single input, having the permission, should succeed
@@ -548,11 +552,10 @@ func TestCreatePermission(t *testing.T) {
 		Balance:     1000,
 		Code:        code,
 		Sequence:    0,
-		StorageRoot: Zero256.Bytes(),
 		Permissions: permission.ZeroAccountPermissions,
 	}.MutableAccount()
-	contractAcc.MutablePermissions().Base.Set(ptypes.Call, true)
-	contractAcc.MutablePermissions().Base.Set(ptypes.CreateContract, true)
+	contractAcc.MutablePermissions().Base.Set(permission.Call, true)
+	contractAcc.MutablePermissions().Base.Set(permission.CreateContract, true)
 	exe.stateCache.UpdateAccount(contractAcc)
 
 	// this should call the 0 address but not create ...
@@ -572,9 +575,9 @@ func TestCreateAccountPermission(t *testing.T) {
 	stateDB := dbm.NewDB("state", dbBackend, dbDir)
 	defer stateDB.Close()
 	genDoc := newBaseGenDoc(permission.ZeroAccountPermissions, permission.ZeroAccountPermissions)
-	genDoc.Accounts[0].Permissions.Base.Set(ptypes.Send, true)          // give the 0 account permission
-	genDoc.Accounts[1].Permissions.Base.Set(ptypes.Send, true)          // give the 0 account permission
-	genDoc.Accounts[0].Permissions.Base.Set(ptypes.CreateAccount, true) // give the 0 account permission
+	genDoc.Accounts[0].Permissions.Base.Set(permission.Send, true)          // give the 0 account permission
+	genDoc.Accounts[1].Permissions.Base.Set(permission.Send, true)          // give the 0 account permission
+	genDoc.Accounts[0].Permissions.Base.Set(permission.CreateAccount, true) // give the 0 account permission
 	st, err := MakeGenesisState(stateDB, &genDoc)
 	require.NoError(t, err)
 	batchCommitter := makeExecutor(st)
@@ -615,7 +618,7 @@ func TestCreateAccountPermission(t *testing.T) {
 
 	// Two inputs, both with send, both with create, should pass
 	acc := getAccount(batchCommitter.stateCache, users[1].Address())
-	acc.MutablePermissions().Base.Set(ptypes.CreateAccount, true)
+	acc.MutablePermissions().Base.Set(permission.CreateAccount, true)
 	batchCommitter.stateCache.UpdateAccount(acc)
 	tx = payload.NewSendTx()
 	if err := tx.AddInput(batchCommitter.stateCache, users[0].PublicKey(), 5); err != nil {
@@ -643,7 +646,7 @@ func TestCreateAccountPermission(t *testing.T) {
 	// CALL to unknown account
 
 	acc = getAccount(batchCommitter.stateCache, users[0].Address())
-	acc.MutablePermissions().Base.Set(ptypes.Call, true)
+	acc.MutablePermissions().Base.Set(permission.Call, true)
 	batchCommitter.stateCache.UpdateAccount(acc)
 
 	// call to contract that calls unknown account - without create_account perm
@@ -655,7 +658,6 @@ func TestCreateAccountPermission(t *testing.T) {
 		Balance:     0,
 		Code:        contractCode,
 		Sequence:    0,
-		StorageRoot: Zero256.Bytes(),
 		Permissions: permission.ZeroAccountPermissions,
 	}.MutableAccount()
 	batchCommitter.stateCache.UpdateAccount(caller1Acc)
@@ -671,8 +673,8 @@ func TestCreateAccountPermission(t *testing.T) {
 
 	// NOTE: for a contract to be able to CreateAccount, it must be able to call
 	// NOTE: for a users to be able to CreateAccount, it must be able to send!
-	caller1Acc.MutablePermissions().Base.Set(ptypes.CreateAccount, true)
-	caller1Acc.MutablePermissions().Base.Set(ptypes.Call, true)
+	caller1Acc.MutablePermissions().Base.Set(permission.CreateAccount, true)
+	caller1Acc.MutablePermissions().Base.Set(permission.Call, true)
 	batchCommitter.stateCache.UpdateAccount(caller1Acc)
 	// A single input, having the permission, but the contract doesn't have permission
 	txCall, _ = payload.NewCallTx(batchCommitter.stateCache, users[0].PublicKey(), &caller1ContractAddr, nil, 100, 10000, 100)
@@ -696,8 +698,8 @@ func TestSNativeCALL(t *testing.T) {
 	stateDB := dbm.NewDB("state", dbBackend, dbDir)
 	defer stateDB.Close()
 	genDoc := newBaseGenDoc(permission.ZeroAccountPermissions, permission.ZeroAccountPermissions)
-	genDoc.Accounts[0].Permissions.Base.Set(ptypes.Call, true) // give the 0 account permission
-	genDoc.Accounts[3].Permissions.Base.Set(ptypes.Bond, true) // some arbitrary permission to play with
+	genDoc.Accounts[0].Permissions.Base.Set(permission.Call, true) // give the 0 account permission
+	genDoc.Accounts[3].Permissions.Base.Set(permission.Bond, true) // some arbitrary permission to play with
 	genDoc.Accounts[3].Permissions.AddRole("bumble")
 	genDoc.Accounts[3].Permissions.AddRole("bee")
 	st, err := MakeGenesisState(stateDB, &genDoc)
@@ -713,17 +715,16 @@ func TestSNativeCALL(t *testing.T) {
 		Balance:     0,
 		Code:        nil,
 		Sequence:    0,
-		StorageRoot: Zero256.Bytes(),
 		Permissions: permission.ZeroAccountPermissions,
 	}.MutableAccount()
 
-	doug.MutablePermissions().Base.Set(ptypes.Call, true)
+	doug.MutablePermissions().Base.Set(permission.Call, true)
 	//doug.Permissions.Base.Set(permission.HasBase, true)
 	exe.stateCache.UpdateAccount(doug)
 
 	fmt.Println("\n#### HasBase")
 	// HasBase
-	snativeAddress, pF, data := snativePermTestInputCALL("hasBase", users[3], ptypes.Bond, false)
+	snativeAddress, pF, data := snativePermTestInputCALL("hasBase", users[3], permission.Bond, false)
 	testSNativeCALLExpectFail(t, exe, doug, snativeAddress, data)
 	testSNativeCALLExpectPass(t, exe, doug, pF, snativeAddress, data, func(ret []byte) error {
 		// return value should be true or false as a 32 byte array...
@@ -735,10 +736,10 @@ func TestSNativeCALL(t *testing.T) {
 
 	fmt.Println("\n#### SetBase")
 	// SetBase
-	snativeAddress, pF, data = snativePermTestInputCALL("setBase", users[3], ptypes.Bond, false)
+	snativeAddress, pF, data = snativePermTestInputCALL("setBase", users[3], permission.Bond, false)
 	testSNativeCALLExpectFail(t, exe, doug, snativeAddress, data)
 	testSNativeCALLExpectPass(t, exe, doug, pF, snativeAddress, data, func(ret []byte) error { return nil })
-	snativeAddress, pF, data = snativePermTestInputCALL("hasBase", users[3], ptypes.Bond, false)
+	snativeAddress, pF, data = snativePermTestInputCALL("hasBase", users[3], permission.Bond, false)
 	testSNativeCALLExpectPass(t, exe, doug, pF, snativeAddress, data, func(ret []byte) error {
 		// return value should be true or false as a 32 byte array...
 		if !IsZeros(ret) {
@@ -746,9 +747,9 @@ func TestSNativeCALL(t *testing.T) {
 		}
 		return nil
 	})
-	snativeAddress, pF, data = snativePermTestInputCALL("setBase", users[3], ptypes.CreateContract, true)
+	snativeAddress, pF, data = snativePermTestInputCALL("setBase", users[3], permission.CreateContract, true)
 	testSNativeCALLExpectPass(t, exe, doug, pF, snativeAddress, data, func(ret []byte) error { return nil })
-	snativeAddress, pF, data = snativePermTestInputCALL("hasBase", users[3], ptypes.CreateContract, false)
+	snativeAddress, pF, data = snativePermTestInputCALL("hasBase", users[3], permission.CreateContract, false)
 	testSNativeCALLExpectPass(t, exe, doug, pF, snativeAddress, data, func(ret []byte) error {
 		// return value should be true or false as a 32 byte array...
 		if !IsZeros(ret[:31]) || ret[31] != byte(1) {
@@ -759,10 +760,10 @@ func TestSNativeCALL(t *testing.T) {
 
 	fmt.Println("\n#### UnsetBase")
 	// UnsetBase
-	snativeAddress, pF, data = snativePermTestInputCALL("unsetBase", users[3], ptypes.CreateContract, false)
+	snativeAddress, pF, data = snativePermTestInputCALL("unsetBase", users[3], permission.CreateContract, false)
 	testSNativeCALLExpectFail(t, exe, doug, snativeAddress, data)
 	testSNativeCALLExpectPass(t, exe, doug, pF, snativeAddress, data, func(ret []byte) error { return nil })
-	snativeAddress, pF, data = snativePermTestInputCALL("hasBase", users[3], ptypes.CreateContract, false)
+	snativeAddress, pF, data = snativePermTestInputCALL("hasBase", users[3], permission.CreateContract, false)
 	testSNativeCALLExpectPass(t, exe, doug, pF, snativeAddress, data, func(ret []byte) error {
 		if !IsZeros(ret) {
 			return fmt.Errorf("Expected 0. Got %X", ret)
@@ -772,10 +773,10 @@ func TestSNativeCALL(t *testing.T) {
 
 	fmt.Println("\n#### SetGlobal")
 	// SetGlobalPerm
-	snativeAddress, pF, data = snativePermTestInputCALL("setGlobal", users[3], ptypes.CreateContract, true)
+	snativeAddress, pF, data = snativePermTestInputCALL("setGlobal", users[3], permission.CreateContract, true)
 	testSNativeCALLExpectFail(t, exe, doug, snativeAddress, data)
 	testSNativeCALLExpectPass(t, exe, doug, pF, snativeAddress, data, func(ret []byte) error { return nil })
-	snativeAddress, pF, data = snativePermTestInputCALL("hasBase", users[3], ptypes.CreateContract, false)
+	snativeAddress, pF, data = snativePermTestInputCALL("hasBase", users[3], permission.CreateContract, false)
 	testSNativeCALLExpectPass(t, exe, doug, pF, snativeAddress, data, func(ret []byte) error {
 		// return value should be true or false as a 32 byte array...
 		if !IsZeros(ret[:31]) || ret[31] != byte(1) {
@@ -833,8 +834,8 @@ func TestSNativeTx(t *testing.T) {
 	stateDB := dbm.NewDB("state", dbBackend, dbDir)
 	defer stateDB.Close()
 	genDoc := newBaseGenDoc(permission.ZeroAccountPermissions, permission.ZeroAccountPermissions)
-	genDoc.Accounts[0].Permissions.Base.Set(ptypes.Call, true) // give the 0 account permission
-	genDoc.Accounts[3].Permissions.Base.Set(ptypes.Bond, true) // some arbitrary permission to play with
+	genDoc.Accounts[0].Permissions.Base.Set(permission.Call, true) // give the 0 account permission
+	genDoc.Accounts[3].Permissions.Base.Set(permission.Bond, true) // some arbitrary permission to play with
 	genDoc.Accounts[3].Permissions.AddRole("bumble")
 	genDoc.Accounts[3].Permissions.AddRole("bee")
 	st, err := MakeGenesisState(stateDB, &genDoc)
@@ -846,37 +847,37 @@ func TestSNativeTx(t *testing.T) {
 
 	fmt.Println("\n#### SetBase")
 	// SetBase
-	snativeArgs := snativePermTestInputTx("setBase", users[3], ptypes.Bond, false)
+	snativeArgs := snativePermTestInputTx("setBase", users[3], permission.Bond, false)
 	testSNativeTxExpectFail(t, batchCommitter, snativeArgs)
-	testSNativeTxExpectPass(t, batchCommitter, ptypes.SetBase, snativeArgs)
+	testSNativeTxExpectPass(t, batchCommitter, permission.SetBase, snativeArgs)
 	acc := getAccount(batchCommitter.stateCache, users[3].Address())
-	if v, _ := acc.MutablePermissions().Base.Get(ptypes.Bond); v {
+	if v, _ := acc.MutablePermissions().Base.Get(permission.Bond); v {
 		t.Fatal("expected permission to be set false")
 	}
-	snativeArgs = snativePermTestInputTx("setBase", users[3], ptypes.CreateContract, true)
-	testSNativeTxExpectPass(t, batchCommitter, ptypes.SetBase, snativeArgs)
+	snativeArgs = snativePermTestInputTx("setBase", users[3], permission.CreateContract, true)
+	testSNativeTxExpectPass(t, batchCommitter, permission.SetBase, snativeArgs)
 	acc = getAccount(batchCommitter.stateCache, users[3].Address())
-	if v, _ := acc.MutablePermissions().Base.Get(ptypes.CreateContract); !v {
+	if v, _ := acc.MutablePermissions().Base.Get(permission.CreateContract); !v {
 		t.Fatal("expected permission to be set true")
 	}
 
 	fmt.Println("\n#### UnsetBase")
 	// UnsetBase
-	snativeArgs = snativePermTestInputTx("unsetBase", users[3], ptypes.CreateContract, false)
+	snativeArgs = snativePermTestInputTx("unsetBase", users[3], permission.CreateContract, false)
 	testSNativeTxExpectFail(t, batchCommitter, snativeArgs)
-	testSNativeTxExpectPass(t, batchCommitter, ptypes.UnsetBase, snativeArgs)
+	testSNativeTxExpectPass(t, batchCommitter, permission.UnsetBase, snativeArgs)
 	acc = getAccount(batchCommitter.stateCache, users[3].Address())
-	if v, _ := acc.MutablePermissions().Base.Get(ptypes.CreateContract); v {
+	if v, _ := acc.MutablePermissions().Base.Get(permission.CreateContract); v {
 		t.Fatal("expected permission to be set false")
 	}
 
 	fmt.Println("\n#### SetGlobal")
 	// SetGlobalPerm
-	snativeArgs = snativePermTestInputTx("setGlobal", users[3], ptypes.CreateContract, true)
+	snativeArgs = snativePermTestInputTx("setGlobal", users[3], permission.CreateContract, true)
 	testSNativeTxExpectFail(t, batchCommitter, snativeArgs)
-	testSNativeTxExpectPass(t, batchCommitter, ptypes.SetGlobal, snativeArgs)
+	testSNativeTxExpectPass(t, batchCommitter, permission.SetGlobal, snativeArgs)
 	acc = getAccount(batchCommitter.stateCache, acm.GlobalPermissionsAddress)
-	if v, _ := acc.MutablePermissions().Base.Get(ptypes.CreateContract); !v {
+	if v, _ := acc.MutablePermissions().Base.Get(permission.CreateContract); !v {
 		t.Fatal("expected permission to be set true")
 	}
 
@@ -884,7 +885,7 @@ func TestSNativeTx(t *testing.T) {
 	// AddRole
 	snativeArgs = snativeRoleTestInputTx("addRole", users[3], "chuck")
 	testSNativeTxExpectFail(t, batchCommitter, snativeArgs)
-	testSNativeTxExpectPass(t, batchCommitter, ptypes.AddRole, snativeArgs)
+	testSNativeTxExpectPass(t, batchCommitter, permission.AddRole, snativeArgs)
 	acc = getAccount(batchCommitter.stateCache, users[3].Address())
 	if v := acc.Permissions().HasRole("chuck"); !v {
 		t.Fatal("expected role to be added")
@@ -894,7 +895,7 @@ func TestSNativeTx(t *testing.T) {
 	// RemoveRole
 	snativeArgs = snativeRoleTestInputTx("removeRole", users[3], "chuck")
 	testSNativeTxExpectFail(t, batchCommitter, snativeArgs)
-	testSNativeTxExpectPass(t, batchCommitter, ptypes.RemoveRole, snativeArgs)
+	testSNativeTxExpectPass(t, batchCommitter, permission.RemoveRole, snativeArgs)
 	acc = getAccount(batchCommitter.stateCache, users[3].Address())
 	if v := acc.Permissions().HasRole("chuck"); v {
 		t.Fatal("expected role to be removed")
@@ -951,8 +952,8 @@ func TestNameTxs(t *testing.T) {
 	st.writeState.save()
 
 	names.MinNameRegistrationPeriod = 5
-	blockchain := newBlockchain(testGenesisDoc)
-	startingBlock := blockchain.LastBlockHeight()
+	exe := makeExecutor(st)
+	startingBlock := exe.blockchain.LastBlockHeight()
 
 	// try some bad names. these should all fail
 	nameStrings := []string{"", "\n", "123#$%", "\x00", string([]byte{20, 40, 60, 80}),
@@ -964,10 +965,8 @@ func TestNameTxs(t *testing.T) {
 		amt := fee + numDesiredBlocks*names.NameByteCostMultiplier*names.NameBlockCostMultiplier*
 			names.NameBaseCost(name, data)
 		tx, _ := payload.NewNameTx(st, testPrivAccounts[0].PublicKey(), name, data, amt, fee)
-		txEnv := txs.Enclose(testChainID, tx)
-		txEnv.Sign(testPrivAccounts[0])
 
-		if err := execTxWithState(st, txEnv); err == nil {
+		if err = exe.signExecuteCommit(tx, testPrivAccounts[0]); err == nil {
 			t.Fatalf("Expected invalid name error from %s", name)
 		}
 	}
@@ -979,10 +978,8 @@ func TestNameTxs(t *testing.T) {
 		amt := fee + numDesiredBlocks*names.NameByteCostMultiplier*names.NameBlockCostMultiplier*
 			names.NameBaseCost(name, data)
 		tx, _ := payload.NewNameTx(st, testPrivAccounts[0].PublicKey(), name, data, amt, fee)
-		txEnv := txs.Enclose(testChainID, tx)
-		txEnv.Sign(testPrivAccounts[0])
 
-		if err := execTxWithState(st, txEnv); err == nil {
+		if err = exe.signExecuteCommit(tx, testPrivAccounts[0]); err == nil {
 			t.Fatalf("Expected invalid data error from %s", data)
 		}
 	}
@@ -1010,68 +1007,50 @@ func TestNameTxs(t *testing.T) {
 	data = "on this side of neptune there are 1234567890 people: first is OMNIVORE+-3. Or is it. Ok this is pretty restrictive. No exclamations :(. Faces tho :')"
 	amt := fee + numDesiredBlocks*names.NameByteCostMultiplier*names.NameBlockCostMultiplier*names.NameBaseCost(name, data)
 	tx, _ := payload.NewNameTx(st, testPrivAccounts[0].PublicKey(), name, data, amt, fee)
-	txEnv := txs.Enclose(testChainID, tx)
-	require.NoError(t, txEnv.Sign(testPrivAccounts[0]))
-	if err := execTxWithState(st, txEnv); err != nil {
-		t.Fatal(err)
-	}
-	entry, err := st.GetNameEntry(name)
+
+	require.NoError(t, exe.signExecuteCommit(tx, testPrivAccounts[0]))
+
+	entry, err := st.GetName(name)
 	require.NoError(t, err)
 	validateEntry(t, entry, name, data, testPrivAccounts[0].Address(), startingBlock+numDesiredBlocks)
 
 	// fail to update it as non-owner, in same block
 	tx, _ = payload.NewNameTx(st, testPrivAccounts[1].PublicKey(), name, data, amt, fee)
-	txEnv = txs.Enclose(testChainID, tx)
-	require.NoError(t, txEnv.Sign(testPrivAccounts[1]))
-	if err := execTxWithState(st, txEnv); err == nil {
-		t.Fatal("Expected error")
-	}
+	require.Error(t, exe.signExecuteCommit(tx, testPrivAccounts[1]))
 
 	// update it as owner, just to increase expiry, in same block
 	// NOTE: we have to resend the data or it will clear it (is this what we want?)
 	tx, _ = payload.NewNameTx(st, testPrivAccounts[0].PublicKey(), name, data, amt, fee)
-	txEnv = txs.Enclose(testChainID, tx)
-	require.NoError(t, txEnv.Sign(testPrivAccounts[0]))
-	if err := execTxWithStateNewBlock(st, blockchain, txEnv); err != nil {
-		t.Fatal(err)
-	}
-	entry, err = st.GetNameEntry(name)
+
+	require.NoError(t, exe.signExecuteCommit(tx, testPrivAccounts[0]))
+
+	entry, err = st.GetName(name)
 	require.NoError(t, err)
 	validateEntry(t, entry, name, data, testPrivAccounts[0].Address(), startingBlock+numDesiredBlocks*2)
 
 	// update it as owner, just to increase expiry, in next block
 	tx, _ = payload.NewNameTx(st, testPrivAccounts[0].PublicKey(), name, data, amt, fee)
-	txEnv = txs.Enclose(testChainID, tx)
-	require.NoError(t, txEnv.Sign(testPrivAccounts[0]))
-	if err := execTxWithStateNewBlock(st, blockchain, txEnv); err != nil {
-		t.Fatal(err)
-	}
-	entry, err = st.GetNameEntry(name)
+	require.NoError(t, exe.signExecuteCommit(tx, testPrivAccounts[0]))
+
+	entry, err = st.GetName(name)
 	require.NoError(t, err)
 	validateEntry(t, entry, name, data, testPrivAccounts[0].Address(), startingBlock+numDesiredBlocks*3)
 
 	// fail to update it as non-owner
 	// Fast forward
-	for blockchain.Tip.LastBlockHeight() < entry.Expires-1 {
-		commitNewBlock(st, blockchain)
+	for exe.blockchain.Tip.LastBlockHeight() < entry.Expires-1 {
+		commitNewBlock(st, exe.blockchain)
 	}
 	tx, _ = payload.NewNameTx(st, testPrivAccounts[1].PublicKey(), name, data, amt, fee)
-	txEnv = txs.Enclose(testChainID, tx)
-	require.NoError(t, txEnv.Sign(testPrivAccounts[1]))
-	if err := execTxWithStateAndBlockchain(st, blockchain, txEnv); err == nil {
-		t.Fatal("Expected error")
-	}
-	commitNewBlock(st, blockchain)
+	require.Error(t, exe.signExecuteCommit(tx, testPrivAccounts[1]))
+	commitNewBlock(st, exe.blockchain)
 
 	// once expires, non-owner succeeds
-	startingBlock = blockchain.LastBlockHeight()
+	startingBlock = exe.blockchain.LastBlockHeight()
 	tx, _ = payload.NewNameTx(st, testPrivAccounts[1].PublicKey(), name, data, amt, fee)
-	txEnv = txs.Enclose(testChainID, tx)
-	require.NoError(t, txEnv.Sign(testPrivAccounts[1]))
-	if err := execTxWithStateAndBlockchain(st, blockchain, txEnv); err != nil {
-		t.Fatal(err)
-	}
-	entry, err = st.GetNameEntry(name)
+	require.NoError(t, exe.signExecuteCommit(tx, testPrivAccounts[1]))
+
+	entry, err = st.GetName(name)
 	require.NoError(t, err)
 	validateEntry(t, entry, name, data, testPrivAccounts[1].Address(), startingBlock+numDesiredBlocks)
 
@@ -1081,12 +1060,9 @@ func TestNameTxs(t *testing.T) {
 	numDesiredBlocks = 10
 	amt = fee + numDesiredBlocks*names.NameByteCostMultiplier*names.NameBlockCostMultiplier*names.NameBaseCost(name, data) - oldCredit
 	tx, _ = payload.NewNameTx(st, testPrivAccounts[1].PublicKey(), name, data, amt, fee)
-	txEnv = txs.Enclose(testChainID, tx)
-	require.NoError(t, txEnv.Sign(testPrivAccounts[1]))
-	if err := execTxWithStateAndBlockchain(st, blockchain, txEnv); err != nil {
-		t.Fatal(err)
-	}
-	entry, err = st.GetNameEntry(name)
+	require.NoError(t, exe.signExecuteCommit(tx, testPrivAccounts[1]))
+
+	entry, err = st.GetName(name)
 	require.NoError(t, err)
 	validateEntry(t, entry, name, data, testPrivAccounts[1].Address(), startingBlock+numDesiredBlocks)
 
@@ -1094,12 +1070,9 @@ func TestNameTxs(t *testing.T) {
 	amt = fee
 	data = ""
 	tx, _ = payload.NewNameTx(st, testPrivAccounts[1].PublicKey(), name, data, amt, fee)
-	txEnv = txs.Enclose(testChainID, tx)
-	require.NoError(t, txEnv.Sign(testPrivAccounts[1]))
-	if err := execTxWithStateNewBlock(st, blockchain, txEnv); err != nil {
-		t.Fatal(err)
-	}
-	entry, err = st.GetNameEntry(name)
+	require.NoError(t, exe.signExecuteCommit(tx, testPrivAccounts[1]))
+
+	entry, err = st.GetName(name)
 	require.NoError(t, err)
 	if entry != nil {
 		t.Fatal("Expected removed entry to be nil")
@@ -1107,33 +1080,27 @@ func TestNameTxs(t *testing.T) {
 
 	// create entry by key0,
 	// test removal by key1 after expiry
-	startingBlock = blockchain.LastBlockHeight()
+	startingBlock = exe.blockchain.LastBlockHeight()
 	name = "looking_good/karaoke_bar"
 	data = "some data"
 	amt = fee + numDesiredBlocks*names.NameByteCostMultiplier*names.NameBlockCostMultiplier*names.NameBaseCost(name, data)
 	tx, _ = payload.NewNameTx(st, testPrivAccounts[0].PublicKey(), name, data, amt, fee)
-	txEnv = txs.Enclose(testChainID, tx)
-	require.NoError(t, txEnv.Sign(testPrivAccounts[0]))
-	if err := execTxWithStateAndBlockchain(st, blockchain, txEnv); err != nil {
-		t.Fatal(err)
-	}
-	entry, err = st.GetNameEntry(name)
+	require.NoError(t, exe.signExecuteCommit(tx, testPrivAccounts[0]))
+
+	entry, err = st.GetName(name)
 	require.NoError(t, err)
 	validateEntry(t, entry, name, data, testPrivAccounts[0].Address(), startingBlock+numDesiredBlocks)
 	// Fast forward
-	for blockchain.Tip.LastBlockHeight() < entry.Expires {
-		commitNewBlock(st, blockchain)
+	for exe.blockchain.Tip.LastBlockHeight() < entry.Expires {
+		commitNewBlock(st, exe.blockchain)
 	}
 
 	amt = fee
 	data = ""
 	tx, _ = payload.NewNameTx(st, testPrivAccounts[1].PublicKey(), name, data, amt, fee)
-	txEnv = txs.Enclose(testChainID, tx)
-	require.NoError(t, txEnv.Sign(testPrivAccounts[1]))
-	if err := execTxWithStateNewBlock(st, blockchain, txEnv); err != nil {
-		t.Fatal(err)
-	}
-	entry, err = st.GetNameEntry(name)
+	require.NoError(t, exe.signExecuteCommit(tx, testPrivAccounts[1]))
+
+	entry, err = st.GetName(name)
 	require.NoError(t, err)
 	if entry != nil {
 		t.Fatal("Expected removed entry to be nil")
@@ -1166,20 +1133,22 @@ var createData, _ = hex.DecodeString("9ed93318")
 
 func TestCreates(t *testing.T) {
 	//evm.SetDebug(true)
-	state, privAccounts := makeGenesisState(3, true, 1000, 1, true, 1000)
+	st, privAccounts := makeGenesisState(3, true, 1000, 1, true, 1000)
 
 	//val0 := state.GetValidatorInfo(privValidators[0].Address())
-	acc0 := getAccount(state, privAccounts[0].Address())
-	acc1 := getAccount(state, privAccounts[1].Address())
-	acc2 := getAccount(state, privAccounts[2].Address())
+	acc0 := getAccount(st, privAccounts[0].Address())
+	acc1 := getAccount(st, privAccounts[1].Address())
+	acc2 := getAccount(st, privAccounts[2].Address())
 
-	newAcc1 := getAccount(state, acc1.Address())
+	exe := makeExecutor(st)
+
+	newAcc1 := getAccount(st, acc1.Address())
 	newAcc1.SetCode(preFactoryCode)
-	newAcc2 := getAccount(state, acc2.Address())
+	newAcc2 := getAccount(st, acc2.Address())
 	newAcc2.SetCode(factoryCode)
 
-	state.writeState.UpdateAccount(newAcc1)
-	state.writeState.UpdateAccount(newAcc2)
+	st.writeState.UpdateAccount(newAcc1)
+	st.writeState.UpdateAccount(newAcc2)
 
 	createData = append(createData, acc2.Address().Word256().Bytes()...)
 
@@ -1195,39 +1164,29 @@ func TestCreates(t *testing.T) {
 		Data:     createData,
 	}
 
-	txEnv := txs.Enclose(testChainID, tx)
-	require.NoError(t, txEnv.Sign(privAccounts[0]))
-	err := execTxWithState(state, txEnv)
-	if err != nil {
-		t.Errorf("Got error in executing call transaction, %v", err)
-	}
+	require.NoError(t, exe.signExecuteCommit(tx, privAccounts[0]))
 
-	acc1 = getAccount(state, acc1.Address())
-	firstCreatedAddress, err := state.GetStorage(acc1.Address(), LeftPadWord256(nil))
+	acc1 = getAccount(st, acc1.Address())
+	firstCreatedAddress, err := st.GetStorage(acc1.Address(), LeftPadWord256(nil))
 	require.NoError(t, err)
 
-	acc0 = getAccount(state, acc0.Address())
+	acc0 = getAccount(st, acc0.Address())
 	// call the pre-factory, triggering the factory to run a create
 	tx = &payload.CallTx{
 		Input: &payload.TxInput{
 			Address:  acc0.Address(),
 			Amount:   1,
-			Sequence: acc0.Sequence() + 1,
+			Sequence: tx.Input.Sequence + 1,
 		},
 		Address:  addressPtr(acc1),
 		GasLimit: 100000,
 		Data:     createData,
 	}
 
-	txEnv = txs.Enclose(testChainID, tx)
-	require.NoError(t, txEnv.Sign(privAccounts[0]))
-	err = execTxWithState(state, txEnv)
-	if err != nil {
-		t.Errorf("Got error in executing call transaction, %v", err)
-	}
+	require.NoError(t, exe.signExecuteCommit(tx, privAccounts[0]))
 
-	acc1 = getAccount(state, acc1.Address())
-	secondCreatedAddress, err := state.GetStorage(acc1.Address(), LeftPadWord256(nil))
+	acc1 = getAccount(st, acc1.Address())
+	secondCreatedAddress, err := st.GetStorage(acc1.Address(), LeftPadWord256(nil))
 	require.NoError(t, err)
 
 	if firstCreatedAddress == secondCreatedAddress {
@@ -1487,7 +1446,7 @@ proof-of-work chain as proof of what happened while they were gone `
 			t.Errorf("Unexpected newAcc0 balance. Expected %v, got %v",
 				acc0.Balance()-entryAmount, newAcc0.Balance())
 		}
-		entry, err := stateNameTx.GetNameEntry(entryName)
+		entry, err := stateNameTx.GetName(entryName)
 		require.NoError(t, err)
 		if entry == nil {
 			t.Errorf("Expected an entry but got nil")
@@ -1502,8 +1461,8 @@ proof-of-work chain as proof of what happened while they were gone `
 		txEnv = txs.Enclose(testChainID, tx)
 		require.NoError(t, txEnv.Sign(privAccounts[0]))
 		err = execTxWithState(stateNameTx, txEnv)
-		if _, ok := err.(payload.ErrTxInvalidString); !ok {
-			t.Errorf("Expected invalid string error. Got: %s", err.Error())
+		if errors.AsException(err).ErrorCode() != errors.ErrorCodeInvalidString {
+			t.Errorf("Expected invalid string error. Got: %v", err)
 		}
 	}
 
@@ -1596,7 +1555,7 @@ func TestSelfDestruct(t *testing.T) {
 	signAndExecute(t, false, exe, testChainID, tx, privAccounts[0])
 
 	// commit the block
-	exe.Commit()
+	exe.Commit(nil)
 
 	// acc2 should receive the sent funds and the contracts balance
 	newAcc2 := getAccount(st, acc2.Address())
@@ -1616,10 +1575,11 @@ func signAndExecute(t *testing.T, shouldFail bool, exe BatchExecutor, chainID st
 
 	env := txs.Enclose(chainID, tx)
 	require.NoError(t, env.Sign(signers...), "Could not sign tx in call: %s", debug.Stack())
+	_, err := exe.Execute(env)
 	if shouldFail {
-		require.Error(t, exe.Execute(env), "Tx should fail in call: %s", debug.Stack())
+		require.Error(t, err, "Tx should fail in call: %s", debug.Stack())
 	} else {
-		require.NoError(t, exe.Execute(env), "Could not execute tx in call: %s", debug.Stack())
+		require.NoError(t, err, "Could not execute tx in call: %s", debug.Stack())
 	}
 	return env
 }
@@ -1627,10 +1587,13 @@ func signAndExecute(t *testing.T, shouldFail bool, exe BatchExecutor, chainID st
 func execTxWithStateAndBlockchain(state *State, blockchain *bcm.Blockchain, txEnv *txs.Envelope) error {
 	exe := newExecutor("execTxWithStateAndBlockchainCache", true, state, blockchain.Tip,
 		event.NewNoOpPublisher(), logger)
-	if err := exe.Execute(txEnv); err != nil {
+	if _, err := exe.Execute(txEnv); err != nil {
 		return err
 	} else {
-		exe.Commit()
+		_, err := exe.Commit(nil)
+		if err != nil {
+			return err
+		}
 		commitNewBlock(state, blockchain)
 		return nil
 	}
@@ -1665,7 +1628,7 @@ func makeGenesisState(numAccounts int, randBalance bool, minBalance uint64, numV
 	return s0, privAccounts
 }
 
-func getAccount(accountGetter state.AccountGetter, address crypto.Address) acm.MutableAccount {
+func getAccount(accountGetter state.AccountGetter, address crypto.Address) *acm.MutableAccount {
 	acc, _ := state.GetMutableAccount(accountGetter, address)
 	return acc
 }
@@ -1686,46 +1649,44 @@ var ExceptionTimeOut = errors.NewCodedError(errors.ErrorCodeGeneric, "timed out
 // run ExecTx and wait for the Call event on given addr
 // returns the msg data and an error/exception
 func execTxWaitAccountCall(t *testing.T, exe *testExecutor, txEnv *txs.Envelope,
-	address crypto.Address) (*events.EventDataCall, error) {
-
-	ch := make(chan *events.EventDataCall)
-	ctx := context.Background()
-	const subscriber = "execTxWaitEvent"
-	events.SubscribeAccountCall(ctx, exe, subscriber, address, txEnv.Tx.Hash(), -1, ch)
-	defer exe.UnsubscribeAll(ctx, subscriber)
-	err := exe.Execute(txEnv)
+	address crypto.Address) (*exec.CallEvent, error) {
+
+	qry, err := event.QueryForEventID(exec.EventStringAccountCall(address)).
+		AndEquals(event.TxHashKey, txEnv.Tx.Hash()).Query()
 	if err != nil {
 		return nil, err
 	}
-	exe.Commit()
-	exe.blockchain.CommitBlock(time.Time{}, nil, nil)
-	ticker := time.NewTicker(5 * time.Second)
-
-	select {
-	case eventDataCall := <-ch:
-		fmt.Println("MSG: ", eventDataCall)
-		return eventDataCall, eventDataCall.Exception.AsError()
-
-	case <-ticker.C:
-		return nil, ExceptionTimeOut
+	evs, err := exe.Execute(txEnv)
+	if err != nil {
+		return nil, err
 	}
+	_, err = exe.Commit(nil)
+	require.NoError(t, err)
+	err = exe.blockchain.CommitBlock(time.Time{}, nil, nil)
+	require.NoError(t, err)
 
+	for _, ev := range evs.TaggedEvents().Filter(qry) {
+		if ev.Call != nil {
+			return ev.Call, ev.Header.Exception.AsError()
+		}
+	}
+	return nil, fmt.Errorf("did not receive EventDataCall execution event from execTxWaitAccountCall")
 }
 
 // give a contract perms for an snative, call it, it calls the snative, but shouldn't have permission
-func testSNativeCALLExpectFail(t *testing.T, exe *testExecutor, doug acm.MutableAccount,
+func testSNativeCALLExpectFail(t *testing.T, exe *testExecutor, doug *acm.MutableAccount,
 	snativeAddress crypto.Address, data []byte) {
 	testSNativeCALL(t, false, exe, doug, 0, snativeAddress, data, nil)
 }
 
 // give a contract perms for an snative, call it, it calls the snative, ensure the check funciton (f) succeeds
-func testSNativeCALLExpectPass(t *testing.T, exe *testExecutor, doug acm.MutableAccount, snativePerm ptypes.PermFlag,
+func testSNativeCALLExpectPass(t *testing.T, exe *testExecutor, doug *acm.MutableAccount, snativePerm permission.PermFlag,
 	snativeAddress crypto.Address, data []byte, f func([]byte) error) {
 	testSNativeCALL(t, true, exe, doug, snativePerm, snativeAddress, data, f)
 }
 
-func testSNativeCALL(t *testing.T, expectPass bool, exe *testExecutor, doug acm.MutableAccount,
-	snativePerm ptypes.PermFlag, snativeAddress crypto.Address, data []byte, f func([]byte) error) {
+func testSNativeCALL(t *testing.T, expectPass bool, exe *testExecutor, doug *acm.MutableAccount,
+	snativePerm permission.PermFlag, snativeAddress crypto.Address, data []byte, f func([]byte) error) {
 	if expectPass {
 		doug.MutablePermissions().Base.Set(snativePerm, true)
 	}
@@ -1737,7 +1698,6 @@ func testSNativeCALL(t *testing.T, expectPass bool, exe *testExecutor, doug acm.
 	tx, _ := payload.NewCallTx(exe.stateCache, users[0].PublicKey(), &dougAddress, data, 100, 10000, 100)
 	txEnv := txs.Enclose(testChainID, tx)
 	require.NoError(t, txEnv.Sign(users[0]))
-	t.Logf("subscribing to %v", events.EventStringAccountCall(snativeAddress))
 	ev, err := execTxWaitAccountCall(t, exe, txEnv, snativeAddress)
 	if err == ExceptionTimeOut {
 		t.Fatal("Timed out waiting for event")
@@ -1753,17 +1713,17 @@ func testSNativeCALL(t *testing.T, expectPass bool, exe *testExecutor, doug acm.
 	}
 }
 
-func testSNativeTxExpectFail(t *testing.T, batchCommitter *testExecutor, snativeArgs snatives.PermArgs) {
+func testSNativeTxExpectFail(t *testing.T, batchCommitter *testExecutor, snativeArgs permission.PermArgs) {
 	testSNativeTx(t, false, batchCommitter, 0, snativeArgs)
 }
 
-func testSNativeTxExpectPass(t *testing.T, batchCommitter *testExecutor, perm ptypes.PermFlag,
-	snativeArgs snatives.PermArgs) {
+func testSNativeTxExpectPass(t *testing.T, batchCommitter *testExecutor, perm permission.PermFlag,
+	snativeArgs permission.PermArgs) {
 	testSNativeTx(t, true, batchCommitter, perm, snativeArgs)
 }
 
-func testSNativeTx(t *testing.T, expectPass bool, batchCommitter *testExecutor, perm ptypes.PermFlag,
-	snativeArgs snatives.PermArgs) {
+func testSNativeTx(t *testing.T, expectPass bool, batchCommitter *testExecutor, perm permission.PermFlag,
+	snativeArgs permission.PermArgs) {
 	if expectPass {
 		acc := getAccount(batchCommitter.stateCache, users[0].Address())
 		acc.MutablePermissions().Base.Set(perm, true)
@@ -1772,7 +1732,7 @@ func testSNativeTx(t *testing.T, expectPass bool, batchCommitter *testExecutor,
 	tx, _ := payload.NewPermissionsTx(batchCommitter.stateCache, users[0].PublicKey(), snativeArgs)
 	txEnv := txs.Enclose(testChainID, tx)
 	require.NoError(t, txEnv.Sign(users[0]))
-	err := batchCommitter.Execute(txEnv)
+	_, err := batchCommitter.Execute(txEnv)
 	if expectPass {
 		if err != nil {
 			t.Fatal("Unexpected exception", err)
@@ -1803,8 +1763,8 @@ func permNameToFuncID(name string) []byte {
 	return id[:]
 }
 
-func snativePermTestInputCALL(name string, user acm.AddressableSigner, perm ptypes.PermFlag,
-	val bool) (addr crypto.Address, pF ptypes.PermFlag, data []byte) {
+func snativePermTestInputCALL(name string, user acm.AddressableSigner, perm permission.PermFlag,
+	val bool) (addr crypto.Address, pF permission.PermFlag, data []byte) {
 	addr = permissionsContract.Address()
 	switch name {
 	case "hasBase", "unsetBase":
@@ -1820,50 +1780,50 @@ func snativePermTestInputCALL(name string, user acm.AddressableSigner, perm ptyp
 	}
 	data = append(permNameToFuncID(name), data...)
 	var err error
-	if pF, err = ptypes.PermStringToFlag(name); err != nil {
+	if pF, err = permission.PermStringToFlag(name); err != nil {
 		panic(fmt.Sprintf("failed to convert perm string (%s) to flag", name))
 	}
 	return
 }
 
-func snativePermTestInputTx(name string, user acm.AddressableSigner, perm ptypes.PermFlag,
-	val bool) (snativeArgs snatives.PermArgs) {
+func snativePermTestInputTx(name string, user acm.AddressableSigner, perm permission.PermFlag,
+	val bool) (snativeArgs permission.PermArgs) {
 
 	switch name {
 	case "hasBase":
-		snativeArgs = snatives.HasBaseArgs(user.Address(), perm)
+		snativeArgs = permission.HasBaseArgs(user.Address(), perm)
 	case "unsetBase":
-		snativeArgs = snatives.UnsetBaseArgs(user.Address(), perm)
+		snativeArgs = permission.UnsetBaseArgs(user.Address(), perm)
 	case "setBase":
-		snativeArgs = snatives.SetBaseArgs(user.Address(), perm, val)
+		snativeArgs = permission.SetBaseArgs(user.Address(), perm, val)
 	case "setGlobal":
-		snativeArgs = snatives.SetGlobalArgs(perm, val)
+		snativeArgs = permission.SetGlobalArgs(perm, val)
 	}
 	return
 }
 
 func snativeRoleTestInputCALL(name string, user acm.AddressableSigner,
-	role string) (addr crypto.Address, pF ptypes.PermFlag, data []byte) {
+	role string) (addr crypto.Address, pF permission.PermFlag, data []byte) {
 	addr = permissionsContract.Address()
 	data = user.Address().Word256().Bytes()
 	data = append(data, RightPadBytes([]byte(role), 32)...)
 	data = append(permNameToFuncID(name), data...)
 
 	var err error
-	if pF, err = ptypes.PermStringToFlag(name); err != nil {
+	if pF, err = permission.PermStringToFlag(name); err != nil {
 		panic(fmt.Sprintf("failed to convert perm string (%s) to flag", name))
 	}
 	return
 }
 
-func snativeRoleTestInputTx(name string, user acm.AddressableSigner, role string) (snativeArgs snatives.PermArgs) {
+func snativeRoleTestInputTx(name string, user acm.AddressableSigner, role string) (snativeArgs permission.PermArgs) {
 	switch name {
 	case "hasRole":
-		snativeArgs = snatives.HasRoleArgs(user.Address(), role)
+		snativeArgs = permission.HasRoleArgs(user.Address(), role)
 	case "addRole":
-		snativeArgs = snatives.AddRoleArgs(user.Address(), role)
+		snativeArgs = permission.AddRoleArgs(user.Address(), role)
 	case "removeRole":
-		snativeArgs = snatives.RemoveRoleArgs(user.Address(), role)
+		snativeArgs = permission.RemoveRoleArgs(user.Address(), role)
 	}
 	return
 }
diff --git a/execution/executors/call.go b/execution/executors/call_context.go
similarity index 73%
rename from execution/executors/call.go
rename to execution/executors/call_context.go
index ce79fc5c2a6ddaecca585f3c2a21ec8761dcc4a1..78fa25e4a7218770693655e267da7a433d428bfd 100644
--- a/execution/executors/call.go
+++ b/execution/executors/call_context.go
@@ -3,17 +3,15 @@ package executors
 import (
 	"fmt"
 
-	acm "github.com/hyperledger/burrow/account"
-	"github.com/hyperledger/burrow/account/state"
+	"github.com/hyperledger/burrow/acm"
+	"github.com/hyperledger/burrow/acm/state"
 	"github.com/hyperledger/burrow/binary"
 	"github.com/hyperledger/burrow/blockchain"
-	"github.com/hyperledger/burrow/event"
 	"github.com/hyperledger/burrow/execution/errors"
-	"github.com/hyperledger/burrow/execution/events"
 	"github.com/hyperledger/burrow/execution/evm"
+	"github.com/hyperledger/burrow/execution/exec"
 	"github.com/hyperledger/burrow/logging"
 	"github.com/hyperledger/burrow/logging/structure"
-	"github.com/hyperledger/burrow/txs"
 	"github.com/hyperledger/burrow/txs/payload"
 )
 
@@ -21,23 +19,22 @@ import (
 const GasLimit = uint64(1000000)
 
 type CallContext struct {
-	Tip            blockchain.TipInfo
-	StateWriter    state.ReaderWriter
-	EventPublisher event.Publisher
-	RunCall        bool
-	VMOptions      []func(*evm.VM)
-	Logger         *logging.Logger
-	tx             *payload.CallTx
-	txEnv          *txs.Envelope
+	Tip         blockchain.TipInfo
+	StateWriter state.ReaderWriter
+	RunCall     bool
+	VMOptions   []func(*evm.VM)
+	Logger      *logging.Logger
+	tx          *payload.CallTx
+	txe         *exec.TxExecution
 }
 
-func (ctx *CallContext) Execute(txEnv *txs.Envelope) error {
+func (ctx *CallContext) Execute(txe *exec.TxExecution) error {
 	var ok bool
-	ctx.tx, ok = txEnv.Tx.Payload.(*payload.CallTx)
+	ctx.tx, ok = txe.Envelope.Tx.Payload.(*payload.CallTx)
 	if !ok {
-		return fmt.Errorf("payload must be CallTx, but is: %v", txEnv.Tx.Payload)
+		return fmt.Errorf("payload must be CallTx, but is: %v", txe.Envelope.Tx.Payload)
 	}
-	ctx.txEnv = txEnv
+	ctx.txe = txe
 	inAcc, outAcc, err := ctx.Precheck()
 	if err != nil {
 		return err
@@ -46,15 +43,12 @@ func (ctx *CallContext) Execute(txEnv *txs.Envelope) error {
 	value := ctx.tx.Input.Amount - ctx.tx.Fee
 
 	if ctx.RunCall {
-		ctx.Deliver(inAcc, outAcc, value)
-	} else {
-		ctx.Check(inAcc, value)
+		return ctx.Deliver(inAcc, outAcc, value)
 	}
-
-	return nil
+	return ctx.Check(inAcc, value)
 }
 
-func (ctx *CallContext) Precheck() (acm.MutableAccount, acm.Account, error) {
+func (ctx *CallContext) Precheck() (*acm.MutableAccount, acm.Account, error) {
 	var outAcc acm.Account
 	// Validate input
 	inAcc, err := state.GetMutableAccount(ctx.StateWriter, ctx.tx.Input.Address)
@@ -85,7 +79,8 @@ func (ctx *CallContext) Precheck() (acm.MutableAccount, acm.Account, error) {
 		"old_sequence", inAcc.Sequence(),
 		"new_sequence", inAcc.Sequence()+1)
 
-	inAcc, err = inAcc.IncSequence().SubtractFromBalance(ctx.tx.Fee)
+	inAcc.IncSequence()
+	err = inAcc.SubtractFromBalance(ctx.tx.Fee)
 	if err != nil {
 		return nil, nil, err
 	}
@@ -126,13 +121,13 @@ func (ctx *CallContext) Precheck() (acm.MutableAccount, acm.Account, error) {
 	return inAcc, outAcc, nil
 }
 
-func (ctx *CallContext) Check(inAcc acm.MutableAccount, value uint64) error {
+func (ctx *CallContext) Check(inAcc *acm.MutableAccount, value uint64) error {
 	createContract := ctx.tx.Address == nil
 	// The mempool does not call txs until
 	// the proposer determines the order of txs.
 	// So mempool will skip the actual .Call(),
 	// and only deduct from the caller's balance.
-	inAcc, err := inAcc.SubtractFromBalance(value)
+	err := inAcc.SubtractFromBalance(value)
 	if err != nil {
 		return err
 	}
@@ -145,20 +140,24 @@ func (ctx *CallContext) Check(inAcc acm.MutableAccount, value uint64) error {
 			"new_sequence", inAcc.Sequence()+1)
 		inAcc.IncSequence()
 	}
-	return ctx.StateWriter.UpdateAccount(inAcc)
+	err = ctx.StateWriter.UpdateAccount(inAcc)
+	if err != nil {
+		return err
+	}
+	return nil
 }
 
 func (ctx *CallContext) Deliver(inAcc, outAcc acm.Account, value uint64) error {
 	createContract := ctx.tx.Address == nil
 	// VM call variables
 	var (
-		gas     uint64             = ctx.tx.GasLimit
-		caller  acm.MutableAccount = acm.AsMutableAccount(inAcc)
-		callee  acm.MutableAccount = nil // initialized below
-		code    []byte             = nil
-		ret     []byte             = nil
-		txCache                    = state.NewCache(ctx.StateWriter, state.Name("TxCache"))
-		params                     = evm.Params{
+		gas     uint64              = ctx.tx.GasLimit
+		caller  *acm.MutableAccount = acm.AsMutableAccount(inAcc)
+		callee  *acm.MutableAccount = nil // initialized below
+		code    []byte              = nil
+		ret     []byte              = nil
+		txCache                     = state.NewCache(ctx.StateWriter, state.Name("TxCache"))
+		params                      = evm.Params{
 			BlockHeight: ctx.Tip.LastBlockHeight(),
 			BlockHash:   binary.LeftPadWord256(ctx.Tip.LastBlockHash()),
 			BlockTime:   ctx.Tip.LastBlockTime().Unix(),
@@ -192,7 +191,7 @@ func (ctx *CallContext) Deliver(inAcc, outAcc acm.Account, value uint64) error {
 					"caller_address", inAcc.Address(),
 					"callee_address", ctx.tx.Address)
 			}
-			ctx.FireCallEvents(nil, payload.ErrTxInvalidAddress)
+			ctx.CallEvents(payload.ErrTxInvalidAddress)
 			return nil
 		}
 		callee = acm.AsMutableAccount(outAcc)
@@ -206,8 +205,8 @@ func (ctx *CallContext) Deliver(inAcc, outAcc acm.Account, value uint64) error {
 
 	txCache.UpdateAccount(caller)
 	txCache.UpdateAccount(callee)
-	vmach := evm.NewVM(params, caller.Address(), ctx.txEnv.Tx, ctx.Logger, ctx.VMOptions...)
-	vmach.SetPublisher(ctx.EventPublisher)
+	vmach := evm.NewVM(params, caller.Address(), ctx.txe.Envelope.Tx, ctx.Logger, ctx.VMOptions...)
+	vmach.SetEventSink(ctx.txe)
 	// NOTE: Call() transfers the value from caller to callee iff call succeeds.
 	ret, exception := vmach.Call(txCache, caller, callee, code, ctx.tx.Data, value, &gas)
 	if exception != nil {
@@ -224,25 +223,21 @@ func (ctx *CallContext) Deliver(inAcc, outAcc acm.Account, value uint64) error {
 			return err
 		}
 	}
+	ctx.CallEvents(exception)
+	ctx.txe.Return(ret, ctx.tx.GasLimit-gas)
 	// Create a receipt from the ret and whether it erred.
 	ctx.Logger.TraceMsg("VM call complete",
 		"caller", caller,
 		"callee", callee,
 		"return", ret,
 		structure.ErrorKey, exception)
-	ctx.FireCallEvents(ret, exception)
 	return nil
 }
 
-func (ctx *CallContext) FireCallEvents(ret []byte, err error) {
-	// Fire Events for sender and receiver
-	// a separate event will be fired from vm for each additional call
-	if ctx.EventPublisher != nil {
-		events.PublishAccountInput(ctx.EventPublisher, ctx.Tip.LastBlockHeight(), ctx.tx.Input.Address, ctx.txEnv.Tx,
-			ret, errors.AsCodedError(err))
-		if ctx.tx.Address != nil {
-			events.PublishAccountOutput(ctx.EventPublisher, ctx.Tip.LastBlockHeight(), *ctx.tx.Address, ctx.txEnv.Tx,
-				ret, errors.AsCodedError(err))
-		}
+func (ctx *CallContext) CallEvents(err error) {
+	// Fire Events for sender and receiver a separate event will be fired from vm for each additional call
+	ctx.txe.Input(ctx.tx.Input.Address, errors.AsException(err))
+	if ctx.tx.Address != nil {
+		ctx.txe.Input(*ctx.tx.Address, errors.AsException(err))
 	}
 }
diff --git a/execution/executors/name.go b/execution/executors/name_context.go
similarity index 67%
rename from execution/executors/name.go
rename to execution/executors/name_context.go
index 658992d5331687450cf34fe524ddbde96a9f9583..ce8396704b35f75b58d536f017282ecaab9589d6 100644
--- a/execution/executors/name.go
+++ b/execution/executors/name_context.go
@@ -3,31 +3,36 @@ package executors
 import (
 	"fmt"
 
-	"github.com/hyperledger/burrow/account/state"
+	"regexp"
+
+	"github.com/hyperledger/burrow/acm/state"
 	"github.com/hyperledger/burrow/blockchain"
-	"github.com/hyperledger/burrow/event"
-	"github.com/hyperledger/burrow/execution/events"
+	"github.com/hyperledger/burrow/execution/errors"
+	"github.com/hyperledger/burrow/execution/exec"
 	"github.com/hyperledger/burrow/execution/names"
 	"github.com/hyperledger/burrow/logging"
 	"github.com/hyperledger/burrow/logging/structure"
-	"github.com/hyperledger/burrow/txs"
 	"github.com/hyperledger/burrow/txs/payload"
 )
 
+// Name should be file system like
+// Data should be anything permitted in JSON
+var regexpAlphaNum = regexp.MustCompile("^[a-zA-Z0-9._/-@]*$")
+var regexpJSON = regexp.MustCompile(`^[a-zA-Z0-9_/ \-+"':,\n\t.{}()\[\]]*$`)
+
 type NameContext struct {
-	Tip            blockchain.TipInfo
-	StateWriter    state.ReaderWriter
-	EventPublisher event.Publisher
-	NameReg        names.ReaderWriter
-	Logger         *logging.Logger
-	tx             *payload.NameTx
+	Tip         blockchain.TipInfo
+	StateWriter state.ReaderWriter
+	NameReg     names.ReaderWriter
+	Logger      *logging.Logger
+	tx          *payload.NameTx
 }
 
-func (ctx *NameContext) Execute(txEnv *txs.Envelope) error {
+func (ctx *NameContext) Execute(txe *exec.TxExecution) error {
 	var ok bool
-	ctx.tx, ok = txEnv.Tx.Payload.(*payload.NameTx)
+	ctx.tx, ok = txe.Envelope.Tx.Payload.(*payload.NameTx)
 	if !ok {
-		return fmt.Errorf("payload must be NameTx, but is: %v", txEnv.Tx.Payload)
+		return fmt.Errorf("payload must be NameTx, but is: %v", txe.Envelope.Tx.Payload)
 	}
 	// Validate input
 	inAcc, err := state.GetMutableAccount(ctx.StateWriter, ctx.tx.Input.Address)
@@ -56,7 +61,7 @@ func (ctx *NameContext) Execute(txEnv *txs.Envelope) error {
 	}
 
 	// validate the input strings
-	if err := ctx.tx.ValidateStrings(); err != nil {
+	if err := validateStrings(ctx.tx); err != nil {
 		return err
 	}
 
@@ -74,7 +79,7 @@ func (ctx *NameContext) Execute(txEnv *txs.Envelope) error {
 		"last_block_height", lastBlockHeight)
 
 	// check if the name exists
-	entry, err := ctx.NameReg.GetNameEntry(ctx.tx.Name)
+	entry, err := ctx.NameReg.GetName(ctx.tx.Name)
 	if err != nil {
 		return err
 	}
@@ -99,7 +104,7 @@ func (ctx *NameContext) Execute(txEnv *txs.Envelope) error {
 			// (owners if not expired, anyone if expired)
 			ctx.Logger.TraceMsg("Removing NameReg entry (no value and empty data in tx requests this)",
 				"name", entry.Name)
-			err := ctx.NameReg.RemoveNameEntry(entry.Name)
+			err := ctx.NameReg.RemoveName(entry.Name)
 			if err != nil {
 				return err
 			}
@@ -134,7 +139,7 @@ func (ctx *NameContext) Execute(txEnv *txs.Envelope) error {
 					"credit", credit)
 			}
 			entry.Data = ctx.tx.Data
-			err := ctx.NameReg.UpdateNameEntry(entry)
+			err := ctx.NameReg.UpdateName(entry)
 			if err != nil {
 				return err
 			}
@@ -153,7 +158,7 @@ func (ctx *NameContext) Execute(txEnv *txs.Envelope) error {
 		ctx.Logger.TraceMsg("Creating NameReg entry",
 			"name", entry.Name,
 			"expires_in", expiresIn)
-		err := ctx.NameReg.UpdateNameEntry(entry)
+		err := ctx.NameReg.UpdateName(entry)
 		if err != nil {
 			return err
 		}
@@ -168,18 +173,51 @@ func (ctx *NameContext) Execute(txEnv *txs.Envelope) error {
 		"old_sequence", inAcc.Sequence(),
 		"new_sequence", inAcc.Sequence()+1)
 	inAcc.IncSequence()
-	inAcc, err = inAcc.SubtractFromBalance(value)
+	err = inAcc.SubtractFromBalance(value)
+	if err != nil {
+		return err
+	}
+	err = ctx.StateWriter.UpdateAccount(inAcc)
 	if err != nil {
 		return err
 	}
-	ctx.StateWriter.UpdateAccount(inAcc)
 
 	// TODO: maybe we want to take funds on error and allow txs in that don't do anythingi?
 
-	if ctx.EventPublisher != nil {
-		events.PublishAccountInput(ctx.EventPublisher, ctx.Tip.LastBlockHeight(), ctx.tx.Input.Address, txEnv.Tx, nil, nil)
-		events.PublishNameReg(ctx.EventPublisher, ctx.Tip.LastBlockHeight(), txEnv.Tx)
+	txe.Input(ctx.tx.Input.Address, nil)
+	txe.Name(entry)
+	return nil
+}
+
+func validateStrings(tx *payload.NameTx) error {
+	if len(tx.Name) == 0 {
+		return errors.ErrorCodef(errors.ErrorCodeInvalidString, "name must not be empty")
+	}
+	if len(tx.Name) > names.MaxNameLength {
+		return errors.ErrorCodef(errors.ErrorCodeInvalidString, "Name is too long. Max %d bytes", names.MaxNameLength)
+	}
+	if len(tx.Data) > names.MaxDataLength {
+		return errors.ErrorCodef(errors.ErrorCodeInvalidString, "Data is too long. Max %d bytes", names.MaxDataLength)
+	}
+
+	if !validateNameRegEntryName(tx.Name) {
+		return errors.ErrorCodef(errors.ErrorCodeInvalidString,
+			"Invalid characters found in NameTx.Name (%s). Only alphanumeric, underscores, dashes, forward slashes, and @ are allowed", tx.Name)
+	}
+
+	if !validateNameRegEntryData(tx.Data) {
+		return errors.ErrorCodef(errors.ErrorCodeInvalidString,
+			"Invalid characters found in NameTx.Data (%s). Only the kind of things found in a JSON file are allowed", tx.Data)
 	}
 
 	return nil
 }
+
+// filter strings
+func validateNameRegEntryName(name string) bool {
+	return regexpAlphaNum.Match([]byte(name))
+}
+
+func validateNameRegEntryData(data string) bool {
+	return regexpJSON.Match([]byte(data))
+}
diff --git a/execution/executors/permissions.go b/execution/executors/permissions_context.go
similarity index 72%
rename from execution/executors/permissions.go
rename to execution/executors/permissions_context.go
index 0ccc62040da5a695c1ceaaac7c59074af793e9f0..39292a3b0f8cd20c74cb1b0d78ad4c54b0f02f88 100644
--- a/execution/executors/permissions.go
+++ b/execution/executors/permissions_context.go
@@ -3,32 +3,29 @@ package executors
 import (
 	"fmt"
 
-	acm "github.com/hyperledger/burrow/account"
-	"github.com/hyperledger/burrow/account/state"
+	"github.com/hyperledger/burrow/acm"
+	"github.com/hyperledger/burrow/acm/state"
 	"github.com/hyperledger/burrow/blockchain"
 	"github.com/hyperledger/burrow/crypto"
-	"github.com/hyperledger/burrow/event"
-	"github.com/hyperledger/burrow/execution/events"
+	"github.com/hyperledger/burrow/execution/exec"
 	"github.com/hyperledger/burrow/logging"
 	"github.com/hyperledger/burrow/logging/structure"
-	ptypes "github.com/hyperledger/burrow/permission/types"
-	"github.com/hyperledger/burrow/txs"
+	"github.com/hyperledger/burrow/permission"
 	"github.com/hyperledger/burrow/txs/payload"
 )
 
 type PermissionsContext struct {
-	Tip            blockchain.TipInfo
-	StateWriter    state.ReaderWriter
-	EventPublisher event.Publisher
-	Logger         *logging.Logger
-	tx             *payload.PermissionsTx
+	Tip         blockchain.TipInfo
+	StateWriter state.ReaderWriter
+	Logger      *logging.Logger
+	tx          *payload.PermissionsTx
 }
 
-func (ctx *PermissionsContext) Execute(txEnv *txs.Envelope) error {
+func (ctx *PermissionsContext) Execute(txe *exec.TxExecution) error {
 	var ok bool
-	ctx.tx, ok = txEnv.Tx.Payload.(*payload.PermissionsTx)
+	ctx.tx, ok = txe.Envelope.Tx.Payload.(*payload.PermissionsTx)
 	if !ok {
-		return fmt.Errorf("payload must be PermissionsTx, but is: %v", txEnv.Tx.Payload)
+		return fmt.Errorf("payload must be PermissionsTx, but is: %v", txe.Envelope.Tx.Payload)
 	}
 	// Validate input
 	inAcc, err := state.GetMutableAccount(ctx.StateWriter, ctx.tx.Input.Address)
@@ -68,38 +65,38 @@ func (ctx *PermissionsContext) Execute(txEnv *txs.Envelope) error {
 
 	var permAcc acm.Account
 	switch ctx.tx.PermArgs.PermFlag {
-	case ptypes.HasBase:
+	case permission.HasBase:
 		// this one doesn't make sense from txs
 		return fmt.Errorf("HasBase is for contracts, not humans. Just look at the blockchain")
-	case ptypes.SetBase:
+	case permission.SetBase:
 		permAcc, err = mutatePermissions(ctx.StateWriter, *ctx.tx.PermArgs.Address,
-			func(perms *ptypes.AccountPermissions) error {
+			func(perms *permission.AccountPermissions) error {
 				return perms.Base.Set(*ctx.tx.PermArgs.Permission, *ctx.tx.PermArgs.Value)
 			})
-	case ptypes.UnsetBase:
+	case permission.UnsetBase:
 		permAcc, err = mutatePermissions(ctx.StateWriter, *ctx.tx.PermArgs.Address,
-			func(perms *ptypes.AccountPermissions) error {
+			func(perms *permission.AccountPermissions) error {
 				return perms.Base.Unset(*ctx.tx.PermArgs.Permission)
 			})
-	case ptypes.SetGlobal:
+	case permission.SetGlobal:
 		permAcc, err = mutatePermissions(ctx.StateWriter, acm.GlobalPermissionsAddress,
-			func(perms *ptypes.AccountPermissions) error {
+			func(perms *permission.AccountPermissions) error {
 				return perms.Base.Set(*ctx.tx.PermArgs.Permission, *ctx.tx.PermArgs.Value)
 			})
-	case ptypes.HasRole:
+	case permission.HasRole:
 		return fmt.Errorf("HasRole is for contracts, not humans. Just look at the blockchain")
-	case ptypes.AddRole:
+	case permission.AddRole:
 		permAcc, err = mutatePermissions(ctx.StateWriter, *ctx.tx.PermArgs.Address,
-			func(perms *ptypes.AccountPermissions) error {
+			func(perms *permission.AccountPermissions) error {
 				if !perms.AddRole(*ctx.tx.PermArgs.Role) {
 					return fmt.Errorf("role (%s) already exists for account %s",
 						*ctx.tx.PermArgs.Role, *ctx.tx.PermArgs.Address)
 				}
 				return nil
 			})
-	case ptypes.RemoveRole:
+	case permission.RemoveRole:
 		permAcc, err = mutatePermissions(ctx.StateWriter, *ctx.tx.PermArgs.Address,
-			func(perms *ptypes.AccountPermissions) error {
+			func(perms *permission.AccountPermissions) error {
 				if !perms.RmRole(*ctx.tx.PermArgs.Role) {
 					return fmt.Errorf("role (%s) does not exist for account %s",
 						*ctx.tx.PermArgs.Role, *ctx.tx.PermArgs.Address)
@@ -122,7 +119,7 @@ func (ctx *PermissionsContext) Execute(txEnv *txs.Envelope) error {
 		"old_sequence", inAcc.Sequence(),
 		"new_sequence", inAcc.Sequence()+1)
 	inAcc.IncSequence()
-	inAcc, err = inAcc.SubtractFromBalance(value)
+	err = inAcc.SubtractFromBalance(value)
 	if err != nil {
 		return err
 	}
@@ -131,16 +128,13 @@ func (ctx *PermissionsContext) Execute(txEnv *txs.Envelope) error {
 		ctx.StateWriter.UpdateAccount(permAcc)
 	}
 
-	if ctx.EventPublisher != nil {
-		events.PublishAccountInput(ctx.EventPublisher, ctx.Tip.LastBlockHeight(), ctx.tx.Input.Address, txEnv.Tx, nil, nil)
-		events.PublishPermissions(ctx.EventPublisher, ctx.Tip.LastBlockHeight(), txEnv.Tx)
-	}
-
+	txe.Input(ctx.tx.Input.Address, nil)
+	txe.Permission(&ctx.tx.PermArgs)
 	return nil
 }
 
 func mutatePermissions(stateReader state.Reader, address crypto.Address,
-	mutator func(*ptypes.AccountPermissions) error) (acm.Account, error) {
+	mutator func(*permission.AccountPermissions) error) (acm.Account, error) {
 
 	account, err := stateReader.GetAccount(address)
 	if err != nil {
diff --git a/execution/executors/send.go b/execution/executors/send_context.go
similarity index 59%
rename from execution/executors/send.go
rename to execution/executors/send_context.go
index f7e9f752b0bfbf7ea7aaac0fa97609b987a670ad..5cad86303d48049084e716abb33c803233a3c5f3 100644
--- a/execution/executors/send.go
+++ b/execution/executors/send_context.go
@@ -3,28 +3,25 @@ package executors
 import (
 	"fmt"
 
-	"github.com/hyperledger/burrow/account/state"
+	"github.com/hyperledger/burrow/acm/state"
 	"github.com/hyperledger/burrow/blockchain"
-	"github.com/hyperledger/burrow/event"
-	"github.com/hyperledger/burrow/execution/events"
+	"github.com/hyperledger/burrow/execution/exec"
 	"github.com/hyperledger/burrow/logging"
-	"github.com/hyperledger/burrow/txs"
 	"github.com/hyperledger/burrow/txs/payload"
 )
 
 type SendContext struct {
-	Tip            blockchain.TipInfo
-	StateWriter    state.ReaderWriter
-	EventPublisher event.Publisher
-	Logger         *logging.Logger
-	tx             *payload.SendTx
+	Tip         blockchain.TipInfo
+	StateWriter state.ReaderWriter
+	Logger      *logging.Logger
+	tx          *payload.SendTx
 }
 
-func (ctx *SendContext) Execute(txEnv *txs.Envelope) error {
+func (ctx *SendContext) Execute(txe *exec.TxExecution) error {
 	var ok bool
-	ctx.tx, ok = txEnv.Tx.Payload.(*payload.SendTx)
+	ctx.tx, ok = txe.Envelope.Tx.Payload.(*payload.SendTx)
 	if !ok {
-		return fmt.Errorf("payload must be NameTx, but is: %v", txEnv.Tx.Payload)
+		return fmt.Errorf("payload must be NameTx, but is: %v", txe.Envelope.Tx.Payload)
 	}
 	accounts, err := getInputs(ctx.StateWriter, ctx.tx.Inputs)
 	if err != nil {
@@ -70,14 +67,13 @@ func (ctx *SendContext) Execute(txEnv *txs.Envelope) error {
 		ctx.StateWriter.UpdateAccount(acc)
 	}
 
-	if ctx.EventPublisher != nil {
-		for _, i := range ctx.tx.Inputs {
-			events.PublishAccountInput(ctx.EventPublisher, ctx.Tip.LastBlockHeight(), i.Address, txEnv.Tx, nil, nil)
-		}
+	for _, i := range ctx.tx.Inputs {
+		txe.Input(i.Address, nil)
+	}
 
-		for _, o := range ctx.tx.Outputs {
-			events.PublishAccountOutput(ctx.EventPublisher, ctx.Tip.LastBlockHeight(), o.Address, txEnv.Tx, nil, nil)
-		}
+	for _, o := range ctx.tx.Outputs {
+		txe.Output(o.Address, nil)
 	}
+
 	return nil
 }
diff --git a/execution/executors/shared.go b/execution/executors/shared.go
index 8843249b1eaa488400db617ea18676deed2ea647..58904bb98efddc27cd0df9e2a4e3ef7cbc6e94da 100644
--- a/execution/executors/shared.go
+++ b/execution/executors/shared.go
@@ -3,13 +3,12 @@ package executors
 import (
 	"fmt"
 
-	acm "github.com/hyperledger/burrow/account"
-	"github.com/hyperledger/burrow/account/state"
+	"github.com/hyperledger/burrow/acm"
+	"github.com/hyperledger/burrow/acm/state"
 	"github.com/hyperledger/burrow/crypto"
 	"github.com/hyperledger/burrow/logging"
 	"github.com/hyperledger/burrow/logging/structure"
 	"github.com/hyperledger/burrow/permission"
-	ptypes "github.com/hyperledger/burrow/permission/types"
 	"github.com/hyperledger/burrow/txs/payload"
 )
 
@@ -18,9 +17,9 @@ import (
 // or it must be specified in the TxInput.  If redeclared,
 // the TxInput is modified and input.PublicKey() set to nil.
 func getInputs(accountGetter state.AccountGetter,
-	ins []*payload.TxInput) (map[crypto.Address]acm.MutableAccount, error) {
+	ins []*payload.TxInput) (map[crypto.Address]*acm.MutableAccount, error) {
 
-	accounts := map[crypto.Address]acm.MutableAccount{}
+	accounts := map[crypto.Address]*acm.MutableAccount{}
 	for _, in := range ins {
 		// Account shouldn't be duplicated
 		if _, ok := accounts[in.Address]; ok {
@@ -38,10 +37,10 @@ func getInputs(accountGetter state.AccountGetter,
 	return accounts, nil
 }
 
-func getOrMakeOutputs(accountGetter state.AccountGetter, accs map[crypto.Address]acm.MutableAccount,
-	outs []*payload.TxOutput, logger *logging.Logger) (map[crypto.Address]acm.MutableAccount, error) {
+func getOrMakeOutputs(accountGetter state.AccountGetter, accs map[crypto.Address]*acm.MutableAccount,
+	outs []*payload.TxOutput, logger *logging.Logger) (map[crypto.Address]*acm.MutableAccount, error) {
 	if accs == nil {
-		accs = make(map[crypto.Address]acm.MutableAccount)
+		accs = make(map[crypto.Address]*acm.MutableAccount)
 	}
 
 	// we should err if an account is being created but the inputs don't have permission
@@ -75,7 +74,7 @@ func getOrMakeOutputs(accountGetter state.AccountGetter, accs map[crypto.Address
 	return accs, nil
 }
 
-func validateInputs(accs map[crypto.Address]acm.MutableAccount, ins []*payload.TxInput) (uint64, error) {
+func validateInputs(accs map[crypto.Address]*acm.MutableAccount, ins []*payload.TxInput) (uint64, error) {
 	total := uint64(0)
 	for _, in := range ins {
 		acc := accs[in.Address]
@@ -92,7 +91,7 @@ func validateInputs(accs map[crypto.Address]acm.MutableAccount, ins []*payload.T
 	return total, nil
 }
 
-func validateInput(acc acm.MutableAccount, in *payload.TxInput) error {
+func validateInput(acc *acm.MutableAccount, in *payload.TxInput) error {
 	// Check TxInput basic
 	if err := in.ValidateBasic(); err != nil {
 		return err
@@ -124,7 +123,7 @@ func validateOutputs(outs []*payload.TxOutput) (uint64, error) {
 	return total, nil
 }
 
-func adjustByInputs(accs map[crypto.Address]acm.MutableAccount, ins []*payload.TxInput, logger *logging.Logger) error {
+func adjustByInputs(accs map[crypto.Address]*acm.MutableAccount, ins []*payload.TxInput, logger *logging.Logger) error {
 	for _, in := range ins {
 		acc := accs[in.Address]
 		if acc == nil {
@@ -135,7 +134,7 @@ func adjustByInputs(accs map[crypto.Address]acm.MutableAccount, ins []*payload.T
 			return fmt.Errorf("adjustByInputs() expects sufficient funds but account %s only has balance %v and "+
 				"we are deducting %v", in.Address, acc.Balance(), in.Amount)
 		}
-		acc, err := acc.SubtractFromBalance(in.Amount)
+		err := acc.SubtractFromBalance(in.Amount)
 		if err != nil {
 			return err
 		}
@@ -149,14 +148,14 @@ func adjustByInputs(accs map[crypto.Address]acm.MutableAccount, ins []*payload.T
 	return nil
 }
 
-func adjustByOutputs(accs map[crypto.Address]acm.MutableAccount, outs []*payload.TxOutput) error {
+func adjustByOutputs(accs map[crypto.Address]*acm.MutableAccount, outs []*payload.TxOutput) error {
 	for _, out := range outs {
 		acc := accs[out.Address]
 		if acc == nil {
 			return fmt.Errorf("adjustByOutputs() expects account in accounts, but account %s not found",
 				out.Address)
 		}
-		_, err := acc.AddToBalance(out.Amount)
+		err := acc.AddToBalance(out.Amount)
 		if err != nil {
 			return err
 		}
@@ -167,13 +166,13 @@ func adjustByOutputs(accs map[crypto.Address]acm.MutableAccount, outs []*payload
 //---------------------------------------------------------------
 
 // Get permission on an account or fall back to global value
-func HasPermission(accountGetter state.AccountGetter, acc acm.Account, perm ptypes.PermFlag, logger *logging.Logger) bool {
-	if perm > ptypes.AllPermFlags {
+func HasPermission(accountGetter state.AccountGetter, acc acm.Account, perm permission.PermFlag, logger *logging.Logger) bool {
+	if perm > permission.AllPermFlags {
 		logger.InfoMsg(
 			fmt.Sprintf("HasPermission called on invalid permission 0b%b (invalid) > 0b%b (maximum) ",
-				perm, ptypes.AllPermFlags),
+				perm, permission.AllPermFlags),
 			"invalid_permission", perm,
-			"maximum_permission", ptypes.AllPermFlags)
+			"maximum_permission", permission.AllPermFlags)
 		return false
 	}
 
@@ -197,10 +196,10 @@ func HasPermission(accountGetter state.AccountGetter, acc acm.Account, perm ptyp
 }
 
 // TODO: for debug log the failed accounts
-func hasSendPermission(accountGetter state.AccountGetter, accs map[crypto.Address]acm.MutableAccount,
+func hasSendPermission(accountGetter state.AccountGetter, accs map[crypto.Address]*acm.MutableAccount,
 	logger *logging.Logger) bool {
 	for _, acc := range accs {
-		if !HasPermission(accountGetter, acc, ptypes.Send, logger) {
+		if !HasPermission(accountGetter, acc, permission.Send, logger) {
 			return false
 		}
 	}
@@ -209,23 +208,23 @@ func hasSendPermission(accountGetter state.AccountGetter, accs map[crypto.Addres
 
 func hasNamePermission(accountGetter state.AccountGetter, acc acm.Account,
 	logger *logging.Logger) bool {
-	return HasPermission(accountGetter, acc, ptypes.Name, logger)
+	return HasPermission(accountGetter, acc, permission.Name, logger)
 }
 
 func hasCallPermission(accountGetter state.AccountGetter, acc acm.Account,
 	logger *logging.Logger) bool {
-	return HasPermission(accountGetter, acc, ptypes.Call, logger)
+	return HasPermission(accountGetter, acc, permission.Call, logger)
 }
 
 func hasCreateContractPermission(accountGetter state.AccountGetter, acc acm.Account,
 	logger *logging.Logger) bool {
-	return HasPermission(accountGetter, acc, ptypes.CreateContract, logger)
+	return HasPermission(accountGetter, acc, permission.CreateContract, logger)
 }
 
-func hasCreateAccountPermission(accountGetter state.AccountGetter, accs map[crypto.Address]acm.MutableAccount,
+func hasCreateAccountPermission(accountGetter state.AccountGetter, accs map[crypto.Address]*acm.MutableAccount,
 	logger *logging.Logger) bool {
 	for _, acc := range accs {
-		if !HasPermission(accountGetter, acc, ptypes.CreateAccount, logger) {
+		if !HasPermission(accountGetter, acc, permission.CreateAccount, logger) {
 			return false
 		}
 	}
@@ -234,14 +233,14 @@ func hasCreateAccountPermission(accountGetter state.AccountGetter, accs map[cryp
 
 func hasBondPermission(accountGetter state.AccountGetter, acc acm.Account,
 	logger *logging.Logger) bool {
-	return HasPermission(accountGetter, acc, ptypes.Bond, logger)
+	return HasPermission(accountGetter, acc, permission.Bond, logger)
 }
 
 func hasBondOrSendPermission(accountGetter state.AccountGetter, accs map[crypto.Address]acm.Account,
 	logger *logging.Logger) bool {
 	for _, acc := range accs {
-		if !HasPermission(accountGetter, acc, ptypes.Bond, logger) {
-			if !HasPermission(accountGetter, acc, ptypes.Send, logger) {
+		if !HasPermission(accountGetter, acc, permission.Bond, logger) {
+			if !HasPermission(accountGetter, acc, permission.Send, logger) {
 				return false
 			}
 		}
diff --git a/execution/names/cache.go b/execution/names/cache.go
index 7b8e060f1fa1ebe1b4095ad77c6c928598d2ef2a..6513f702ecb0eeb26c8ec80332c01116d3b66134 100644
--- a/execution/names/cache.go
+++ b/execution/names/cache.go
@@ -46,7 +46,7 @@ func NewCache(backend Reader) *Cache {
 	}
 }
 
-func (cache *Cache) GetNameEntry(name string) (*Entry, error) {
+func (cache *Cache) GetName(name string) (*Entry, error) {
 	nameInfo, err := cache.get(name)
 	if err != nil {
 		return nil, err
@@ -59,7 +59,7 @@ func (cache *Cache) GetNameEntry(name string) (*Entry, error) {
 	return nameInfo.entry, nil
 }
 
-func (cache *Cache) UpdateNameEntry(entry *Entry) error {
+func (cache *Cache) UpdateName(entry *Entry) error {
 	nameInfo, err := cache.get(entry.Name)
 	if err != nil {
 		return err
@@ -67,7 +67,7 @@ func (cache *Cache) UpdateNameEntry(entry *Entry) error {
 	nameInfo.Lock()
 	defer nameInfo.Unlock()
 	if nameInfo.removed {
-		return fmt.Errorf("UpdateNameEntry on a removed name: %s", nameInfo.entry.Name)
+		return fmt.Errorf("UpdateName on a removed name: %s", nameInfo.entry.Name)
 	}
 
 	nameInfo.entry = entry
@@ -75,7 +75,7 @@ func (cache *Cache) UpdateNameEntry(entry *Entry) error {
 	return nil
 }
 
-func (cache *Cache) RemoveNameEntry(name string) error {
+func (cache *Cache) RemoveName(name string) error {
 	nameInfo, err := cache.get(name)
 	if err != nil {
 		return err
@@ -83,7 +83,7 @@ func (cache *Cache) RemoveNameEntry(name string) error {
 	nameInfo.Lock()
 	defer nameInfo.Unlock()
 	if nameInfo.removed {
-		return fmt.Errorf("RemoveNameEntry on removed name: %s", name)
+		return fmt.Errorf("RemoveName on removed name: %s", name)
 	}
 	nameInfo.removed = true
 	return nil
@@ -107,13 +107,13 @@ func (cache *Cache) Sync(state Writer) error {
 		nameInfo := cache.names[name]
 		nameInfo.RLock()
 		if nameInfo.removed {
-			err := state.RemoveNameEntry(name)
+			err := state.RemoveName(name)
 			if err != nil {
 				nameInfo.RUnlock()
 				return err
 			}
 		} else if nameInfo.updated {
-			err := state.UpdateNameEntry(nameInfo.entry)
+			err := state.UpdateName(nameInfo.entry)
 			if err != nil {
 				nameInfo.RUnlock()
 				return err
@@ -156,7 +156,7 @@ func (cache *Cache) get(name string) (*nameInfo, error) {
 		defer cache.Unlock()
 		nmeInfo = cache.names[name]
 		if nmeInfo == nil {
-			entry, err := cache.backend.GetNameEntry(name)
+			entry, err := cache.backend.GetName(name)
 			if err != nil {
 				return nil, err
 			}
diff --git a/execution/names/names.go b/execution/names/names.go
index 1732575f0351c50e94cb80c69aead84e706bfde0..81d83b1764bb872b261ffc5a0a297f90286b47ba 100644
--- a/execution/names/names.go
+++ b/execution/names/names.go
@@ -15,12 +15,15 @@
 package names
 
 import (
-	"github.com/hyperledger/burrow/crypto"
+	"fmt"
+
+	"github.com/hyperledger/burrow/event/query"
 	"github.com/tendermint/go-amino"
 )
 
-var (
-	MinNameRegistrationPeriod uint64 = 5
+var MinNameRegistrationPeriod uint64 = 5
+
+const (
 
 	// NOTE: base costs and validity checks are here so clients
 	// can use them without importing state
@@ -34,25 +37,28 @@ var (
 	MaxDataLength = 1 << 16
 )
 
-// NameReg provides a global key value store based on Name, Data pairs that are subject to expiry and ownership by an
-// account.
-type Entry struct {
-	// registered name for the entry
-	Name string
-	// address that created the entry
-	Owner crypto.Address
-	// data to store under this name
-	Data string
-	// block at which this entry expires
-	Expires uint64
-}
-
 var cdc = amino.NewCodec()
 
 func (e *Entry) Encode() ([]byte, error) {
 	return cdc.MarshalBinary(e)
 }
 
+func (e *Entry) String() string {
+	return fmt.Sprintf("NameEntry{%v -> %v; Expires: %v, Owner: %v}", e.Name, e.Data, e.Expires, e.Owner)
+}
+
+type TaggedEntry struct {
+	*Entry
+	query.Tagged
+}
+
+func (e *Entry) Tagged() *TaggedEntry {
+	return &TaggedEntry{
+		Entry:  e,
+		Tagged: query.MustReflectTags(e),
+	}
+}
+
 func DecodeEntry(entryBytes []byte) (*Entry, error) {
 	entry := new(Entry)
 	err := cdc.UnmarshalBinary(entryBytes, entry)
@@ -63,14 +69,14 @@ func DecodeEntry(entryBytes []byte) (*Entry, error) {
 }
 
 type Reader interface {
-	GetNameEntry(name string) (*Entry, error)
+	GetName(name string) (*Entry, error)
 }
 
 type Writer interface {
 	// Updates the name entry creating it if it does not exist
-	UpdateNameEntry(entry *Entry) error
+	UpdateName(entry *Entry) error
 	// Remove the name entry
-	RemoveNameEntry(name string) error
+	RemoveName(name string) error
 }
 
 type ReaderWriter interface {
@@ -79,7 +85,7 @@ type ReaderWriter interface {
 }
 
 type Iterable interface {
-	IterateNameEntries(consumer func(*Entry) (stop bool)) (stopped bool, err error)
+	IterateNames(consumer func(*Entry) (stop bool)) (stopped bool, err error)
 }
 
 type IterableReader interface {
@@ -100,3 +106,7 @@ func NameBaseCost(name, data string) uint64 {
 func NameCostPerBlock(baseCost uint64) uint64 {
 	return NameBlockCostMultiplier * NameByteCostMultiplier * baseCost
 }
+
+func NameCostForExpiryIn(name, data string, expiresIn uint64) uint64 {
+	return NameCostPerBlock(NameBaseCost(name, data)) * expiresIn
+}
diff --git a/execution/names/names.pb.go b/execution/names/names.pb.go
new file mode 100644
index 0000000000000000000000000000000000000000..64cd40e92694559809ea9d8f0e1311a454466afa
--- /dev/null
+++ b/execution/names/names.pb.go
@@ -0,0 +1,449 @@
+// Code generated by protoc-gen-gogo. DO NOT EDIT.
+// source: names.proto
+
+/*
+	Package names is a generated protocol buffer package.
+
+	It is generated from these files:
+		names.proto
+
+	It has these top-level messages:
+		Entry
+*/
+package names
+
+import proto "github.com/gogo/protobuf/proto"
+import golang_proto "github.com/golang/protobuf/proto"
+import fmt "fmt"
+import math "math"
+import _ "github.com/gogo/protobuf/gogoproto"
+
+import github_com_hyperledger_burrow_crypto "github.com/hyperledger/burrow/crypto"
+
+import io "io"
+
+// Reference imports to suppress errors if they are not otherwise used.
+var _ = proto.Marshal
+var _ = golang_proto.Marshal
+var _ = fmt.Errorf
+var _ = math.Inf
+
+// This is a compile-time assertion to ensure that this generated file
+// is compatible with the proto package it is being compiled against.
+// A compilation error at this line likely means your copy of the
+// proto package needs to be updated.
+const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package
+
+// NameReg provides a global key value store based on Name, Data pairs that are subject to expiry and ownership by an
+// account.
+type Entry struct {
+	// registered name for the entry
+	Name string `protobuf:"bytes,1,opt,name=Name,proto3" json:"Name,omitempty"`
+	// address that created the entry
+	Owner github_com_hyperledger_burrow_crypto.Address `protobuf:"bytes,2,opt,name=Owner,proto3,customtype=github.com/hyperledger/burrow/crypto.Address" json:"Owner"`
+	// data to store under this name
+	Data string `protobuf:"bytes,3,opt,name=Data,proto3" json:"Data,omitempty"`
+	// block at which this entry expires
+	Expires uint64 `protobuf:"varint,4,opt,name=Expires,proto3" json:"Expires,omitempty"`
+}
+
+func (m *Entry) Reset()                    { *m = Entry{} }
+func (*Entry) ProtoMessage()               {}
+func (*Entry) Descriptor() ([]byte, []int) { return fileDescriptorNames, []int{0} }
+
+func (m *Entry) GetName() string {
+	if m != nil {
+		return m.Name
+	}
+	return ""
+}
+
+func (m *Entry) GetData() string {
+	if m != nil {
+		return m.Data
+	}
+	return ""
+}
+
+func (m *Entry) GetExpires() uint64 {
+	if m != nil {
+		return m.Expires
+	}
+	return 0
+}
+
+func (*Entry) XXX_MessageName() string {
+	return "names.Entry"
+}
+func init() {
+	proto.RegisterType((*Entry)(nil), "names.Entry")
+	golang_proto.RegisterType((*Entry)(nil), "names.Entry")
+}
+func (m *Entry) Marshal() (dAtA []byte, err error) {
+	size := m.Size()
+	dAtA = make([]byte, size)
+	n, err := m.MarshalTo(dAtA)
+	if err != nil {
+		return nil, err
+	}
+	return dAtA[:n], nil
+}
+
+func (m *Entry) MarshalTo(dAtA []byte) (int, error) {
+	var i int
+	_ = i
+	var l int
+	_ = l
+	if len(m.Name) > 0 {
+		dAtA[i] = 0xa
+		i++
+		i = encodeVarintNames(dAtA, i, uint64(len(m.Name)))
+		i += copy(dAtA[i:], m.Name)
+	}
+	dAtA[i] = 0x12
+	i++
+	i = encodeVarintNames(dAtA, i, uint64(m.Owner.Size()))
+	n1, err := m.Owner.MarshalTo(dAtA[i:])
+	if err != nil {
+		return 0, err
+	}
+	i += n1
+	if len(m.Data) > 0 {
+		dAtA[i] = 0x1a
+		i++
+		i = encodeVarintNames(dAtA, i, uint64(len(m.Data)))
+		i += copy(dAtA[i:], m.Data)
+	}
+	if m.Expires != 0 {
+		dAtA[i] = 0x20
+		i++
+		i = encodeVarintNames(dAtA, i, uint64(m.Expires))
+	}
+	return i, nil
+}
+
+func encodeVarintNames(dAtA []byte, offset int, v uint64) int {
+	for v >= 1<<7 {
+		dAtA[offset] = uint8(v&0x7f | 0x80)
+		v >>= 7
+		offset++
+	}
+	dAtA[offset] = uint8(v)
+	return offset + 1
+}
+func (m *Entry) Size() (n int) {
+	var l int
+	_ = l
+	l = len(m.Name)
+	if l > 0 {
+		n += 1 + l + sovNames(uint64(l))
+	}
+	l = m.Owner.Size()
+	n += 1 + l + sovNames(uint64(l))
+	l = len(m.Data)
+	if l > 0 {
+		n += 1 + l + sovNames(uint64(l))
+	}
+	if m.Expires != 0 {
+		n += 1 + sovNames(uint64(m.Expires))
+	}
+	return n
+}
+
+func sovNames(x uint64) (n int) {
+	for {
+		n++
+		x >>= 7
+		if x == 0 {
+			break
+		}
+	}
+	return n
+}
+func sozNames(x uint64) (n int) {
+	return sovNames(uint64((x << 1) ^ uint64((int64(x) >> 63))))
+}
+func (m *Entry) Unmarshal(dAtA []byte) error {
+	l := len(dAtA)
+	iNdEx := 0
+	for iNdEx < l {
+		preIndex := iNdEx
+		var wire uint64
+		for shift := uint(0); ; shift += 7 {
+			if shift >= 64 {
+				return ErrIntOverflowNames
+			}
+			if iNdEx >= l {
+				return io.ErrUnexpectedEOF
+			}
+			b := dAtA[iNdEx]
+			iNdEx++
+			wire |= (uint64(b) & 0x7F) << shift
+			if b < 0x80 {
+				break
+			}
+		}
+		fieldNum := int32(wire >> 3)
+		wireType := int(wire & 0x7)
+		if wireType == 4 {
+			return fmt.Errorf("proto: Entry: wiretype end group for non-group")
+		}
+		if fieldNum <= 0 {
+			return fmt.Errorf("proto: Entry: illegal tag %d (wire type %d)", fieldNum, wire)
+		}
+		switch fieldNum {
+		case 1:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType)
+			}
+			var stringLen uint64
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowNames
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				stringLen |= (uint64(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			intStringLen := int(stringLen)
+			if intStringLen < 0 {
+				return ErrInvalidLengthNames
+			}
+			postIndex := iNdEx + intStringLen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			m.Name = string(dAtA[iNdEx:postIndex])
+			iNdEx = postIndex
+		case 2:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Owner", wireType)
+			}
+			var byteLen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowNames
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				byteLen |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if byteLen < 0 {
+				return ErrInvalidLengthNames
+			}
+			postIndex := iNdEx + byteLen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			if err := m.Owner.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+				return err
+			}
+			iNdEx = postIndex
+		case 3:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Data", wireType)
+			}
+			var stringLen uint64
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowNames
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				stringLen |= (uint64(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			intStringLen := int(stringLen)
+			if intStringLen < 0 {
+				return ErrInvalidLengthNames
+			}
+			postIndex := iNdEx + intStringLen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			m.Data = string(dAtA[iNdEx:postIndex])
+			iNdEx = postIndex
+		case 4:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Expires", wireType)
+			}
+			m.Expires = 0
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowNames
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				m.Expires |= (uint64(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+		default:
+			iNdEx = preIndex
+			skippy, err := skipNames(dAtA[iNdEx:])
+			if err != nil {
+				return err
+			}
+			if skippy < 0 {
+				return ErrInvalidLengthNames
+			}
+			if (iNdEx + skippy) > l {
+				return io.ErrUnexpectedEOF
+			}
+			iNdEx += skippy
+		}
+	}
+
+	if iNdEx > l {
+		return io.ErrUnexpectedEOF
+	}
+	return nil
+}
+func skipNames(dAtA []byte) (n int, err error) {
+	l := len(dAtA)
+	iNdEx := 0
+	for iNdEx < l {
+		var wire uint64
+		for shift := uint(0); ; shift += 7 {
+			if shift >= 64 {
+				return 0, ErrIntOverflowNames
+			}
+			if iNdEx >= l {
+				return 0, io.ErrUnexpectedEOF
+			}
+			b := dAtA[iNdEx]
+			iNdEx++
+			wire |= (uint64(b) & 0x7F) << shift
+			if b < 0x80 {
+				break
+			}
+		}
+		wireType := int(wire & 0x7)
+		switch wireType {
+		case 0:
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return 0, ErrIntOverflowNames
+				}
+				if iNdEx >= l {
+					return 0, io.ErrUnexpectedEOF
+				}
+				iNdEx++
+				if dAtA[iNdEx-1] < 0x80 {
+					break
+				}
+			}
+			return iNdEx, nil
+		case 1:
+			iNdEx += 8
+			return iNdEx, nil
+		case 2:
+			var length int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return 0, ErrIntOverflowNames
+				}
+				if iNdEx >= l {
+					return 0, io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				length |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			iNdEx += length
+			if length < 0 {
+				return 0, ErrInvalidLengthNames
+			}
+			return iNdEx, nil
+		case 3:
+			for {
+				var innerWire uint64
+				var start int = iNdEx
+				for shift := uint(0); ; shift += 7 {
+					if shift >= 64 {
+						return 0, ErrIntOverflowNames
+					}
+					if iNdEx >= l {
+						return 0, io.ErrUnexpectedEOF
+					}
+					b := dAtA[iNdEx]
+					iNdEx++
+					innerWire |= (uint64(b) & 0x7F) << shift
+					if b < 0x80 {
+						break
+					}
+				}
+				innerWireType := int(innerWire & 0x7)
+				if innerWireType == 4 {
+					break
+				}
+				next, err := skipNames(dAtA[start:])
+				if err != nil {
+					return 0, err
+				}
+				iNdEx = start + next
+			}
+			return iNdEx, nil
+		case 4:
+			return iNdEx, nil
+		case 5:
+			iNdEx += 4
+			return iNdEx, nil
+		default:
+			return 0, fmt.Errorf("proto: illegal wireType %d", wireType)
+		}
+	}
+	panic("unreachable")
+}
+
+var (
+	ErrInvalidLengthNames = fmt.Errorf("proto: negative length found during unmarshaling")
+	ErrIntOverflowNames   = fmt.Errorf("proto: integer overflow")
+)
+
+func init() { proto.RegisterFile("names.proto", fileDescriptorNames) }
+func init() { golang_proto.RegisterFile("names.proto", fileDescriptorNames) }
+
+var fileDescriptorNames = []byte{
+	// 245 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0xce, 0x4b, 0xcc, 0x4d,
+	0x2d, 0xd6, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, 0x05, 0x73, 0xa4, 0x74, 0xd3, 0x33, 0x4b,
+	0x32, 0x4a, 0x93, 0xf4, 0x92, 0xf3, 0x73, 0xf5, 0xd3, 0xf3, 0xd3, 0xf3, 0xf5, 0xc1, 0xb2, 0x49,
+	0xa5, 0x69, 0x60, 0x1e, 0x98, 0x03, 0x66, 0x41, 0x74, 0x29, 0xcd, 0x66, 0xe4, 0x62, 0x75, 0xcd,
+	0x2b, 0x29, 0xaa, 0x14, 0x12, 0xe2, 0x62, 0xf1, 0x4b, 0xcc, 0x4d, 0x95, 0x60, 0x54, 0x60, 0xd4,
+	0xe0, 0x0c, 0x02, 0xb3, 0x85, 0xbc, 0xb8, 0x58, 0xfd, 0xcb, 0xf3, 0x52, 0x8b, 0x24, 0x98, 0x14,
+	0x18, 0x35, 0x78, 0x9c, 0x4c, 0x4e, 0xdc, 0x93, 0x67, 0xb8, 0x75, 0x4f, 0x5e, 0x07, 0xc9, 0x8e,
+	0x8c, 0xca, 0x82, 0xd4, 0xa2, 0x9c, 0xd4, 0x94, 0xf4, 0xd4, 0x22, 0xfd, 0xa4, 0xd2, 0xa2, 0xa2,
+	0xfc, 0x72, 0xfd, 0xe4, 0xa2, 0xca, 0x82, 0x92, 0x7c, 0x3d, 0xc7, 0x94, 0x94, 0xa2, 0xd4, 0xe2,
+	0xe2, 0x20, 0x88, 0x11, 0x20, 0xf3, 0x5d, 0x12, 0x4b, 0x12, 0x25, 0x98, 0x21, 0xe6, 0x83, 0xd8,
+	0x42, 0x12, 0x5c, 0xec, 0xae, 0x15, 0x05, 0x99, 0x45, 0xa9, 0xc5, 0x12, 0x2c, 0x0a, 0x8c, 0x1a,
+	0x2c, 0x41, 0x30, 0xae, 0x15, 0xcb, 0x8c, 0x05, 0xf2, 0x0c, 0x4e, 0xce, 0x27, 0x1e, 0xc9, 0x31,
+	0x5e, 0x78, 0x24, 0xc7, 0xf8, 0xe0, 0x91, 0x1c, 0xe3, 0x81, 0xc7, 0x72, 0x8c, 0x27, 0x1e, 0xcb,
+	0x31, 0x46, 0xe9, 0xe2, 0xb7, 0x3e, 0xb5, 0x22, 0x35, 0xb9, 0xb4, 0x24, 0x33, 0x3f, 0x4f, 0x1f,
+	0x1c, 0x22, 0x49, 0x6c, 0x60, 0x9f, 0x1a, 0x03, 0x02, 0x00, 0x00, 0xff, 0xff, 0x03, 0xd1, 0x42,
+	0x7f, 0x2e, 0x01, 0x00, 0x00,
+}
diff --git a/execution/names/names_test.go b/execution/names/names_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..3ee467ddc947f44827450acde24d4bb70a2f4e57
--- /dev/null
+++ b/execution/names/names_test.go
@@ -0,0 +1,39 @@
+package names
+
+import (
+	"testing"
+
+	"github.com/gogo/protobuf/proto"
+	"github.com/hyperledger/burrow/crypto"
+	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/require"
+)
+
+func TestEncodeAmino(t *testing.T) {
+	entry := &Entry{
+		Name:    "Foo",
+		Data:    "oh noes",
+		Expires: 24423432,
+		Owner:   crypto.Address{1, 2, 0, 9, 8, 8, 1, 2},
+	}
+	encoded, err := entry.Encode()
+	require.NoError(t, err)
+	entryOut, err := DecodeEntry(encoded)
+	require.NoError(t, err)
+	assert.Equal(t, entry, entryOut)
+}
+
+func TestEncodeProtobuf(t *testing.T) {
+	entry := &Entry{
+		Name:    "Foo",
+		Data:    "oh noes",
+		Expires: 24423432,
+		Owner:   crypto.Address{1, 2, 0, 9, 8, 8, 1, 2},
+	}
+	encoded, err := proto.Marshal(entry)
+	require.NoError(t, err)
+	entryOut := new(Entry)
+	err = proto.Unmarshal(encoded, entryOut)
+	require.NoError(t, err)
+	assert.Equal(t, entry, entryOut)
+}
diff --git a/execution/options.go b/execution/options.go
deleted file mode 100644
index 8b6e458b890a5ce9dd1e07e24b0806634541b77f..0000000000000000000000000000000000000000
--- a/execution/options.go
+++ /dev/null
@@ -1,11 +0,0 @@
-package execution
-
-import "github.com/hyperledger/burrow/execution/evm"
-
-type ExecutionOption func(*executor)
-
-func VMOptions(vmOptions ...func(*evm.VM)) func(*executor) {
-	return func(exe *executor) {
-		exe.vmOptions = vmOptions
-	}
-}
diff --git a/execution/pbtransactor/transactor.pb.go b/execution/pbtransactor/transactor.pb.go
deleted file mode 100644
index e5c7a89349d7c3430b3047d9c207ebbef3fd6d1c..0000000000000000000000000000000000000000
--- a/execution/pbtransactor/transactor.pb.go
+++ /dev/null
@@ -1,960 +0,0 @@
-// Code generated by protoc-gen-go. DO NOT EDIT.
-// source: github.com/hyperledger/burrow/execution/pbtransactor/transactor.proto
-
-package pbtransactor // import "github.com/hyperledger/burrow/execution/pbtransactor"
-
-import proto "github.com/golang/protobuf/proto"
-import fmt "fmt"
-import math "math"
-import pbevents "github.com/hyperledger/burrow/execution/events/pbevents"
-
-import (
-	context "golang.org/x/net/context"
-	grpc "google.golang.org/grpc"
-)
-
-// Reference imports to suppress errors if they are not otherwise used.
-var _ = proto.Marshal
-var _ = fmt.Errorf
-var _ = math.Inf
-
-// This is a compile-time assertion to ensure that this generated file
-// is compatible with the proto package it is being compiled against.
-// A compilation error at this line likely means your copy of the
-// proto package needs to be updated.
-const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
-
-// Params
-type CallParam struct {
-	From                 []byte   `protobuf:"bytes,1,opt,name=from,proto3" json:"from,omitempty"`
-	Address              []byte   `protobuf:"bytes,2,opt,name=address,proto3" json:"address,omitempty"`
-	Data                 []byte   `protobuf:"bytes,3,opt,name=data,proto3" json:"data,omitempty"`
-	XXX_NoUnkeyedLiteral struct{} `json:"-"`
-	XXX_unrecognized     []byte   `json:"-"`
-	XXX_sizecache        int32    `json:"-"`
-}
-
-func (m *CallParam) Reset()         { *m = CallParam{} }
-func (m *CallParam) String() string { return proto.CompactTextString(m) }
-func (*CallParam) ProtoMessage()    {}
-func (*CallParam) Descriptor() ([]byte, []int) {
-	return fileDescriptor_transactor_97142763aca9e238, []int{0}
-}
-func (m *CallParam) XXX_Unmarshal(b []byte) error {
-	return xxx_messageInfo_CallParam.Unmarshal(m, b)
-}
-func (m *CallParam) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
-	return xxx_messageInfo_CallParam.Marshal(b, m, deterministic)
-}
-func (dst *CallParam) XXX_Merge(src proto.Message) {
-	xxx_messageInfo_CallParam.Merge(dst, src)
-}
-func (m *CallParam) XXX_Size() int {
-	return xxx_messageInfo_CallParam.Size(m)
-}
-func (m *CallParam) XXX_DiscardUnknown() {
-	xxx_messageInfo_CallParam.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_CallParam proto.InternalMessageInfo
-
-func (m *CallParam) GetFrom() []byte {
-	if m != nil {
-		return m.From
-	}
-	return nil
-}
-
-func (m *CallParam) GetAddress() []byte {
-	if m != nil {
-		return m.Address
-	}
-	return nil
-}
-
-func (m *CallParam) GetData() []byte {
-	if m != nil {
-		return m.Data
-	}
-	return nil
-}
-
-type CallCodeParam struct {
-	From                 []byte   `protobuf:"bytes,1,opt,name=from,proto3" json:"from,omitempty"`
-	Code                 []byte   `protobuf:"bytes,2,opt,name=code,proto3" json:"code,omitempty"`
-	Data                 []byte   `protobuf:"bytes,3,opt,name=data,proto3" json:"data,omitempty"`
-	XXX_NoUnkeyedLiteral struct{} `json:"-"`
-	XXX_unrecognized     []byte   `json:"-"`
-	XXX_sizecache        int32    `json:"-"`
-}
-
-func (m *CallCodeParam) Reset()         { *m = CallCodeParam{} }
-func (m *CallCodeParam) String() string { return proto.CompactTextString(m) }
-func (*CallCodeParam) ProtoMessage()    {}
-func (*CallCodeParam) Descriptor() ([]byte, []int) {
-	return fileDescriptor_transactor_97142763aca9e238, []int{1}
-}
-func (m *CallCodeParam) XXX_Unmarshal(b []byte) error {
-	return xxx_messageInfo_CallCodeParam.Unmarshal(m, b)
-}
-func (m *CallCodeParam) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
-	return xxx_messageInfo_CallCodeParam.Marshal(b, m, deterministic)
-}
-func (dst *CallCodeParam) XXX_Merge(src proto.Message) {
-	xxx_messageInfo_CallCodeParam.Merge(dst, src)
-}
-func (m *CallCodeParam) XXX_Size() int {
-	return xxx_messageInfo_CallCodeParam.Size(m)
-}
-func (m *CallCodeParam) XXX_DiscardUnknown() {
-	xxx_messageInfo_CallCodeParam.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_CallCodeParam proto.InternalMessageInfo
-
-func (m *CallCodeParam) GetFrom() []byte {
-	if m != nil {
-		return m.From
-	}
-	return nil
-}
-
-func (m *CallCodeParam) GetCode() []byte {
-	if m != nil {
-		return m.Code
-	}
-	return nil
-}
-
-func (m *CallCodeParam) GetData() []byte {
-	if m != nil {
-		return m.Data
-	}
-	return nil
-}
-
-type TransactParam struct {
-	// The input account to sign with
-	InputAccount *InputAccount `protobuf:"bytes,1,opt,name=inputAccount,proto3" json:"inputAccount,omitempty"`
-	// The address of the contract to call, or omitted if creating a new contract
-	Address []byte `protobuf:"bytes,2,opt,name=address,proto3" json:"address,omitempty"`
-	// EVM bytecode payload to deliver
-	Data []byte `protobuf:"bytes,3,opt,name=data,proto3" json:"data,omitempty"`
-	// The maximum gas to provide to the EVM when running any code - provided in order to bound the computation time
-	GasLimit uint64 `protobuf:"varint,4,opt,name=gasLimit,proto3" json:"gasLimit,omitempty"`
-	// Value to transfer, where amount = value + fee
-	Value uint64 `protobuf:"varint,5,opt,name=value,proto3" json:"value,omitempty"`
-	// Fee to offer validators for processing transaction
-	Fee                  uint64   `protobuf:"varint,6,opt,name=fee,proto3" json:"fee,omitempty"`
-	XXX_NoUnkeyedLiteral struct{} `json:"-"`
-	XXX_unrecognized     []byte   `json:"-"`
-	XXX_sizecache        int32    `json:"-"`
-}
-
-func (m *TransactParam) Reset()         { *m = TransactParam{} }
-func (m *TransactParam) String() string { return proto.CompactTextString(m) }
-func (*TransactParam) ProtoMessage()    {}
-func (*TransactParam) Descriptor() ([]byte, []int) {
-	return fileDescriptor_transactor_97142763aca9e238, []int{2}
-}
-func (m *TransactParam) XXX_Unmarshal(b []byte) error {
-	return xxx_messageInfo_TransactParam.Unmarshal(m, b)
-}
-func (m *TransactParam) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
-	return xxx_messageInfo_TransactParam.Marshal(b, m, deterministic)
-}
-func (dst *TransactParam) XXX_Merge(src proto.Message) {
-	xxx_messageInfo_TransactParam.Merge(dst, src)
-}
-func (m *TransactParam) XXX_Size() int {
-	return xxx_messageInfo_TransactParam.Size(m)
-}
-func (m *TransactParam) XXX_DiscardUnknown() {
-	xxx_messageInfo_TransactParam.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_TransactParam proto.InternalMessageInfo
-
-func (m *TransactParam) GetInputAccount() *InputAccount {
-	if m != nil {
-		return m.InputAccount
-	}
-	return nil
-}
-
-func (m *TransactParam) GetAddress() []byte {
-	if m != nil {
-		return m.Address
-	}
-	return nil
-}
-
-func (m *TransactParam) GetData() []byte {
-	if m != nil {
-		return m.Data
-	}
-	return nil
-}
-
-func (m *TransactParam) GetGasLimit() uint64 {
-	if m != nil {
-		return m.GasLimit
-	}
-	return 0
-}
-
-func (m *TransactParam) GetValue() uint64 {
-	if m != nil {
-		return m.Value
-	}
-	return 0
-}
-
-func (m *TransactParam) GetFee() uint64 {
-	if m != nil {
-		return m.Fee
-	}
-	return 0
-}
-
-type SendParam struct {
-	InputAccount         *InputAccount `protobuf:"bytes,1,opt,name=inputAccount,proto3" json:"inputAccount,omitempty"`
-	ToAddress            []byte        `protobuf:"bytes,2,opt,name=toAddress,proto3" json:"toAddress,omitempty"`
-	Amount               uint64        `protobuf:"varint,3,opt,name=amount,proto3" json:"amount,omitempty"`
-	XXX_NoUnkeyedLiteral struct{}      `json:"-"`
-	XXX_unrecognized     []byte        `json:"-"`
-	XXX_sizecache        int32         `json:"-"`
-}
-
-func (m *SendParam) Reset()         { *m = SendParam{} }
-func (m *SendParam) String() string { return proto.CompactTextString(m) }
-func (*SendParam) ProtoMessage()    {}
-func (*SendParam) Descriptor() ([]byte, []int) {
-	return fileDescriptor_transactor_97142763aca9e238, []int{3}
-}
-func (m *SendParam) XXX_Unmarshal(b []byte) error {
-	return xxx_messageInfo_SendParam.Unmarshal(m, b)
-}
-func (m *SendParam) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
-	return xxx_messageInfo_SendParam.Marshal(b, m, deterministic)
-}
-func (dst *SendParam) XXX_Merge(src proto.Message) {
-	xxx_messageInfo_SendParam.Merge(dst, src)
-}
-func (m *SendParam) XXX_Size() int {
-	return xxx_messageInfo_SendParam.Size(m)
-}
-func (m *SendParam) XXX_DiscardUnknown() {
-	xxx_messageInfo_SendParam.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_SendParam proto.InternalMessageInfo
-
-func (m *SendParam) GetInputAccount() *InputAccount {
-	if m != nil {
-		return m.InputAccount
-	}
-	return nil
-}
-
-func (m *SendParam) GetToAddress() []byte {
-	if m != nil {
-		return m.ToAddress
-	}
-	return nil
-}
-
-func (m *SendParam) GetAmount() uint64 {
-	if m != nil {
-		return m.Amount
-	}
-	return 0
-}
-
-type TxParam struct {
-	Tx                   []byte   `protobuf:"bytes,1,opt,name=tx,proto3" json:"tx,omitempty"`
-	XXX_NoUnkeyedLiteral struct{} `json:"-"`
-	XXX_unrecognized     []byte   `json:"-"`
-	XXX_sizecache        int32    `json:"-"`
-}
-
-func (m *TxParam) Reset()         { *m = TxParam{} }
-func (m *TxParam) String() string { return proto.CompactTextString(m) }
-func (*TxParam) ProtoMessage()    {}
-func (*TxParam) Descriptor() ([]byte, []int) {
-	return fileDescriptor_transactor_97142763aca9e238, []int{4}
-}
-func (m *TxParam) XXX_Unmarshal(b []byte) error {
-	return xxx_messageInfo_TxParam.Unmarshal(m, b)
-}
-func (m *TxParam) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
-	return xxx_messageInfo_TxParam.Marshal(b, m, deterministic)
-}
-func (dst *TxParam) XXX_Merge(src proto.Message) {
-	xxx_messageInfo_TxParam.Merge(dst, src)
-}
-func (m *TxParam) XXX_Size() int {
-	return xxx_messageInfo_TxParam.Size(m)
-}
-func (m *TxParam) XXX_DiscardUnknown() {
-	xxx_messageInfo_TxParam.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_TxParam proto.InternalMessageInfo
-
-func (m *TxParam) GetTx() []byte {
-	if m != nil {
-		return m.Tx
-	}
-	return nil
-}
-
-type SignTxParam struct {
-	Tx                   []byte            `protobuf:"bytes,1,opt,name=tx,proto3" json:"tx,omitempty"`
-	PrivateAccounts      []*PrivateAccount `protobuf:"bytes,2,rep,name=privateAccounts,proto3" json:"privateAccounts,omitempty"`
-	XXX_NoUnkeyedLiteral struct{}          `json:"-"`
-	XXX_unrecognized     []byte            `json:"-"`
-	XXX_sizecache        int32             `json:"-"`
-}
-
-func (m *SignTxParam) Reset()         { *m = SignTxParam{} }
-func (m *SignTxParam) String() string { return proto.CompactTextString(m) }
-func (*SignTxParam) ProtoMessage()    {}
-func (*SignTxParam) Descriptor() ([]byte, []int) {
-	return fileDescriptor_transactor_97142763aca9e238, []int{5}
-}
-func (m *SignTxParam) XXX_Unmarshal(b []byte) error {
-	return xxx_messageInfo_SignTxParam.Unmarshal(m, b)
-}
-func (m *SignTxParam) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
-	return xxx_messageInfo_SignTxParam.Marshal(b, m, deterministic)
-}
-func (dst *SignTxParam) XXX_Merge(src proto.Message) {
-	xxx_messageInfo_SignTxParam.Merge(dst, src)
-}
-func (m *SignTxParam) XXX_Size() int {
-	return xxx_messageInfo_SignTxParam.Size(m)
-}
-func (m *SignTxParam) XXX_DiscardUnknown() {
-	xxx_messageInfo_SignTxParam.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_SignTxParam proto.InternalMessageInfo
-
-func (m *SignTxParam) GetTx() []byte {
-	if m != nil {
-		return m.Tx
-	}
-	return nil
-}
-
-func (m *SignTxParam) GetPrivateAccounts() []*PrivateAccount {
-	if m != nil {
-		return m.PrivateAccounts
-	}
-	return nil
-}
-
-// Results
-type SignedTx struct {
-	Tx                   []byte   `protobuf:"bytes,1,opt,name=tx,proto3" json:"tx,omitempty"`
-	XXX_NoUnkeyedLiteral struct{} `json:"-"`
-	XXX_unrecognized     []byte   `json:"-"`
-	XXX_sizecache        int32    `json:"-"`
-}
-
-func (m *SignedTx) Reset()         { *m = SignedTx{} }
-func (m *SignedTx) String() string { return proto.CompactTextString(m) }
-func (*SignedTx) ProtoMessage()    {}
-func (*SignedTx) Descriptor() ([]byte, []int) {
-	return fileDescriptor_transactor_97142763aca9e238, []int{6}
-}
-func (m *SignedTx) XXX_Unmarshal(b []byte) error {
-	return xxx_messageInfo_SignedTx.Unmarshal(m, b)
-}
-func (m *SignedTx) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
-	return xxx_messageInfo_SignedTx.Marshal(b, m, deterministic)
-}
-func (dst *SignedTx) XXX_Merge(src proto.Message) {
-	xxx_messageInfo_SignedTx.Merge(dst, src)
-}
-func (m *SignedTx) XXX_Size() int {
-	return xxx_messageInfo_SignedTx.Size(m)
-}
-func (m *SignedTx) XXX_DiscardUnknown() {
-	xxx_messageInfo_SignedTx.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_SignedTx proto.InternalMessageInfo
-
-func (m *SignedTx) GetTx() []byte {
-	if m != nil {
-		return m.Tx
-	}
-	return nil
-}
-
-type CallResult struct {
-	Return               []byte   `protobuf:"bytes,1,opt,name=Return,proto3" json:"Return,omitempty"`
-	GasUsed              uint64   `protobuf:"varint,2,opt,name=GasUsed,proto3" json:"GasUsed,omitempty"`
-	XXX_NoUnkeyedLiteral struct{} `json:"-"`
-	XXX_unrecognized     []byte   `json:"-"`
-	XXX_sizecache        int32    `json:"-"`
-}
-
-func (m *CallResult) Reset()         { *m = CallResult{} }
-func (m *CallResult) String() string { return proto.CompactTextString(m) }
-func (*CallResult) ProtoMessage()    {}
-func (*CallResult) Descriptor() ([]byte, []int) {
-	return fileDescriptor_transactor_97142763aca9e238, []int{7}
-}
-func (m *CallResult) XXX_Unmarshal(b []byte) error {
-	return xxx_messageInfo_CallResult.Unmarshal(m, b)
-}
-func (m *CallResult) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
-	return xxx_messageInfo_CallResult.Marshal(b, m, deterministic)
-}
-func (dst *CallResult) XXX_Merge(src proto.Message) {
-	xxx_messageInfo_CallResult.Merge(dst, src)
-}
-func (m *CallResult) XXX_Size() int {
-	return xxx_messageInfo_CallResult.Size(m)
-}
-func (m *CallResult) XXX_DiscardUnknown() {
-	xxx_messageInfo_CallResult.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_CallResult proto.InternalMessageInfo
-
-func (m *CallResult) GetReturn() []byte {
-	if m != nil {
-		return m.Return
-	}
-	return nil
-}
-
-func (m *CallResult) GetGasUsed() uint64 {
-	if m != nil {
-		return m.GasUsed
-	}
-	return 0
-}
-
-type TxReceipt struct {
-	TxHash               []byte   `protobuf:"bytes,1,opt,name=TxHash,proto3" json:"TxHash,omitempty"`
-	CreatesContract      bool     `protobuf:"varint,2,opt,name=CreatesContract,proto3" json:"CreatesContract,omitempty"`
-	ContractAddress      []byte   `protobuf:"bytes,3,opt,name=ContractAddress,proto3" json:"ContractAddress,omitempty"`
-	XXX_NoUnkeyedLiteral struct{} `json:"-"`
-	XXX_unrecognized     []byte   `json:"-"`
-	XXX_sizecache        int32    `json:"-"`
-}
-
-func (m *TxReceipt) Reset()         { *m = TxReceipt{} }
-func (m *TxReceipt) String() string { return proto.CompactTextString(m) }
-func (*TxReceipt) ProtoMessage()    {}
-func (*TxReceipt) Descriptor() ([]byte, []int) {
-	return fileDescriptor_transactor_97142763aca9e238, []int{8}
-}
-func (m *TxReceipt) XXX_Unmarshal(b []byte) error {
-	return xxx_messageInfo_TxReceipt.Unmarshal(m, b)
-}
-func (m *TxReceipt) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
-	return xxx_messageInfo_TxReceipt.Marshal(b, m, deterministic)
-}
-func (dst *TxReceipt) XXX_Merge(src proto.Message) {
-	xxx_messageInfo_TxReceipt.Merge(dst, src)
-}
-func (m *TxReceipt) XXX_Size() int {
-	return xxx_messageInfo_TxReceipt.Size(m)
-}
-func (m *TxReceipt) XXX_DiscardUnknown() {
-	xxx_messageInfo_TxReceipt.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_TxReceipt proto.InternalMessageInfo
-
-func (m *TxReceipt) GetTxHash() []byte {
-	if m != nil {
-		return m.TxHash
-	}
-	return nil
-}
-
-func (m *TxReceipt) GetCreatesContract() bool {
-	if m != nil {
-		return m.CreatesContract
-	}
-	return false
-}
-
-func (m *TxReceipt) GetContractAddress() []byte {
-	if m != nil {
-		return m.ContractAddress
-	}
-	return nil
-}
-
-type InputAccount struct {
-	PrivateKey           []byte   `protobuf:"bytes,1,opt,name=privateKey,proto3" json:"privateKey,omitempty"`
-	Address              []byte   `protobuf:"bytes,2,opt,name=address,proto3" json:"address,omitempty"`
-	XXX_NoUnkeyedLiteral struct{} `json:"-"`
-	XXX_unrecognized     []byte   `json:"-"`
-	XXX_sizecache        int32    `json:"-"`
-}
-
-func (m *InputAccount) Reset()         { *m = InputAccount{} }
-func (m *InputAccount) String() string { return proto.CompactTextString(m) }
-func (*InputAccount) ProtoMessage()    {}
-func (*InputAccount) Descriptor() ([]byte, []int) {
-	return fileDescriptor_transactor_97142763aca9e238, []int{9}
-}
-func (m *InputAccount) XXX_Unmarshal(b []byte) error {
-	return xxx_messageInfo_InputAccount.Unmarshal(m, b)
-}
-func (m *InputAccount) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
-	return xxx_messageInfo_InputAccount.Marshal(b, m, deterministic)
-}
-func (dst *InputAccount) XXX_Merge(src proto.Message) {
-	xxx_messageInfo_InputAccount.Merge(dst, src)
-}
-func (m *InputAccount) XXX_Size() int {
-	return xxx_messageInfo_InputAccount.Size(m)
-}
-func (m *InputAccount) XXX_DiscardUnknown() {
-	xxx_messageInfo_InputAccount.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_InputAccount proto.InternalMessageInfo
-
-func (m *InputAccount) GetPrivateKey() []byte {
-	if m != nil {
-		return m.PrivateKey
-	}
-	return nil
-}
-
-func (m *InputAccount) GetAddress() []byte {
-	if m != nil {
-		return m.Address
-	}
-	return nil
-}
-
-type PrivateAccount struct {
-	PrivateKey           []byte   `protobuf:"bytes,1,opt,name=PrivateKey,proto3" json:"PrivateKey,omitempty"`
-	XXX_NoUnkeyedLiteral struct{} `json:"-"`
-	XXX_unrecognized     []byte   `json:"-"`
-	XXX_sizecache        int32    `json:"-"`
-}
-
-func (m *PrivateAccount) Reset()         { *m = PrivateAccount{} }
-func (m *PrivateAccount) String() string { return proto.CompactTextString(m) }
-func (*PrivateAccount) ProtoMessage()    {}
-func (*PrivateAccount) Descriptor() ([]byte, []int) {
-	return fileDescriptor_transactor_97142763aca9e238, []int{10}
-}
-func (m *PrivateAccount) XXX_Unmarshal(b []byte) error {
-	return xxx_messageInfo_PrivateAccount.Unmarshal(m, b)
-}
-func (m *PrivateAccount) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
-	return xxx_messageInfo_PrivateAccount.Marshal(b, m, deterministic)
-}
-func (dst *PrivateAccount) XXX_Merge(src proto.Message) {
-	xxx_messageInfo_PrivateAccount.Merge(dst, src)
-}
-func (m *PrivateAccount) XXX_Size() int {
-	return xxx_messageInfo_PrivateAccount.Size(m)
-}
-func (m *PrivateAccount) XXX_DiscardUnknown() {
-	xxx_messageInfo_PrivateAccount.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_PrivateAccount proto.InternalMessageInfo
-
-func (m *PrivateAccount) GetPrivateKey() []byte {
-	if m != nil {
-		return m.PrivateKey
-	}
-	return nil
-}
-
-func init() {
-	proto.RegisterType((*CallParam)(nil), "pbtransactor.CallParam")
-	proto.RegisterType((*CallCodeParam)(nil), "pbtransactor.CallCodeParam")
-	proto.RegisterType((*TransactParam)(nil), "pbtransactor.TransactParam")
-	proto.RegisterType((*SendParam)(nil), "pbtransactor.SendParam")
-	proto.RegisterType((*TxParam)(nil), "pbtransactor.TxParam")
-	proto.RegisterType((*SignTxParam)(nil), "pbtransactor.SignTxParam")
-	proto.RegisterType((*SignedTx)(nil), "pbtransactor.SignedTx")
-	proto.RegisterType((*CallResult)(nil), "pbtransactor.CallResult")
-	proto.RegisterType((*TxReceipt)(nil), "pbtransactor.TxReceipt")
-	proto.RegisterType((*InputAccount)(nil), "pbtransactor.InputAccount")
-	proto.RegisterType((*PrivateAccount)(nil), "pbtransactor.PrivateAccount")
-}
-
-// Reference imports to suppress errors if they are not otherwise used.
-var _ context.Context
-var _ grpc.ClientConn
-
-// This is a compile-time assertion to ensure that this generated file
-// is compatible with the grpc package it is being compiled against.
-const _ = grpc.SupportPackageIsVersion4
-
-// TransactorClient is the client API for Transactor service.
-//
-// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
-type TransactorClient interface {
-	// Broadcast a signed and serialised transaction to the mempool
-	BroadcastTx(ctx context.Context, in *TxParam, opts ...grpc.CallOption) (*TxReceipt, error)
-	// Perform a 'simulated' call of a contract against the current committed EVM state without any changes been saved
-	Call(ctx context.Context, in *CallParam, opts ...grpc.CallOption) (*CallResult, error)
-	// Perform a 'simulated' execution of provided code against the current committed EVM state without any changes been saved
-	CallCode(ctx context.Context, in *CallCodeParam, opts ...grpc.CallOption) (*CallResult, error)
-	// Formulate a CallTx transaction signed server-side
-	Transact(ctx context.Context, in *TransactParam, opts ...grpc.CallOption) (*TxReceipt, error)
-	// Formulate a CallTx transaction signed server-side and wait for it to be included in a block, retrieving response
-	TransactAndHold(ctx context.Context, in *TransactParam, opts ...grpc.CallOption) (*pbevents.EventDataCall, error)
-	// Formulate a SendTx transaction signed server-side
-	Send(ctx context.Context, in *SendParam, opts ...grpc.CallOption) (*TxReceipt, error)
-	// Formulate a SendTx transaction signed server-side and wait for it to be included in a block, retrieving response
-	SendAndHold(ctx context.Context, in *SendParam, opts ...grpc.CallOption) (*TxReceipt, error)
-	// Sign a transaction server-side
-	SignTx(ctx context.Context, in *SignTxParam, opts ...grpc.CallOption) (*SignedTx, error)
-}
-
-type transactorClient struct {
-	cc *grpc.ClientConn
-}
-
-func NewTransactorClient(cc *grpc.ClientConn) TransactorClient {
-	return &transactorClient{cc}
-}
-
-func (c *transactorClient) BroadcastTx(ctx context.Context, in *TxParam, opts ...grpc.CallOption) (*TxReceipt, error) {
-	out := new(TxReceipt)
-	err := c.cc.Invoke(ctx, "/pbtransactor.Transactor/BroadcastTx", in, out, opts...)
-	if err != nil {
-		return nil, err
-	}
-	return out, nil
-}
-
-func (c *transactorClient) Call(ctx context.Context, in *CallParam, opts ...grpc.CallOption) (*CallResult, error) {
-	out := new(CallResult)
-	err := c.cc.Invoke(ctx, "/pbtransactor.Transactor/Call", in, out, opts...)
-	if err != nil {
-		return nil, err
-	}
-	return out, nil
-}
-
-func (c *transactorClient) CallCode(ctx context.Context, in *CallCodeParam, opts ...grpc.CallOption) (*CallResult, error) {
-	out := new(CallResult)
-	err := c.cc.Invoke(ctx, "/pbtransactor.Transactor/CallCode", in, out, opts...)
-	if err != nil {
-		return nil, err
-	}
-	return out, nil
-}
-
-func (c *transactorClient) Transact(ctx context.Context, in *TransactParam, opts ...grpc.CallOption) (*TxReceipt, error) {
-	out := new(TxReceipt)
-	err := c.cc.Invoke(ctx, "/pbtransactor.Transactor/Transact", in, out, opts...)
-	if err != nil {
-		return nil, err
-	}
-	return out, nil
-}
-
-func (c *transactorClient) TransactAndHold(ctx context.Context, in *TransactParam, opts ...grpc.CallOption) (*pbevents.EventDataCall, error) {
-	out := new(pbevents.EventDataCall)
-	err := c.cc.Invoke(ctx, "/pbtransactor.Transactor/TransactAndHold", in, out, opts...)
-	if err != nil {
-		return nil, err
-	}
-	return out, nil
-}
-
-func (c *transactorClient) Send(ctx context.Context, in *SendParam, opts ...grpc.CallOption) (*TxReceipt, error) {
-	out := new(TxReceipt)
-	err := c.cc.Invoke(ctx, "/pbtransactor.Transactor/Send", in, out, opts...)
-	if err != nil {
-		return nil, err
-	}
-	return out, nil
-}
-
-func (c *transactorClient) SendAndHold(ctx context.Context, in *SendParam, opts ...grpc.CallOption) (*TxReceipt, error) {
-	out := new(TxReceipt)
-	err := c.cc.Invoke(ctx, "/pbtransactor.Transactor/SendAndHold", in, out, opts...)
-	if err != nil {
-		return nil, err
-	}
-	return out, nil
-}
-
-func (c *transactorClient) SignTx(ctx context.Context, in *SignTxParam, opts ...grpc.CallOption) (*SignedTx, error) {
-	out := new(SignedTx)
-	err := c.cc.Invoke(ctx, "/pbtransactor.Transactor/SignTx", in, out, opts...)
-	if err != nil {
-		return nil, err
-	}
-	return out, nil
-}
-
-// TransactorServer is the server API for Transactor service.
-type TransactorServer interface {
-	// Broadcast a signed and serialised transaction to the mempool
-	BroadcastTx(context.Context, *TxParam) (*TxReceipt, error)
-	// Perform a 'simulated' call of a contract against the current committed EVM state without any changes been saved
-	Call(context.Context, *CallParam) (*CallResult, error)
-	// Perform a 'simulated' execution of provided code against the current committed EVM state without any changes been saved
-	CallCode(context.Context, *CallCodeParam) (*CallResult, error)
-	// Formulate a CallTx transaction signed server-side
-	Transact(context.Context, *TransactParam) (*TxReceipt, error)
-	// Formulate a CallTx transaction signed server-side and wait for it to be included in a block, retrieving response
-	TransactAndHold(context.Context, *TransactParam) (*pbevents.EventDataCall, error)
-	// Formulate a SendTx transaction signed server-side
-	Send(context.Context, *SendParam) (*TxReceipt, error)
-	// Formulate a SendTx transaction signed server-side and wait for it to be included in a block, retrieving response
-	SendAndHold(context.Context, *SendParam) (*TxReceipt, error)
-	// Sign a transaction server-side
-	SignTx(context.Context, *SignTxParam) (*SignedTx, error)
-}
-
-func RegisterTransactorServer(s *grpc.Server, srv TransactorServer) {
-	s.RegisterService(&_Transactor_serviceDesc, srv)
-}
-
-func _Transactor_BroadcastTx_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
-	in := new(TxParam)
-	if err := dec(in); err != nil {
-		return nil, err
-	}
-	if interceptor == nil {
-		return srv.(TransactorServer).BroadcastTx(ctx, in)
-	}
-	info := &grpc.UnaryServerInfo{
-		Server:     srv,
-		FullMethod: "/pbtransactor.Transactor/BroadcastTx",
-	}
-	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
-		return srv.(TransactorServer).BroadcastTx(ctx, req.(*TxParam))
-	}
-	return interceptor(ctx, in, info, handler)
-}
-
-func _Transactor_Call_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
-	in := new(CallParam)
-	if err := dec(in); err != nil {
-		return nil, err
-	}
-	if interceptor == nil {
-		return srv.(TransactorServer).Call(ctx, in)
-	}
-	info := &grpc.UnaryServerInfo{
-		Server:     srv,
-		FullMethod: "/pbtransactor.Transactor/Call",
-	}
-	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
-		return srv.(TransactorServer).Call(ctx, req.(*CallParam))
-	}
-	return interceptor(ctx, in, info, handler)
-}
-
-func _Transactor_CallCode_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
-	in := new(CallCodeParam)
-	if err := dec(in); err != nil {
-		return nil, err
-	}
-	if interceptor == nil {
-		return srv.(TransactorServer).CallCode(ctx, in)
-	}
-	info := &grpc.UnaryServerInfo{
-		Server:     srv,
-		FullMethod: "/pbtransactor.Transactor/CallCode",
-	}
-	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
-		return srv.(TransactorServer).CallCode(ctx, req.(*CallCodeParam))
-	}
-	return interceptor(ctx, in, info, handler)
-}
-
-func _Transactor_Transact_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
-	in := new(TransactParam)
-	if err := dec(in); err != nil {
-		return nil, err
-	}
-	if interceptor == nil {
-		return srv.(TransactorServer).Transact(ctx, in)
-	}
-	info := &grpc.UnaryServerInfo{
-		Server:     srv,
-		FullMethod: "/pbtransactor.Transactor/Transact",
-	}
-	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
-		return srv.(TransactorServer).Transact(ctx, req.(*TransactParam))
-	}
-	return interceptor(ctx, in, info, handler)
-}
-
-func _Transactor_TransactAndHold_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
-	in := new(TransactParam)
-	if err := dec(in); err != nil {
-		return nil, err
-	}
-	if interceptor == nil {
-		return srv.(TransactorServer).TransactAndHold(ctx, in)
-	}
-	info := &grpc.UnaryServerInfo{
-		Server:     srv,
-		FullMethod: "/pbtransactor.Transactor/TransactAndHold",
-	}
-	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
-		return srv.(TransactorServer).TransactAndHold(ctx, req.(*TransactParam))
-	}
-	return interceptor(ctx, in, info, handler)
-}
-
-func _Transactor_Send_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
-	in := new(SendParam)
-	if err := dec(in); err != nil {
-		return nil, err
-	}
-	if interceptor == nil {
-		return srv.(TransactorServer).Send(ctx, in)
-	}
-	info := &grpc.UnaryServerInfo{
-		Server:     srv,
-		FullMethod: "/pbtransactor.Transactor/Send",
-	}
-	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
-		return srv.(TransactorServer).Send(ctx, req.(*SendParam))
-	}
-	return interceptor(ctx, in, info, handler)
-}
-
-func _Transactor_SendAndHold_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
-	in := new(SendParam)
-	if err := dec(in); err != nil {
-		return nil, err
-	}
-	if interceptor == nil {
-		return srv.(TransactorServer).SendAndHold(ctx, in)
-	}
-	info := &grpc.UnaryServerInfo{
-		Server:     srv,
-		FullMethod: "/pbtransactor.Transactor/SendAndHold",
-	}
-	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
-		return srv.(TransactorServer).SendAndHold(ctx, req.(*SendParam))
-	}
-	return interceptor(ctx, in, info, handler)
-}
-
-func _Transactor_SignTx_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
-	in := new(SignTxParam)
-	if err := dec(in); err != nil {
-		return nil, err
-	}
-	if interceptor == nil {
-		return srv.(TransactorServer).SignTx(ctx, in)
-	}
-	info := &grpc.UnaryServerInfo{
-		Server:     srv,
-		FullMethod: "/pbtransactor.Transactor/SignTx",
-	}
-	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
-		return srv.(TransactorServer).SignTx(ctx, req.(*SignTxParam))
-	}
-	return interceptor(ctx, in, info, handler)
-}
-
-var _Transactor_serviceDesc = grpc.ServiceDesc{
-	ServiceName: "pbtransactor.Transactor",
-	HandlerType: (*TransactorServer)(nil),
-	Methods: []grpc.MethodDesc{
-		{
-			MethodName: "BroadcastTx",
-			Handler:    _Transactor_BroadcastTx_Handler,
-		},
-		{
-			MethodName: "Call",
-			Handler:    _Transactor_Call_Handler,
-		},
-		{
-			MethodName: "CallCode",
-			Handler:    _Transactor_CallCode_Handler,
-		},
-		{
-			MethodName: "Transact",
-			Handler:    _Transactor_Transact_Handler,
-		},
-		{
-			MethodName: "TransactAndHold",
-			Handler:    _Transactor_TransactAndHold_Handler,
-		},
-		{
-			MethodName: "Send",
-			Handler:    _Transactor_Send_Handler,
-		},
-		{
-			MethodName: "SendAndHold",
-			Handler:    _Transactor_SendAndHold_Handler,
-		},
-		{
-			MethodName: "SignTx",
-			Handler:    _Transactor_SignTx_Handler,
-		},
-	},
-	Streams:  []grpc.StreamDesc{},
-	Metadata: "github.com/hyperledger/burrow/execution/pbtransactor/transactor.proto",
-}
-
-func init() {
-	proto.RegisterFile("github.com/hyperledger/burrow/execution/pbtransactor/transactor.proto", fileDescriptor_transactor_97142763aca9e238)
-}
-
-var fileDescriptor_transactor_97142763aca9e238 = []byte{
-	// 625 bytes of a gzipped FileDescriptorProto
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x55, 0x4f, 0x6f, 0xd3, 0x30,
-	0x14, 0x57, 0xd7, 0xac, 0x6b, 0x5f, 0xbb, 0x0d, 0x59, 0x30, 0xb2, 0x30, 0xa1, 0x29, 0xa7, 0x9e,
-	0x5a, 0x34, 0x10, 0x02, 0x21, 0x06, 0x5d, 0x37, 0x36, 0x34, 0x90, 0xa6, 0x2c, 0x5c, 0xb8, 0xb9,
-	0xf1, 0x5b, 0x17, 0xa9, 0x8d, 0x23, 0xc7, 0xd9, 0xb2, 0x23, 0x77, 0xbe, 0x14, 0xdf, 0x0c, 0xd9,
-	0x71, 0xda, 0x26, 0xa5, 0xc0, 0x10, 0xa7, 0xbc, 0x3f, 0x3f, 0xff, 0xde, 0x3f, 0x3f, 0x07, 0x4e,
-	0xc6, 0xa1, 0xbc, 0x4e, 0x47, 0xbd, 0x80, 0x4f, 0xfb, 0xd7, 0x77, 0x31, 0x8a, 0x09, 0xb2, 0x31,
-	0x8a, 0xfe, 0x28, 0x15, 0x82, 0xdf, 0xf6, 0x31, 0xc3, 0x20, 0x95, 0x21, 0x8f, 0xfa, 0xf1, 0x48,
-	0x0a, 0x1a, 0x25, 0x34, 0x90, 0x5c, 0xf4, 0xe7, 0x62, 0x2f, 0x16, 0x5c, 0x72, 0xd2, 0x59, 0x74,
-	0x3b, 0xc7, 0x7f, 0x4b, 0x8a, 0x37, 0x18, 0xc9, 0xa4, 0x1f, 0x8f, 0x8c, 0x90, 0x7f, 0x72, 0x4e,
-	0xf7, 0x33, 0xb4, 0x86, 0x74, 0x32, 0xb9, 0xa0, 0x82, 0x4e, 0x09, 0x01, 0xeb, 0x4a, 0xf0, 0xa9,
-	0x5d, 0xdb, 0xaf, 0x75, 0x3b, 0x9e, 0x96, 0x89, 0x0d, 0x1b, 0x94, 0x31, 0x81, 0x49, 0x62, 0xaf,
-	0x69, 0x73, 0xa1, 0x2a, 0x34, 0xa3, 0x92, 0xda, 0xf5, 0x1c, 0xad, 0x64, 0xf7, 0x1c, 0x36, 0x15,
-	0xdd, 0x90, 0x33, 0x5c, 0x4d, 0x49, 0xc0, 0x0a, 0x38, 0x43, 0xc3, 0xa7, 0xe5, 0x5f, 0x92, 0xfd,
-	0xa8, 0xc1, 0xa6, 0x6f, 0x0a, 0xce, 0xd9, 0x0e, 0xa1, 0x13, 0x46, 0x71, 0x2a, 0x07, 0x41, 0xc0,
-	0xd3, 0x48, 0x6a, 0xd6, 0xf6, 0x81, 0xd3, 0x5b, 0x6c, 0x4c, 0xef, 0xe3, 0x02, 0xc2, 0x2b, 0xe1,
-	0xef, 0x57, 0x0c, 0x71, 0xa0, 0x39, 0xa6, 0xc9, 0xa7, 0x70, 0x1a, 0x4a, 0xdb, 0xda, 0xaf, 0x75,
-	0x2d, 0x6f, 0xa6, 0x93, 0x87, 0xb0, 0x7e, 0x43, 0x27, 0x29, 0xda, 0xeb, 0xda, 0x91, 0x2b, 0xe4,
-	0x01, 0xd4, 0xaf, 0x10, 0xed, 0x86, 0xb6, 0x29, 0xd1, 0xfd, 0x56, 0x83, 0xd6, 0x25, 0x46, 0xec,
-	0xff, 0xe4, 0xbf, 0x07, 0x2d, 0xc9, 0x07, 0xa5, 0x0a, 0xe6, 0x06, 0xb2, 0x03, 0x0d, 0x3a, 0xd5,
-	0xbc, 0x75, 0x9d, 0x80, 0xd1, 0xdc, 0x5d, 0xd8, 0xf0, 0xb3, 0x3c, 0x81, 0x2d, 0x58, 0x93, 0x99,
-	0x19, 0xc6, 0x9a, 0xcc, 0x5c, 0x84, 0xf6, 0x65, 0x38, 0x8e, 0x56, 0xb8, 0xc9, 0x07, 0xd8, 0x8e,
-	0x45, 0x78, 0x43, 0x25, 0x9a, 0x0c, 0x54, 0xd4, 0x7a, 0xb7, 0x7d, 0xb0, 0x57, 0x4e, 0xf9, 0xa2,
-	0x04, 0xf2, 0xaa, 0x87, 0x5c, 0x07, 0x9a, 0x2a, 0x0c, 0x32, 0x3f, 0x5b, 0x4a, 0xe1, 0x10, 0x40,
-	0x5d, 0x19, 0x0f, 0x93, 0x74, 0x22, 0x55, 0x0d, 0x1e, 0xca, 0x54, 0x44, 0x06, 0x61, 0x34, 0x35,
-	0xb9, 0x53, 0x9a, 0x7c, 0x49, 0x90, 0xe9, 0xba, 0x2d, 0xaf, 0x50, 0xdd, 0x5b, 0x68, 0xf9, 0x99,
-	0x87, 0x01, 0x86, 0xb1, 0x3e, 0xee, 0x67, 0x67, 0x34, 0xb9, 0x2e, 0x8e, 0xe7, 0x1a, 0xe9, 0xc2,
-	0xf6, 0x50, 0x20, 0x95, 0x98, 0x0c, 0x79, 0x24, 0x05, 0x0d, 0xa4, 0xa6, 0x69, 0x7a, 0x55, 0xb3,
-	0x46, 0x1a, 0xb9, 0x68, 0x74, 0x7e, 0x27, 0xaa, 0x66, 0xf7, 0x0c, 0x3a, 0x8b, 0xa3, 0x22, 0x4f,
-	0x01, 0x4c, 0xdd, 0xe7, 0x78, 0x67, 0xe2, 0x2f, 0x58, 0x56, 0x5f, 0x3e, 0xf7, 0x19, 0x6c, 0x95,
-	0x3b, 0xa8, 0xb8, 0x2e, 0x96, 0xb8, 0xe6, 0x96, 0x83, 0xef, 0x16, 0x80, 0x3f, 0xeb, 0x3f, 0x79,
-	0x0b, 0xed, 0x23, 0xc1, 0x29, 0x0b, 0x68, 0x22, 0xfd, 0x8c, 0x3c, 0x2a, 0x4f, 0xc7, 0x4c, 0xd7,
-	0x79, 0x5c, 0x35, 0x17, 0x5d, 0x7b, 0x0d, 0x96, 0x1a, 0x01, 0xa9, 0x00, 0x66, 0x0f, 0x83, 0x63,
-	0x2f, 0x3b, 0xcc, 0xbc, 0x06, 0xd0, 0x2c, 0x16, 0x9e, 0x3c, 0x59, 0x46, 0xcd, 0x1e, 0x82, 0xdf,
-	0x50, 0xbc, 0x87, 0x66, 0x51, 0x4a, 0x95, 0xa2, 0xb4, 0xfd, 0xab, 0xf3, 0x3f, 0x85, 0xed, 0x02,
-	0x39, 0x88, 0xd8, 0x19, 0x9f, 0xb0, 0x3f, 0x13, 0x99, 0x57, 0xf0, 0x44, 0x7d, 0x8e, 0xa9, 0xa4,
-	0xba, 0x01, 0xaf, 0xc0, 0x52, 0xcb, 0x5a, 0x6d, 0xc4, 0x6c, 0x81, 0x57, 0xa7, 0xf0, 0x0e, 0xda,
-	0x0a, 0x55, 0x84, 0xbf, 0x3f, 0xc1, 0x1b, 0x68, 0xe4, 0x9b, 0x48, 0x76, 0x2b, 0x67, 0xe7, 0xfb,
-	0xe9, 0xec, 0x2c, 0xbb, 0xd4, 0x4e, 0x1d, 0xbd, 0xfc, 0xfa, 0xe2, 0x5f, 0x7e, 0x31, 0xa3, 0x86,
-	0xfe, 0x09, 0x3c, 0xff, 0x19, 0x00, 0x00, 0xff, 0xff, 0x51, 0xbd, 0x3d, 0xf0, 0xa1, 0x06, 0x00,
-	0x00,
-}
diff --git a/execution/pbtransactor/transactor.proto b/execution/pbtransactor/transactor.proto
deleted file mode 100644
index dd058388d94e87214adcb2880ce098e8c2f0c223..0000000000000000000000000000000000000000
--- a/execution/pbtransactor/transactor.proto
+++ /dev/null
@@ -1,96 +0,0 @@
-syntax = 'proto3';
-
-package pbtransactor;
-
-option go_package = "github.com/hyperledger/burrow/execution/pbtransactor";
-
-import "github.com/hyperledger/burrow/execution/events/pbevents/events.proto";
-
-// Transaction Service Definition
-service Transactor {
-    // Broadcast a signed and serialised transaction to the mempool
-    rpc BroadcastTx (TxParam) returns (TxReceipt);
-    // Perform a 'simulated' call of a contract against the current committed EVM state without any changes been saved
-    rpc Call (CallParam) returns (CallResult);
-    // Perform a 'simulated' execution of provided code against the current committed EVM state without any changes been saved
-    rpc CallCode (CallCodeParam) returns (CallResult);
-    // Formulate a CallTx transaction signed server-side
-    rpc Transact (TransactParam) returns (TxReceipt);
-    // Formulate a CallTx transaction signed server-side and wait for it to be included in a block, retrieving response
-    rpc TransactAndHold (TransactParam) returns (pbevents.EventDataCall);
-    // Formulate a SendTx transaction signed server-side
-    rpc Send (SendParam) returns (TxReceipt);
-    // Formulate a SendTx transaction signed server-side and wait for it to be included in a block, retrieving response
-    rpc SendAndHold (SendParam) returns (TxReceipt);
-    // Sign a transaction server-side
-    rpc SignTx (SignTxParam) returns (SignedTx);
-}
-
-// Params
-message CallParam {
-    bytes from = 1;
-    bytes address = 2;
-    bytes data = 3;
-}
-
-message CallCodeParam {
-    bytes from = 1;
-    bytes code = 2;
-    bytes data = 3;
-}
-
-message TransactParam {
-    // The input account to sign with
-    InputAccount inputAccount = 1;
-    // The address of the contract to call, or omitted if creating a new contract
-    bytes address = 2;
-    // EVM bytecode payload to deliver
-    bytes data = 3;
-    // The maximum gas to provide to the EVM when running any code - provided in order to bound the computation time
-    uint64 gasLimit = 4;
-    // Value to transfer, where amount = value + fee
-    uint64 value = 5;
-    // Fee to offer validators for processing transaction
-    uint64 fee = 6;
-}
-
-message SendParam {
-    InputAccount inputAccount = 1;
-    bytes toAddress = 2;
-    uint64 amount = 3;
-}
-
-message TxParam {
-    bytes tx = 1;
-}
-
-message SignTxParam {
-    bytes tx = 1;
-    repeated PrivateAccount privateAccounts = 2;
-}
-
-// Results
-message SignedTx {
-    bytes tx = 1;
-}
-
-message CallResult {
-    bytes Return = 1;
-    uint64 GasUsed = 2;
-}
-
-message TxReceipt {
-    bytes TxHash = 1;
-    bool CreatesContract = 2;
-    bytes ContractAddress = 3;
-}
-
-message InputAccount {
-    bytes privateKey = 1;
-    bytes address = 2;
-}
-
-message PrivateAccount {
-    bytes PrivateKey = 1;
-}
-//--------------------------------------------------
\ No newline at end of file
diff --git a/execution/simulated_call.go b/execution/simulated_call.go
new file mode 100644
index 0000000000000000000000000000000000000000..fc7156a41678477afcbfcdbda062376b648e7b71
--- /dev/null
+++ b/execution/simulated_call.go
@@ -0,0 +1,75 @@
+package execution
+
+import (
+	"fmt"
+	"runtime/debug"
+
+	"github.com/hyperledger/burrow/acm"
+	"github.com/hyperledger/burrow/acm/state"
+	"github.com/hyperledger/burrow/binary"
+	"github.com/hyperledger/burrow/blockchain"
+	"github.com/hyperledger/burrow/crypto"
+	"github.com/hyperledger/burrow/execution/evm"
+	"github.com/hyperledger/burrow/execution/exec"
+	"github.com/hyperledger/burrow/execution/executors"
+	"github.com/hyperledger/burrow/logging"
+)
+
+// Run a contract's code on an isolated and unpersisted state
+// Cannot be used to create new contracts
+func CallSim(reader state.Reader, tip blockchain.TipInfo, fromAddress, address crypto.Address, data []byte,
+	logger *logging.Logger) (*exec.TxExecution, error) {
+
+	if evm.IsRegisteredNativeContract(address.Word256()) {
+		return nil, fmt.Errorf("attempt to call native contract at address "+
+			"%X, but native contracts can not be called directly. Use a deployed "+
+			"contract that calls the native function instead", address)
+	}
+	// This was being run against CheckTx cache, need to understand the reasoning
+	callee, err := state.GetMutableAccount(reader, address)
+	if err != nil {
+		return nil, err
+	}
+	if callee == nil {
+		return nil, fmt.Errorf("account %s does not exist", address)
+	}
+	return CallCodeSim(reader, tip, fromAddress, address, callee.Code(), data, logger)
+}
+
+// Run the given code on an isolated and unpersisted state
+// Cannot be used to create new contracts.
+func CallCodeSim(reader state.Reader, tip blockchain.TipInfo, fromAddress, address crypto.Address, code, data []byte,
+	logger *logging.Logger) (_ *exec.TxExecution, err error) {
+	// This was being run against CheckTx cache, need to understand the reasoning
+	caller := acm.ConcreteAccount{Address: fromAddress}.MutableAccount()
+	callee := acm.ConcreteAccount{Address: address}.MutableAccount()
+
+	txCache := state.NewCache(reader)
+
+	params := vmParams(tip)
+	vmach := evm.NewVM(params, caller.Address(), nil, logger.WithScope("CallCode"))
+
+	txe := &exec.TxExecution{}
+	vmach.SetEventSink(txe)
+	gas := params.GasLimit
+	defer func() {
+		if r := recover(); r != nil {
+			err = fmt.Errorf("panic from VM in simulated call: %v\n%s", r, debug.Stack())
+		}
+	}()
+	ret, err := vmach.Call(txCache, caller, callee, code, data, 0, &gas)
+	if err != nil {
+		return nil, err
+	}
+	txe.Return(ret, params.GasLimit-gas)
+	return txe, nil
+}
+
+func vmParams(tip blockchain.TipInfo) evm.Params {
+	return evm.Params{
+		BlockHeight: tip.LastBlockHeight(),
+		BlockHash:   binary.LeftPadWord256(tip.LastBlockHash()),
+		BlockTime:   tip.LastBlockTime().Unix(),
+		GasLimit:    executors.GasLimit,
+	}
+}
diff --git a/execution/state.go b/execution/state.go
index 8418c836fdadca65c923fd81b71010451c573e86..12460d7837b8e62c74da7a8b7314b3b99dc3db7b 100644
--- a/execution/state.go
+++ b/execution/state.go
@@ -15,22 +15,19 @@
 package execution
 
 import (
-	"context"
 	"fmt"
 	"sync"
 	"time"
 
-	acm "github.com/hyperledger/burrow/account"
-	"github.com/hyperledger/burrow/account/state"
+	"github.com/hyperledger/burrow/acm"
+	"github.com/hyperledger/burrow/acm/state"
 	"github.com/hyperledger/burrow/binary"
 	"github.com/hyperledger/burrow/crypto"
-	"github.com/hyperledger/burrow/event"
-	"github.com/hyperledger/burrow/execution/events"
+	"github.com/hyperledger/burrow/execution/exec"
 	"github.com/hyperledger/burrow/execution/names"
 	"github.com/hyperledger/burrow/genesis"
 	"github.com/hyperledger/burrow/logging"
 	"github.com/hyperledger/burrow/permission"
-	ptypes "github.com/hyperledger/burrow/permission/types"
 	"github.com/tendermint/iavl"
 	dbm "github.com/tendermint/tmlibs/db"
 )
@@ -49,13 +46,15 @@ const (
 	accountsPrefix = "a/"
 	storagePrefix  = "s/"
 	nameRegPrefix  = "n/"
-	eventPrefix    = "e/"
+	blockPrefix    = "b/"
+	txPrefix       = "t/"
 )
 
 var (
 	accountsStart, accountsEnd []byte = prefixKeyRange(accountsPrefix)
 	storageStart, storageEnd   []byte = prefixKeyRange(storagePrefix)
 	nameRegStart, nameRegEnd   []byte = prefixKeyRange(nameRegPrefix)
+	lastBlockHeightKey                = []byte("h")
 )
 
 // Implements account and blockchain state
@@ -66,7 +65,7 @@ var _ Updatable = &writeState{}
 type Updatable interface {
 	state.Writer
 	names.Writer
-	event.Publisher
+	AddBlock(blockExecution *exec.BlockExecution) error
 }
 
 // Wraps state to give access to writer methods
@@ -86,8 +85,6 @@ type State struct {
 	// Values may be reassigned (mutex protected)
 	// Previous version of IAVL tree for concurrent read-only access
 	readTree *iavl.Tree
-	// High water mark for height/index - make sure we do not overwrite events - should only increase
-	eventKeyHighWatermark events.Key
 	// Last state hash
 	hash []byte
 }
@@ -139,7 +136,7 @@ func MakeGenesisState(db dbm.DB, genesisDoc *genesis.GenesisDoc) (*State, error)
 	globalPerms = genesisDoc.GlobalPermissions
 	// XXX: make sure the set bits are all true
 	// Without it the HasPermission() functions will fail
-	globalPerms.Base.SetBit = ptypes.AllPermFlags
+	globalPerms.Base.SetBit = permission.AllPermFlags
 
 	permsAcc := &acm.ConcreteAccount{
 		Address:     acm.GlobalPermissionsAddress,
@@ -195,7 +192,10 @@ func LoadState(db dbm.DB, hash []byte) (*State, error) {
 func (s *State) Update(updater func(up Updatable) error) ([]byte, error) {
 	s.Lock()
 	defer s.Unlock()
-	updater(s.writeState)
+	err := updater(s.writeState)
+	if err != nil {
+		return nil, err
+	}
 	return s.writeState.save()
 }
 
@@ -244,12 +244,12 @@ func (s *State) GetAccount(address crypto.Address) (acm.Account, error) {
 
 func (ws *writeState) UpdateAccount(account acm.Account) error {
 	if account == nil {
-		return fmt.Errorf("UpdateAccount passed nil account in execution.State")
+		return fmt.Errorf("UpdateAccount passed nil account in State")
 	}
 	// TODO: find a way to implement something equivalent to this so we can set the account StorageRoot
 	//storageRoot := s.tree.SubTreeHash(prefixedKey(storagePrefix, account.Address().Bytes()))
 	// Alternatively just abandon and
-	accountWithStorageRoot := acm.AsMutableAccount(account).SetStorageRoot(nil)
+	accountWithStorageRoot := acm.AsMutableAccount(account)
 	encodedAccount, err := accountWithStorageRoot.Encode()
 	if err != nil {
 		return err
@@ -313,40 +313,68 @@ func (s *State) IterateStorage(address crypto.Address,
 // Events
 
 // Execution events
-func (ws *writeState) Publish(ctx context.Context, msg interface{}, tags event.Tags) error {
-	if exeEvent, ok := msg.(*events.Event); ok {
-		key := exeEvent.Header.Key()
-		if !key.IsSuccessorOf(ws.state.eventKeyHighWatermark) {
-			return fmt.Errorf("received event with non-increasing key compared with current high watermark %v: %v",
-				ws.state.eventKeyHighWatermark, exeEvent)
-		}
-		ws.state.eventKeyHighWatermark = key
-		if exeEvent.Tx != nil {
-			// Don't serialise the tx (for now) we should normalise and store against tx hash
-			exeEvent = exeEvent.Copy()
-			// The header still contains the tx hash
-			exeEvent.Tx.Tx = nil
-		}
-		bs, err := exeEvent.Encode()
-		if err != nil {
-			return err
-		}
-		ws.state.tree.Set(eventKey(key), bs)
+func (ws *writeState) AddBlock(be *exec.BlockExecution) error {
+	lastBlockHeight, ok := ws.lastBlockHeight()
+	if ok && be.Height != lastBlockHeight+1 {
+		return fmt.Errorf("AddBlock received block for height %v but last block height was %v",
+			be.Height, lastBlockHeight)
+	}
+	ws.setLastBlockHeight(be.Height)
+	// Index transactions so they can be retrieved by their TxHash
+	for i, txe := range be.TxExecutions {
+		ws.addTx(txe.TxHash, be.Height, uint64(i))
+	}
+	bs, err := be.Encode()
+	if err != nil {
+		return err
 	}
+	key := blockKey(be.Height)
+	ws.state.tree.Set(key, bs)
 	return nil
 }
 
-func (s *State) GetEvents(startKey, endKey events.Key, consumer func(ev *events.Event) (stop bool)) (stopped bool, err error) {
-	return s.tree.IterateRange(eventKey(startKey), eventKey(endKey), true,
+func (ws *writeState) addTx(txHash []byte, height, index uint64) {
+	ws.state.tree.Set(txKey(txHash), encodeTxRef(height, index))
+}
+
+func (s *State) GetTx(txHash []byte) (*exec.TxExecution, error) {
+	_, bs := s.readTree.Get(txKey(txHash))
+	if len(bs) == 0 {
+		return nil, nil
+	}
+	height, index, err := decodeTxRef(bs)
+	if err != nil {
+		return nil, fmt.Errorf("error decoding database reference to tx %X: %v", txHash, err)
+	}
+	be, err := s.GetBlock(height)
+	if err != nil {
+		return nil, fmt.Errorf("error getting block %v containing tx %X", height, txHash)
+	}
+	if index < uint64(len(be.TxExecutions)) {
+		return be.TxExecutions[index], nil
+	}
+	return nil, fmt.Errorf("retrieved index %v in block %v for tx %X but block only contains %v TxExecutions",
+		index, height, txHash, len(be.TxExecutions))
+}
+
+func (s *State) GetBlock(height uint64) (*exec.BlockExecution, error) {
+	_, bs := s.readTree.Get(blockKey(height))
+	if len(bs) == 0 {
+		return nil, nil
+	}
+	return exec.DecodeBlockExecution(bs)
+}
+
+func (s *State) GetBlocks(startHeight, endHeight uint64, consumer func(*exec.BlockExecution) (stop bool)) (stopped bool, err error) {
+	return s.readTree.IterateRange(blockKey(startHeight), blockKey(endHeight), true,
 		func(_, value []byte) bool {
-			var exeEvent *events.Event
-			exeEvent, err = events.DecodeEvent(value)
+			block, err := exec.DecodeBlockExecution(value)
 			if err != nil {
 				err = fmt.Errorf("error unmarshalling ExecutionEvent in GetEvents: %v", err)
 				// stop iteration on error
 				return true
 			}
-			return consumer(exeEvent)
+			return consumer(block)
 		}), err
 }
 
@@ -356,10 +384,18 @@ func (s *State) Hash() []byte {
 	return s.hash
 }
 
-func (s *State) LatestEventKey() events.Key {
-	s.RLock()
-	defer s.RUnlock()
-	return s.eventKeyHighWatermark
+func (s *writeState) lastBlockHeight() (uint64, bool) {
+	_, bs := s.state.tree.Get(lastBlockHeightKey)
+	if len(bs) == 0 {
+		return 0, false
+	}
+	return binary.GetUint64BE(bs), true
+}
+
+func (s *writeState) setLastBlockHeight(height uint64) {
+	bs := make([]byte, 8)
+	binary.PutUint64BE(bs, height)
+	s.state.tree.Set(lastBlockHeightKey, bs)
 }
 
 // Events
@@ -368,7 +404,7 @@ func (s *State) LatestEventKey() events.Key {
 
 var _ names.IterableReader = &State{}
 
-func (s *State) GetNameEntry(name string) (*names.Entry, error) {
+func (s *State) GetName(name string) (*names.Entry, error) {
 	_, entryBytes := s.readTree.Get(prefixedKey(nameRegPrefix, []byte(name)))
 	if entryBytes == nil {
 		return nil, nil
@@ -377,7 +413,7 @@ func (s *State) GetNameEntry(name string) (*names.Entry, error) {
 	return names.DecodeEntry(entryBytes)
 }
 
-func (s *State) IterateNameEntries(consumer func(*names.Entry) (stop bool)) (stopped bool, err error) {
+func (s *State) IterateNames(consumer func(*names.Entry) (stop bool)) (stopped bool, err error) {
 	return s.readTree.IterateRange(nameRegStart, nameRegEnd, true, func(key []byte, value []byte) (stop bool) {
 		var entry *names.Entry
 		entry, err = names.DecodeEntry(value)
@@ -388,7 +424,7 @@ func (s *State) IterateNameEntries(consumer func(*names.Entry) (stop bool)) (sto
 	}), err
 }
 
-func (ws *writeState) UpdateNameEntry(entry *names.Entry) error {
+func (ws *writeState) UpdateName(entry *names.Entry) error {
 	bs, err := entry.Encode()
 	if err != nil {
 		return err
@@ -397,7 +433,7 @@ func (ws *writeState) UpdateNameEntry(entry *names.Entry) error {
 	return nil
 }
 
-func (ws *writeState) RemoveNameEntry(name string) error {
+func (ws *writeState) RemoveName(name string) error {
 	ws.state.tree.Remove(prefixedKey(nameRegPrefix, []byte(name)))
 	return nil
 }
@@ -416,8 +452,32 @@ func (s *State) Copy(db dbm.DB) (*State, error) {
 	return stateCopy, nil
 }
 
-func eventKey(key events.Key) []byte {
-	return prefixedKey(eventPrefix, key)
+// Key and value helpers
+
+func encodeTxRef(height, index uint64) []byte {
+	bs := make([]byte, 16)
+	binary.PutUint64BE(bs[:8], height)
+	binary.PutUint64BE(bs[8:], index)
+	return bs
+}
+
+func decodeTxRef(bs []byte) (height, index uint64, _ error) {
+	if len(bs) != 16 {
+		return 0, 0, fmt.Errorf("tx reference must have 16 bytes but '%X' does not", bs)
+	}
+	height = binary.GetUint64BE(bs[:8])
+	index = binary.GetUint64BE(bs[8:])
+	return
+}
+
+func txKey(txHash []byte) []byte {
+	return prefixedKey(txPrefix, txHash)
+}
+
+func blockKey(height uint64) []byte {
+	bs := make([]byte, 8)
+	binary.PutUint64BE(bs, height)
+	return prefixedKey(blockPrefix, bs)
 }
 
 func prefixedKey(prefix string, suffices ...[]byte) []byte {
diff --git a/execution/state_test.go b/execution/state_test.go
index 360910ba9021aa0c719b75d8b6b150833667cc23..7a821c340c16fa4a63c2830344c491ce008bde8f 100644
--- a/execution/state_test.go
+++ b/execution/state_test.go
@@ -15,21 +15,16 @@
 package execution
 
 import (
-	"context"
 	"encoding/json"
 	"fmt"
 	"testing"
 
-	"github.com/golang/protobuf/proto"
-	acm "github.com/hyperledger/burrow/account"
+	"github.com/hyperledger/burrow/acm"
 	"github.com/hyperledger/burrow/binary"
 	"github.com/hyperledger/burrow/crypto"
-	"github.com/hyperledger/burrow/execution/events"
-	"github.com/hyperledger/burrow/execution/events/pbevents"
 	"github.com/hyperledger/burrow/execution/evm/sha3"
-	permission "github.com/hyperledger/burrow/permission/types"
-	"github.com/hyperledger/burrow/txs"
-	"github.com/hyperledger/burrow/txs/payload"
+	"github.com/hyperledger/burrow/execution/exec"
+	"github.com/hyperledger/burrow/permission"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
 	"github.com/tendermint/tmlibs/db"
@@ -50,63 +45,58 @@ func TestState_UpdateAccount(t *testing.T) {
 	assert.Equal(t, account, accountOut)
 }
 
-func TestState_Publish(t *testing.T) {
+func TestWriteState_AddBlock(t *testing.T) {
 	s := NewState(db.NewMemDB())
-	ctx := context.Background()
-	evs := []*events.Event{
-		mkEvent(100, 0),
-		mkEvent(100, 1),
-	}
+	height := uint64(100)
+	txs := uint64(5)
+	events := uint64(10)
 	_, err := s.Update(func(ws Updatable) error {
-		for _, ev := range evs {
-			require.NoError(t, ws.Publish(ctx, ev, nil))
-		}
-		return nil
+		return ws.AddBlock(mkBlock(height, txs, events))
 	})
 	require.NoError(t, err)
-	i := 0
-	_, err = s.GetEvents(events.NewKey(100, 0), events.NewKey(100, 0),
-		func(ev *events.Event) (stop bool) {
-			assert.Equal(t, evs[i], ev)
-			i++
+	_, err = s.GetBlocks(height, height+1,
+		func(be *exec.BlockExecution) (stop bool) {
+			for ti := uint64(0); ti < txs; ti++ {
+				for e := uint64(0); e < events; e++ {
+					assert.Equal(t, mkEvent(height, ti, e).Header.TxHash.String(),
+						be.TxExecutions[ti].Events[e].Header.TxHash.String())
+				}
+			}
 			return false
 		})
 	require.NoError(t, err)
 	// non-increasing events
 	_, err = s.Update(func(ws Updatable) error {
-		require.Error(t, ws.Publish(ctx, mkEvent(100, 0), nil))
-		require.Error(t, ws.Publish(ctx, mkEvent(100, 1), nil))
-		require.Error(t, ws.Publish(ctx, mkEvent(99, 1324234), nil))
-		require.NoError(t, ws.Publish(ctx, mkEvent(100, 2), nil))
-		require.NoError(t, ws.Publish(ctx, mkEvent(101, 0), nil))
 		return nil
 	})
 	require.NoError(t, err)
 }
 
-func TestProtobufEventSerialisation(t *testing.T) {
-	ev := mkEvent(112, 23)
-	pbEvent := pbevents.GetExecutionEvent(ev)
-	bs, err := proto.Marshal(pbEvent)
-	require.NoError(t, err)
-	pbEventOut := new(pbevents.ExecutionEvent)
-	require.NoError(t, proto.Unmarshal(bs, pbEventOut))
-	fmt.Println(pbEventOut)
-	assert.Equal(t, asJSON(t, pbEvent), asJSON(t, pbEventOut))
+func mkBlock(height, txs, events uint64) *exec.BlockExecution {
+	be := &exec.BlockExecution{
+		Height: height,
+	}
+	for ti := uint64(0); ti < txs; ti++ {
+		txe := &exec.TxExecution{
+			Height: height,
+		}
+		for e := uint64(0); e < events; e++ {
+			txe.Events = append(txe.Events, mkEvent(height, ti, e))
+		}
+		be.TxExecutions = append(be.TxExecutions, txe)
+	}
+	return be
 }
 
-func mkEvent(height, index uint64) *events.Event {
-	return &events.Event{
-		Header: &events.Header{
+func mkEvent(height, tx, index uint64) *exec.Event {
+	return &exec.Event{
+		Header: &exec.Header{
 			Height:  height,
 			Index:   index,
-			TxHash:  sha3.Sha3([]byte(fmt.Sprintf("txhash%v%v", height, index))),
-			EventID: fmt.Sprintf("eventID: %v%v", height, index),
-		},
-		Tx: &events.EventDataTx{
-			Tx: txs.Enclose("foo", &payload.CallTx{}).Tx,
+			TxHash:  sha3.Sha3([]byte(fmt.Sprintf("txhash%v%v%v", height, tx, index))),
+			EventID: fmt.Sprintf("eventID: %v%v%v", height, tx, index),
 		},
-		Log: &events.EventDataLog{
+		Log: &exec.LogEvent{
 			Address: crypto.Address{byte(height), byte(index)},
 			Topics:  []binary.Word256{{1, 2, 3}},
 		},
diff --git a/execution/transactor.go b/execution/transactor.go
index c4d57bba192210072240583ad4700526727236d6..3a5cbd2743f598dc1421c153df1373dc9c177354 100644
--- a/execution/transactor.go
+++ b/execution/transactor.go
@@ -15,414 +15,232 @@
 package execution
 
 import (
-	"bytes"
 	"context"
-	"encoding/json"
 	"fmt"
-	"runtime/debug"
 	"time"
 
-	acm "github.com/hyperledger/burrow/account"
-	"github.com/hyperledger/burrow/account/state"
-	"github.com/hyperledger/burrow/binary"
+	"github.com/hyperledger/burrow/acm"
 	"github.com/hyperledger/burrow/blockchain"
 	"github.com/hyperledger/burrow/consensus/tendermint/codes"
 	"github.com/hyperledger/burrow/crypto"
 	"github.com/hyperledger/burrow/event"
-	"github.com/hyperledger/burrow/execution/errors"
-	"github.com/hyperledger/burrow/execution/events"
-	"github.com/hyperledger/burrow/execution/evm"
-	"github.com/hyperledger/burrow/execution/executors"
+	"github.com/hyperledger/burrow/execution/exec"
 	"github.com/hyperledger/burrow/logging"
 	"github.com/hyperledger/burrow/logging/structure"
 	"github.com/hyperledger/burrow/txs"
-	"github.com/hyperledger/burrow/txs/payload"
 	abciTypes "github.com/tendermint/abci/types"
 	tmTypes "github.com/tendermint/tendermint/types"
 )
 
-const BlockingTimeoutSeconds = 30
-
-type Call struct {
-	Return  binary.HexBytes
-	GasUsed uint64
-}
+const (
+	BlockingTimeout     = 10 * time.Second
+	SubscribeBufferSize = 10
+)
 
-// Transactor is the controller/middleware for the v0 RPC
+// Transactor is responsible for helping to formulate, sign, and broadcast transactions to tendermint
+//
+// The BroadcastTx* methods are able to work against the mempool Accounts (pending) state rather than the
+// committed (final) Accounts state and can assign a sequence number based on all of the txs
+// seen since the last block - provided these transactions are successfully committed (via DeliverTx) then
+// subsequent transactions will have valid sequence numbers. This allows Burrow to coordinate sequencing and signing
+// for a key it holds or is provided - it is down to the key-holder to manage the mutual information between transactions
+// concurrent within a new block window.
 type Transactor struct {
-	tip              *blockchain.Tip
-	eventEmitter     event.Emitter
-	broadcastTxAsync func(tx tmTypes.Tx, cb func(*abciTypes.Response)) error
-	txEncoder        txs.Encoder
-	logger           *logging.Logger
+	Tip             blockchain.TipInfo
+	Subscribable    event.Subscribable
+	MempoolAccounts *Accounts
+	checkTxAsync    func(tx tmTypes.Tx, cb func(*abciTypes.Response)) error
+	txEncoder       txs.Encoder
+	logger          *logging.Logger
 }
 
-func NewTransactor(tip *blockchain.Tip, eventEmitter event.Emitter,
-	broadcastTxAsync func(tx tmTypes.Tx, cb func(*abciTypes.Response)) error, txEncoder txs.Encoder,
+func NewTransactor(tip blockchain.TipInfo, subscribable event.Subscribable, mempoolAccounts *Accounts,
+	checkTxAsync func(tx tmTypes.Tx, cb func(*abciTypes.Response)) error, txEncoder txs.Encoder,
 	logger *logging.Logger) *Transactor {
 
 	return &Transactor{
-		tip:              tip,
-		eventEmitter:     eventEmitter,
-		broadcastTxAsync: broadcastTxAsync,
-		txEncoder:        txEncoder,
-		logger:           logger.With(structure.ComponentKey, "Transactor"),
-	}
-}
-
-// Run a contract's code on an isolated and unpersisted state
-// Cannot be used to create new contracts
-func (trans *Transactor) Call(reader state.Reader, fromAddress, address crypto.Address,
-	data []byte) (call *Call, err error) {
-
-	if evm.IsRegisteredNativeContract(address.Word256()) {
-		return nil, fmt.Errorf("attempt to call native contract at address "+
-			"%X, but native contracts can not be called directly. Use a deployed "+
-			"contract that calls the native function instead", address)
-	}
-	// This was being run against CheckTx cache, need to understand the reasoning
-	callee, err := state.GetMutableAccount(reader, address)
-	if err != nil {
-		return nil, err
-	}
-	if callee == nil {
-		return nil, fmt.Errorf("account %s does not exist", address)
-	}
-	caller := acm.ConcreteAccount{Address: fromAddress}.MutableAccount()
-	txCache := state.NewCache(reader)
-	params := vmParams(trans.tip)
-
-	vmach := evm.NewVM(params, caller.Address(), nil, trans.logger.WithScope("Call"))
-	vmach.SetPublisher(trans.eventEmitter)
-
-	gas := params.GasLimit
-	defer func() {
-		if r := recover(); r != nil {
-			err = fmt.Errorf("panic from VM in simulated call: %v\n%s", r, debug.Stack())
-		}
-	}()
-	ret, err := vmach.Call(txCache, caller, callee, callee.Code(), data, 0, &gas)
-	if err != nil {
-		return nil, err
-	}
-	gasUsed := params.GasLimit - gas
-	return &Call{Return: ret, GasUsed: gasUsed}, nil
-}
-
-// Run the given code on an isolated and unpersisted state
-// Cannot be used to create new contracts.
-func (trans *Transactor) CallCode(reader state.Reader, fromAddress crypto.Address, code, data []byte) (*Call, error) {
-	// This was being run against CheckTx cache, need to understand the reasoning
-	callee := acm.ConcreteAccount{Address: fromAddress}.MutableAccount()
-	caller := acm.ConcreteAccount{Address: fromAddress}.MutableAccount()
-	txCache := state.NewCache(reader)
-	params := vmParams(trans.tip)
-
-	vmach := evm.NewVM(params, caller.Address(), nil, trans.logger.WithScope("CallCode"))
-	gas := params.GasLimit
-	ret, err := vmach.Call(txCache, caller, callee, code, data, 0, &gas)
-	if err != nil {
-		return nil, err
-	}
-	gasUsed := params.GasLimit - gas
-	return &Call{Return: ret, GasUsed: gasUsed}, nil
-}
-
-func (trans *Transactor) BroadcastTxAsyncRaw(txBytes []byte, callback func(res *abciTypes.Response)) error {
-	return trans.broadcastTxAsync(txBytes, callback)
-}
-
-func (trans *Transactor) BroadcastTxAsync(txEnv *txs.Envelope, callback func(res *abciTypes.Response)) error {
-	err := txEnv.Validate()
-	if err != nil {
-		return err
-	}
-	txBytes, err := trans.txEncoder.EncodeTx(txEnv)
-	if err != nil {
-		return fmt.Errorf("error encoding transaction: %v", err)
-	}
-	return trans.BroadcastTxAsyncRaw(txBytes, callback)
-}
-
-// Broadcast a transaction and waits for a response from the mempool. Transactions to BroadcastTx will block during
-// various mempool operations (managed by Tendermint) including mempool Reap, Commit, and recheckTx.
-func (trans *Transactor) BroadcastTx(txEnv *txs.Envelope) (*txs.Receipt, error) {
-	trans.logger.Trace.Log("method", "BroadcastTx",
-		"tx_hash", txEnv.Tx.Hash(),
-		"tx", txEnv.String())
-	err := txEnv.Validate()
-	if err != nil {
-		return nil, err
-	}
-	txBytes, err := trans.txEncoder.EncodeTx(txEnv)
-	if err != nil {
-		return nil, err
-	}
-	return trans.BroadcastTxRaw(txBytes)
-}
-
-func (trans *Transactor) BroadcastTxRaw(txBytes []byte) (*txs.Receipt, error) {
-	responseCh := make(chan *abciTypes.Response, 1)
-	err := trans.BroadcastTxAsyncRaw(txBytes, func(res *abciTypes.Response) {
-		responseCh <- res
-	})
-
-	if err != nil {
-		return nil, err
-	}
-	response := <-responseCh
-	checkTxResponse := response.GetCheckTx()
-	if checkTxResponse == nil {
-		return nil, fmt.Errorf("application did not return CheckTx response")
-	}
-
-	switch checkTxResponse.Code {
-	case codes.TxExecutionSuccessCode:
-		receipt := new(txs.Receipt)
-		err := json.Unmarshal(checkTxResponse.Data, receipt)
+		Tip:             tip,
+		Subscribable:    subscribable,
+		MempoolAccounts: mempoolAccounts,
+		checkTxAsync:    checkTxAsync,
+		txEncoder:       txEncoder,
+		logger:          logger.With(structure.ComponentKey, "Transactor"),
+	}
+}
+
+func (trans *Transactor) BroadcastTxSync(ctx context.Context, txEnv *txs.Envelope) (*exec.TxExecution, error) {
+	// Subscribe to TX
+	// Sign if needed - must do before we sign in order to get correct TxHash
+	if len(txEnv.Signatories) == 0 {
+		var err error
+		var unlock UnlockFunc
+		txEnv, unlock, err = trans.SignTxMempool(txEnv)
 		if err != nil {
-			return nil, fmt.Errorf("could not deserialise transaction receipt: %s", err)
+			return nil, fmt.Errorf("error signing trnasction: %v", err)
 		}
-		return receipt, nil
-	default:
-		return nil, fmt.Errorf("error returned by Tendermint in BroadcastTxSync "+
-			"ABCI code: %v, ABCI log: %v", checkTxResponse.Code, checkTxResponse.Log)
-	}
-}
-
-// Orders calls to BroadcastTx using lock (waits for response from core before releasing)
-func (trans *Transactor) Transact(sequentialSigningAccount *SequentialSigningAccount, address *crypto.Address, data []byte,
-	gasLimit, value, fee uint64) (*txs.Receipt, error) {
-
-	// Use the get the freshest sequence numbers from mempool state and hold the lock until we get a response from
-	// CheckTx
-	inputAccount, unlock, err := sequentialSigningAccount.Lock()
-	if err != nil {
-		return nil, err
-	}
-	defer unlock()
-	if binary.IsUint64SumOverflow(value, fee) {
-		return nil, fmt.Errorf("amount to transfer overflows uint64 amount = %v (value) + %v (fee)", value, fee)
-	}
-	txEnv, err := trans.formulateCallTx(inputAccount, address, data, gasLimit, value+fee, fee)
-	if err != nil {
-		return nil, err
-	}
-	return trans.BroadcastTx(txEnv)
-}
-
-func (trans *Transactor) TransactAndHold(ctx context.Context, sequentialSigningAccount *SequentialSigningAccount,
-	address *crypto.Address, data []byte, gasLimit, value, fee uint64) (*events.EventDataCall, error) {
-
-	inputAccount, unlock, err := sequentialSigningAccount.Lock()
-	if err != nil {
-		return nil, err
-	}
-	defer unlock()
-	if binary.IsUint64SumOverflow(value, fee) {
-		return nil, fmt.Errorf("amount to transfer overflows uint64 amount = %v (value) + %v (fee)", value, fee)
-	}
-	callTxEnv, err := trans.formulateCallTx(inputAccount, address, data, gasLimit, value+fee, fee)
-	if err != nil {
-		return nil, err
+		defer unlock()
 	}
 
-	expectedReceipt := callTxEnv.Tx.GenerateReceipt()
-
-	subID, err := event.GenerateSubscriptionID()
+	txHash := txEnv.Tx.Hash()
+	subID := event.GenSubID()
+	out, err := trans.Subscribable.Subscribe(ctx, subID, exec.QueryForTxExecution(txHash), SubscribeBufferSize)
 	if err != nil {
 		return nil, err
 	}
+	defer trans.Subscribable.UnsubscribeAll(context.Background(), subID)
 
-	// We want non-blocking on the first event received (but buffer the value),
-	// after which we want to block (and then discard the value - see below)
-	ch := make(chan *events.EventDataCall, 1)
-
-	err = events.SubscribeAccountCall(context.Background(), trans.eventEmitter, subID, expectedReceipt.ContractAddress,
-		expectedReceipt.TxHash, 0, ch)
+	checkTxReceipt, err := trans.CheckTxSync(txEnv)
 	if err != nil {
 		return nil, err
 	}
-	// Will clean up callback goroutine and subscription in pubsub
-	defer trans.eventEmitter.UnsubscribeAll(context.Background(), subID)
-
-	receipt, err := trans.BroadcastTx(callTxEnv)
-	if err != nil {
-		return nil, err
-	}
-	if !bytes.Equal(receipt.TxHash, expectedReceipt.TxHash) {
-		return nil, fmt.Errorf("BroadcastTx received TxHash %X but %X was expected",
-			receipt.TxHash, expectedReceipt.TxHash)
-	}
-
-	timer := time.NewTimer(BlockingTimeoutSeconds * time.Second)
+	// Wait for all responses
+	timer := time.NewTimer(BlockingTimeout)
 	defer timer.Stop()
 
+	// Get all the execution events for this Tx
 	select {
 	case <-ctx.Done():
 		return nil, ctx.Err()
 	case <-timer.C:
-		return nil, fmt.Errorf("transaction timed out TxHash: %X", expectedReceipt.TxHash)
-	case eventDataCall := <-ch:
-		if eventDataCall.Exception != nil && eventDataCall.Exception.ErrorCode() != errors.ErrorCodeExecutionReverted {
-			return nil, fmt.Errorf("error when transacting: %v", eventDataCall.Exception)
-		} else {
-			return eventDataCall, nil
-		}
+		return nil, fmt.Errorf("timed out waiting for transaction with hash %v timed out after %v",
+			checkTxReceipt.TxHash, BlockingTimeout)
+	case msg := <-out:
+		return msg.(*exec.TxExecution), nil
 	}
 }
-func (trans *Transactor) formulateCallTx(inputAccount *SigningAccount, address *crypto.Address, data []byte,
-	gasLimit, amount, fee uint64) (*txs.Envelope, error) {
-
-	txInput := &payload.TxInput{
-		Address:  inputAccount.Address(),
-		Amount:   amount,
-		Sequence: inputAccount.Sequence() + 1,
-	}
-	tx := &payload.CallTx{
-		Input:    txInput,
-		Address:  address,
-		GasLimit: gasLimit,
-		Fee:      fee,
-		Data:     data,
-	}
 
-	env := txs.Enclose(trans.tip.ChainID(), tx)
-	// Got ourselves a tx.
-	err := env.Sign(inputAccount)
-	if err != nil {
-		return nil, err
+// Broadcast a transaction without waiting for confirmation - will attempt to sign server-side and set sequence numbers
+// if no signatures are provided
+func (trans *Transactor) BroadcastTxAsync(txEnv *txs.Envelope) (*txs.Receipt, error) {
+	// Attempt to sign unless signatures provided
+	if len(txEnv.Signatories) == 0 {
+		var err error
+		var unlock UnlockFunc
+		txEnv, unlock, err = trans.SignTxMempool(txEnv)
+		if err != nil {
+			return nil, err
+		}
+		defer unlock()
 	}
-	return env, nil
+	return trans.CheckTxSync(txEnv)
 }
 
-func (trans *Transactor) Send(sequentialSigningAccount *SequentialSigningAccount, toAddress crypto.Address,
-	amount uint64) (*txs.Receipt, error) {
-
-	inputAccount, unlock, err := sequentialSigningAccount.Lock()
-	if err != nil {
-		return nil, err
+func (trans *Transactor) SignTxMempool(txEnv *txs.Envelope) (*txs.Envelope, UnlockFunc, error) {
+	inputs := txEnv.Tx.GetInputs()
+	signers := make([]acm.AddressableSigner, len(inputs))
+	unlockers := make([]UnlockFunc, len(inputs))
+	for i, input := range inputs {
+		ssa, err := trans.MempoolAccounts.SequentialSigningAccount(input.Address)
+		if err != nil {
+			return nil, nil, err
+		}
+		sa, unlock, err := ssa.Lock()
+		if err != nil {
+			return nil, nil, err
+		}
+		// Hold lock until safely in mempool - important that this is held until after CheckTxSync returns
+		unlockers[i] = unlock
+		signers[i] = sa
+		// Set sequence number consecutively from mempool
+		input.Sequence = sa.Sequence() + 1
 	}
-	defer unlock()
 
-	sendTxEnv, err := trans.formulateSendTx(inputAccount, toAddress, amount)
+	err := txEnv.Sign(signers...)
 	if err != nil {
-		return nil, err
+		return nil, nil, err
 	}
-
-	return trans.BroadcastTx(sendTxEnv)
+	return txEnv, UnlockFunc(func() {
+		for _, unlock := range unlockers {
+			defer unlock()
+		}
+	}), nil
 }
 
-func (trans *Transactor) SendAndHold(ctx context.Context, sequentialSigningAccount *SequentialSigningAccount,
-	toAddress crypto.Address, amount uint64) (*txs.Receipt, error) {
-
-	inputAccount, unlock, err := sequentialSigningAccount.Lock()
-	if err != nil {
-		return nil, err
+func (trans *Transactor) SignTx(txEnv *txs.Envelope) (*txs.Envelope, error) {
+	var err error
+	inputs := txEnv.Tx.GetInputs()
+	signers := make([]acm.AddressableSigner, len(inputs))
+	for i, input := range inputs {
+		signers[i], err = trans.MempoolAccounts.SigningAccount(input.Address)
 	}
-	defer unlock()
-
-	sendTxEnv, err := trans.formulateSendTx(inputAccount, toAddress, amount)
+	err = txEnv.Sign(signers...)
 	if err != nil {
 		return nil, err
 	}
-	expectedReceipt := sendTxEnv.Tx.GenerateReceipt()
+	return txEnv, nil
+}
 
-	subID, err := event.GenerateSubscriptionID()
+// Broadcast a transaction and waits for a response from the mempool. Transactions to BroadcastTx will block during
+// various mempool operations (managed by Tendermint) including mempool Reap, Commit, and recheckTx.
+func (trans *Transactor) CheckTxSync(txEnv *txs.Envelope) (*txs.Receipt, error) {
+	trans.logger.Trace.Log("method", "CheckTxSync",
+		"tx_hash", txEnv.Tx.Hash(),
+		"tx", txEnv.String())
+	err := txEnv.Validate()
 	if err != nil {
 		return nil, err
 	}
-
-	wc := make(chan *payload.SendTx)
-	err = events.SubscribeAccountOutputSendTx(context.Background(), trans.eventEmitter, subID, toAddress,
-		expectedReceipt.TxHash, wc)
+	txBytes, err := trans.txEncoder.EncodeTx(txEnv)
 	if err != nil {
 		return nil, err
 	}
-	defer trans.eventEmitter.UnsubscribeAll(context.Background(), subID)
+	return trans.CheckTxSyncRaw(txBytes)
+}
 
-	receipt, err := trans.BroadcastTx(sendTxEnv)
+func (trans *Transactor) CheckTxSyncRaw(txBytes []byte) (*txs.Receipt, error) {
+	responseCh := make(chan *abciTypes.Response, 1)
+	err := trans.CheckTxAsyncRaw(txBytes, func(res *abciTypes.Response) {
+		responseCh <- res
+	})
 	if err != nil {
 		return nil, err
 	}
-	if !bytes.Equal(receipt.TxHash, expectedReceipt.TxHash) {
-		return nil, fmt.Errorf("BroadcastTx received TxHash %X but %X was expected",
-			receipt.TxHash, expectedReceipt.TxHash)
-	}
-
-	timer := time.NewTimer(BlockingTimeoutSeconds * time.Second)
+	timer := time.NewTimer(BlockingTimeout)
 	defer timer.Stop()
 
 	select {
-	case <-ctx.Done():
-		return nil, ctx.Err()
 	case <-timer.C:
-		return nil, fmt.Errorf("transaction timed out TxHash: %X", expectedReceipt.TxHash)
-	case sendTx := <-wc:
-		// This is a double check - we subscribed to this tx's hash so something has gone wrong if the amounts don't match
-		if sendTx.Inputs[0].Amount == amount {
-			return expectedReceipt, nil
+		return nil, fmt.Errorf("timed out waiting for CheckTx response in CheckTxSyncRaw")
+	case response := <-responseCh:
+		checkTxResponse := response.GetCheckTx()
+		if checkTxResponse == nil {
+			return nil, fmt.Errorf("application did not return CheckTx response")
 		}
-		return nil, fmt.Errorf("received SendTx but hash doesn't seem to match what we subscribed to, "+
-			"received SendTx: %v which does not match receipt on sending: %v", sendTx, expectedReceipt)
-	}
-}
-
-func (trans *Transactor) formulateSendTx(inputAccount *SigningAccount, toAddress crypto.Address,
-	amount uint64) (*txs.Envelope, error) {
 
-	sendTx := payload.NewSendTx()
-	txInput := &payload.TxInput{
-		Address:  inputAccount.Address(),
-		Amount:   amount,
-		Sequence: inputAccount.Sequence() + 1,
-	}
-	sendTx.Inputs = append(sendTx.Inputs, txInput)
-	txOutput := &payload.TxOutput{Address: toAddress, Amount: amount}
-	sendTx.Outputs = append(sendTx.Outputs, txOutput)
-
-	env := txs.Enclose(trans.tip.ChainID(), sendTx)
-	err := env.Sign(inputAccount)
-	if err != nil {
-		return nil, err
+		switch checkTxResponse.Code {
+		case codes.TxExecutionSuccessCode:
+			receipt, err := txs.DecodeReceipt(checkTxResponse.Data)
+			if err != nil {
+				return nil, fmt.Errorf("could not deserialise transaction receipt: %s", err)
+			}
+			return receipt, nil
+		default:
+			return nil, fmt.Errorf("error returned by Tendermint in BroadcastTxSync "+
+				"ABCI code: %v, ABCI log: %v", checkTxResponse.Code, checkTxResponse.Log)
+		}
 	}
-
-	return env, nil
 }
 
-func (trans *Transactor) TransactNameReg(sequentialSigningAccount *SequentialSigningAccount, name, data string, amount,
-	fee uint64) (*txs.Receipt, error) {
+func (trans *Transactor) CheckTxAsyncRaw(txBytes []byte, callback func(res *abciTypes.Response)) error {
+	return trans.checkTxAsync(txBytes, callback)
+}
 
-	inputAccount, unlock, err := sequentialSigningAccount.Lock()
+func (trans *Transactor) CheckTxAsync(txEnv *txs.Envelope, callback func(res *abciTypes.Response)) error {
+	err := txEnv.Validate()
 	if err != nil {
-		return nil, err
+		return err
 	}
-	defer unlock()
-	// Formulate and sign
-	tx := payload.NewNameTxWithSequence(inputAccount.PublicKey(), name, data, amount, fee, inputAccount.Sequence()+1)
-	env := txs.Enclose(trans.tip.ChainID(), tx)
-	err = env.Sign(inputAccount)
+	txBytes, err := trans.txEncoder.EncodeTx(txEnv)
 	if err != nil {
-		return nil, err
+		return fmt.Errorf("error encoding transaction: %v", err)
 	}
-	return trans.BroadcastTx(env)
+	return trans.CheckTxAsyncRaw(txBytes, callback)
 }
 
-// Sign a transaction
-func (trans *Transactor) SignTx(txEnv *txs.Envelope, signingAccounts []acm.AddressableSigner) (*txs.Envelope, error) {
-	// more checks?
-	err := txEnv.Sign(signingAccounts...)
-	if err != nil {
-		return nil, err
-	}
-	return txEnv, nil
+func (trans *Transactor) CallCodeSim(fromAddress crypto.Address, code, data []byte) (*exec.TxExecution, error) {
+	return CallCodeSim(trans.MempoolAccounts, trans.Tip, fromAddress, fromAddress, code, data, trans.logger)
 }
 
-func vmParams(tip *blockchain.Tip) evm.Params {
-	return evm.Params{
-		BlockHeight: tip.LastBlockHeight(),
-		BlockHash:   binary.LeftPadWord256(tip.LastBlockHash()),
-		BlockTime:   tip.LastBlockTime().Unix(),
-		GasLimit:    executors.GasLimit,
-	}
+func (trans *Transactor) CallSim(fromAddress, address crypto.Address, data []byte) (*exec.TxExecution, error) {
+	return CallSim(trans.MempoolAccounts, trans.Tip, fromAddress, address, data, trans.logger)
 }
diff --git a/execution/transactor_test.go b/execution/transactor_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..f8c6389544d60ff422c52f4293b1a890a0e6a26d
--- /dev/null
+++ b/execution/transactor_test.go
@@ -0,0 +1,77 @@
+// Copyright 2017 Monax Industries Limited
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package execution
+
+import (
+	"context"
+	"testing"
+	"time"
+
+	"github.com/hyperledger/burrow/acm"
+	"github.com/hyperledger/burrow/acm/state"
+	"github.com/hyperledger/burrow/blockchain"
+	"github.com/hyperledger/burrow/consensus/tendermint/codes"
+	"github.com/hyperledger/burrow/crypto"
+	"github.com/hyperledger/burrow/event"
+	"github.com/hyperledger/burrow/execution/exec"
+	"github.com/hyperledger/burrow/keys/mock"
+	"github.com/hyperledger/burrow/logging"
+	"github.com/hyperledger/burrow/txs"
+	"github.com/hyperledger/burrow/txs/payload"
+	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/require"
+	abciTypes "github.com/tendermint/abci/types"
+	tmTypes "github.com/tendermint/tendermint/types"
+)
+
+func TestTransactor_BroadcastTxSync(t *testing.T) {
+	chainID := "TestChain"
+	tip := blockchain.NewTip(chainID, time.Time{}, []byte("genesis"))
+	logger := logging.NewNoopLogger()
+	evc := event.NewEmitter(logger)
+	txCodec := txs.NewAminoCodec()
+	privAccount := acm.GeneratePrivateAccountFromSecret("frogs")
+	tx := &payload.CallTx{
+		Input: &payload.TxInput{
+			Address: privAccount.Address(),
+		},
+		Address: &crypto.Address{1, 2, 3},
+	}
+	txEnv := txs.Enclose(chainID, tx)
+	err := txEnv.Sign(privAccount)
+	require.NoError(t, err)
+	height := uint64(35)
+	trans := NewTransactor(tip, evc, NewAccounts(state.NewMemoryState(), mock.NewKeyClient(privAccount), 100),
+		func(tx tmTypes.Tx, cb func(*abciTypes.Response)) error {
+			txe := exec.NewTxExecution(txEnv)
+			txe.Height = height
+			err := evc.Publish(context.Background(), txe, txe.Tagged())
+			if err != nil {
+				return err
+			}
+			bs, err := txe.Receipt.Encode()
+			if err != nil {
+				return err
+			}
+			cb(abciTypes.ToResponseCheckTx(abciTypes.ResponseCheckTx{
+				Code: codes.TxExecutionSuccessCode,
+				Data: bs,
+			}))
+			return nil
+		}, txCodec, logger)
+	txe, err := trans.BroadcastTxSync(context.Background(), txEnv)
+	require.NoError(t, err)
+	assert.Equal(t, height, txe.Height)
+}
diff --git a/genesis/deterministic_genesis.go b/genesis/deterministic_genesis.go
index ca023f2617dad40d527ec32e078b7718618f6531..6c4e6a2090209fbe60a503ab5dbc0425d3b0fe18 100644
--- a/genesis/deterministic_genesis.go
+++ b/genesis/deterministic_genesis.go
@@ -5,7 +5,7 @@ import (
 	"math/rand"
 	"time"
 
-	acm "github.com/hyperledger/burrow/account"
+	"github.com/hyperledger/burrow/acm"
 	"github.com/hyperledger/burrow/crypto"
 	"github.com/hyperledger/burrow/permission"
 )
diff --git a/genesis/genesis.go b/genesis/genesis.go
index d60564415ea851eb85cbcc7d4e0154121a848d5c..6d91fd472710b9be879090eb63f55e74cf886c17 100644
--- a/genesis/genesis.go
+++ b/genesis/genesis.go
@@ -21,10 +21,9 @@ import (
 	"sort"
 	"time"
 
-	acm "github.com/hyperledger/burrow/account"
+	"github.com/hyperledger/burrow/acm"
 	"github.com/hyperledger/burrow/crypto"
 	"github.com/hyperledger/burrow/permission"
-	ptypes "github.com/hyperledger/burrow/permission/types"
 )
 
 // How many bytes to take from the front of the GenesisDoc hash to append
@@ -45,7 +44,7 @@ type BasicAccount struct {
 type Account struct {
 	BasicAccount
 	Name        string
-	Permissions ptypes.AccountPermissions
+	Permissions permission.AccountPermissions
 }
 
 type Validator struct {
@@ -62,7 +61,7 @@ type GenesisDoc struct {
 	GenesisTime       time.Time
 	ChainName         string
 	Salt              []byte `json:",omitempty" toml:",omitempty"`
-	GlobalPermissions ptypes.AccountPermissions
+	GlobalPermissions permission.AccountPermissions
 	Accounts          []Account
 	Validators        []Validator
 }
diff --git a/genesis/genesis_test.go b/genesis/genesis_test.go
index 0c5021bb0a0b07f3ad6d10a96e003d807cbbf305..640bf18d975c07102436609a01159c79c11ec18a 100644
--- a/genesis/genesis_test.go
+++ b/genesis/genesis_test.go
@@ -5,7 +5,7 @@ import (
 	"testing"
 	"time"
 
-	acm "github.com/hyperledger/burrow/account"
+	"github.com/hyperledger/burrow/acm"
 	"github.com/hyperledger/burrow/permission"
 	"github.com/stretchr/testify/assert"
 )
diff --git a/genesis/spec/genesis_spec.go b/genesis/spec/genesis_spec.go
index 3f3aba5f387e92a26a00221ea3f9412cf9c8d42c..cb4fb76cfb3a9d8f4e1f4c30ad4b1ac29bcc4347 100644
--- a/genesis/spec/genesis_spec.go
+++ b/genesis/spec/genesis_spec.go
@@ -10,7 +10,6 @@ import (
 	"github.com/hyperledger/burrow/genesis"
 	"github.com/hyperledger/burrow/keys"
 	"github.com/hyperledger/burrow/permission"
-	ptypes "github.com/hyperledger/burrow/permission/types"
 )
 
 const DefaultAmount uint64 = 1000000
@@ -62,7 +61,7 @@ func (gs *GenesisSpec) GenesisDoc(keyClient keys.KeyClient, generateNodeKeys boo
 		if err != nil {
 			return nil, err
 		}
-		genesisDoc.GlobalPermissions = ptypes.AccountPermissions{
+		genesisDoc.GlobalPermissions = permission.AccountPermissions{
 			Base: basePerms,
 		}
 	}
diff --git a/genesis/spec/genesis_spec_test.go b/genesis/spec/genesis_spec_test.go
index 0a9aeb7af802c71f93f3fa755c9740ddd5d6a01a..98665055d9ef3c1d0b4e6ed4f13bb386c2cce92b 100644
--- a/genesis/spec/genesis_spec_test.go
+++ b/genesis/spec/genesis_spec_test.go
@@ -5,7 +5,7 @@ import (
 
 	"github.com/hyperledger/burrow/crypto"
 	"github.com/hyperledger/burrow/keys/mock"
-	permission "github.com/hyperledger/burrow/permission/types"
+	"github.com/hyperledger/burrow/permission"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
 )
diff --git a/genesis/spec/presets.go b/genesis/spec/presets.go
index 30e6c08a186cb14fb5c02e9797194568737051b0..3025d98c0f4b9e9a3f995f8aea33c91f9e77f82f 100644
--- a/genesis/spec/presets.go
+++ b/genesis/spec/presets.go
@@ -3,7 +3,7 @@ package spec
 import (
 	"sort"
 
-	permission "github.com/hyperledger/burrow/permission/types"
+	"github.com/hyperledger/burrow/permission"
 )
 
 // Files here can be used as starting points for building various 'chain types' but are otherwise
diff --git a/genesis/spec/presets_test.go b/genesis/spec/presets_test.go
index df77f9bdba93339754ef237cf503f292e1cf13c9..762e397bd3154b6368e4ae01fe5f7532632d81d5 100644
--- a/genesis/spec/presets_test.go
+++ b/genesis/spec/presets_test.go
@@ -4,7 +4,7 @@ import (
 	"testing"
 
 	"github.com/hyperledger/burrow/keys/mock"
-	permission "github.com/hyperledger/burrow/permission/types"
+	"github.com/hyperledger/burrow/permission"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
 )
diff --git a/genesis/spec/spec.pb.go b/genesis/spec/spec.pb.go
new file mode 100644
index 0000000000000000000000000000000000000000..9d568bfd4db830e6f7a3ab147d301289699a3b46
--- /dev/null
+++ b/genesis/spec/spec.pb.go
@@ -0,0 +1,662 @@
+// Code generated by protoc-gen-gogo. DO NOT EDIT.
+// source: spec.proto
+
+/*
+	Package spec is a generated protocol buffer package.
+
+	It is generated from these files:
+		spec.proto
+
+	It has these top-level messages:
+		TemplateAccount
+*/
+package spec
+
+import proto "github.com/gogo/protobuf/proto"
+import golang_proto "github.com/golang/protobuf/proto"
+import fmt "fmt"
+import math "math"
+import _ "github.com/gogo/protobuf/gogoproto"
+import crypto "github.com/hyperledger/burrow/crypto"
+
+import github_com_hyperledger_burrow_crypto "github.com/hyperledger/burrow/crypto"
+
+import io "io"
+
+// Reference imports to suppress errors if they are not otherwise used.
+var _ = proto.Marshal
+var _ = golang_proto.Marshal
+var _ = fmt.Errorf
+var _ = math.Inf
+
+// This is a compile-time assertion to ensure that this generated file
+// is compatible with the proto package it is being compiled against.
+// A compilation error at this line likely means your copy of the
+// proto package needs to be updated.
+const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package
+
+type TemplateAccount struct {
+	Name        string                                        `protobuf:"bytes,1,opt,name=Name" json:"Name"`
+	Address     *github_com_hyperledger_burrow_crypto.Address `protobuf:"bytes,2,opt,name=Address,customtype=github.com/hyperledger/burrow/crypto.Address" json:",omitempty" toml:",omitempty"`
+	NodeAddress *github_com_hyperledger_burrow_crypto.Address `protobuf:"bytes,3,opt,name=NodeAddress,customtype=github.com/hyperledger/burrow/crypto.Address" json:",omitempty" toml:",omitempty"`
+	PublicKey   *crypto.PublicKey                             `protobuf:"bytes,4,opt,name=PublicKey" json:",omitempty" toml:",omitempty"`
+	Amount      *uint64                                       `protobuf:"varint,5,opt,name=Amount" json:",omitempty" toml:",omitempty"`
+	Power       *uint64                                       `protobuf:"varint,6,opt,name=Power" json:",omitempty" toml:",omitempty"`
+	Permissions []string                                      `protobuf:"bytes,7,rep,name=Permissions" json:",omitempty" toml:",omitempty"`
+	Roles       []string                                      `protobuf:"bytes,8,rep,name=Roles" json:",omitempty" toml:",omitempty"`
+}
+
+func (m *TemplateAccount) Reset()                    { *m = TemplateAccount{} }
+func (m *TemplateAccount) String() string            { return proto.CompactTextString(m) }
+func (*TemplateAccount) ProtoMessage()               {}
+func (*TemplateAccount) Descriptor() ([]byte, []int) { return fileDescriptorSpec, []int{0} }
+
+func (m *TemplateAccount) GetName() string {
+	if m != nil {
+		return m.Name
+	}
+	return ""
+}
+
+func (m *TemplateAccount) GetPublicKey() *crypto.PublicKey {
+	if m != nil {
+		return m.PublicKey
+	}
+	return nil
+}
+
+func (m *TemplateAccount) GetAmount() uint64 {
+	if m != nil && m.Amount != nil {
+		return *m.Amount
+	}
+	return 0
+}
+
+func (m *TemplateAccount) GetPower() uint64 {
+	if m != nil && m.Power != nil {
+		return *m.Power
+	}
+	return 0
+}
+
+func (m *TemplateAccount) GetPermissions() []string {
+	if m != nil {
+		return m.Permissions
+	}
+	return nil
+}
+
+func (m *TemplateAccount) GetRoles() []string {
+	if m != nil {
+		return m.Roles
+	}
+	return nil
+}
+
+func (*TemplateAccount) XXX_MessageName() string {
+	return "spec.TemplateAccount"
+}
+func init() {
+	proto.RegisterType((*TemplateAccount)(nil), "spec.TemplateAccount")
+	golang_proto.RegisterType((*TemplateAccount)(nil), "spec.TemplateAccount")
+}
+func (m *TemplateAccount) Marshal() (dAtA []byte, err error) {
+	size := m.Size()
+	dAtA = make([]byte, size)
+	n, err := m.MarshalTo(dAtA)
+	if err != nil {
+		return nil, err
+	}
+	return dAtA[:n], nil
+}
+
+func (m *TemplateAccount) MarshalTo(dAtA []byte) (int, error) {
+	var i int
+	_ = i
+	var l int
+	_ = l
+	dAtA[i] = 0xa
+	i++
+	i = encodeVarintSpec(dAtA, i, uint64(len(m.Name)))
+	i += copy(dAtA[i:], m.Name)
+	if m.Address != nil {
+		dAtA[i] = 0x12
+		i++
+		i = encodeVarintSpec(dAtA, i, uint64(m.Address.Size()))
+		n1, err := m.Address.MarshalTo(dAtA[i:])
+		if err != nil {
+			return 0, err
+		}
+		i += n1
+	}
+	if m.NodeAddress != nil {
+		dAtA[i] = 0x1a
+		i++
+		i = encodeVarintSpec(dAtA, i, uint64(m.NodeAddress.Size()))
+		n2, err := m.NodeAddress.MarshalTo(dAtA[i:])
+		if err != nil {
+			return 0, err
+		}
+		i += n2
+	}
+	if m.PublicKey != nil {
+		dAtA[i] = 0x22
+		i++
+		i = encodeVarintSpec(dAtA, i, uint64(m.PublicKey.Size()))
+		n3, err := m.PublicKey.MarshalTo(dAtA[i:])
+		if err != nil {
+			return 0, err
+		}
+		i += n3
+	}
+	if m.Amount != nil {
+		dAtA[i] = 0x28
+		i++
+		i = encodeVarintSpec(dAtA, i, uint64(*m.Amount))
+	}
+	if m.Power != nil {
+		dAtA[i] = 0x30
+		i++
+		i = encodeVarintSpec(dAtA, i, uint64(*m.Power))
+	}
+	if len(m.Permissions) > 0 {
+		for _, s := range m.Permissions {
+			dAtA[i] = 0x3a
+			i++
+			l = len(s)
+			for l >= 1<<7 {
+				dAtA[i] = uint8(uint64(l)&0x7f | 0x80)
+				l >>= 7
+				i++
+			}
+			dAtA[i] = uint8(l)
+			i++
+			i += copy(dAtA[i:], s)
+		}
+	}
+	if len(m.Roles) > 0 {
+		for _, s := range m.Roles {
+			dAtA[i] = 0x42
+			i++
+			l = len(s)
+			for l >= 1<<7 {
+				dAtA[i] = uint8(uint64(l)&0x7f | 0x80)
+				l >>= 7
+				i++
+			}
+			dAtA[i] = uint8(l)
+			i++
+			i += copy(dAtA[i:], s)
+		}
+	}
+	return i, nil
+}
+
+func encodeVarintSpec(dAtA []byte, offset int, v uint64) int {
+	for v >= 1<<7 {
+		dAtA[offset] = uint8(v&0x7f | 0x80)
+		v >>= 7
+		offset++
+	}
+	dAtA[offset] = uint8(v)
+	return offset + 1
+}
+func (m *TemplateAccount) Size() (n int) {
+	var l int
+	_ = l
+	l = len(m.Name)
+	n += 1 + l + sovSpec(uint64(l))
+	if m.Address != nil {
+		l = m.Address.Size()
+		n += 1 + l + sovSpec(uint64(l))
+	}
+	if m.NodeAddress != nil {
+		l = m.NodeAddress.Size()
+		n += 1 + l + sovSpec(uint64(l))
+	}
+	if m.PublicKey != nil {
+		l = m.PublicKey.Size()
+		n += 1 + l + sovSpec(uint64(l))
+	}
+	if m.Amount != nil {
+		n += 1 + sovSpec(uint64(*m.Amount))
+	}
+	if m.Power != nil {
+		n += 1 + sovSpec(uint64(*m.Power))
+	}
+	if len(m.Permissions) > 0 {
+		for _, s := range m.Permissions {
+			l = len(s)
+			n += 1 + l + sovSpec(uint64(l))
+		}
+	}
+	if len(m.Roles) > 0 {
+		for _, s := range m.Roles {
+			l = len(s)
+			n += 1 + l + sovSpec(uint64(l))
+		}
+	}
+	return n
+}
+
+func sovSpec(x uint64) (n int) {
+	for {
+		n++
+		x >>= 7
+		if x == 0 {
+			break
+		}
+	}
+	return n
+}
+func sozSpec(x uint64) (n int) {
+	return sovSpec(uint64((x << 1) ^ uint64((int64(x) >> 63))))
+}
+func (m *TemplateAccount) Unmarshal(dAtA []byte) error {
+	l := len(dAtA)
+	iNdEx := 0
+	for iNdEx < l {
+		preIndex := iNdEx
+		var wire uint64
+		for shift := uint(0); ; shift += 7 {
+			if shift >= 64 {
+				return ErrIntOverflowSpec
+			}
+			if iNdEx >= l {
+				return io.ErrUnexpectedEOF
+			}
+			b := dAtA[iNdEx]
+			iNdEx++
+			wire |= (uint64(b) & 0x7F) << shift
+			if b < 0x80 {
+				break
+			}
+		}
+		fieldNum := int32(wire >> 3)
+		wireType := int(wire & 0x7)
+		if wireType == 4 {
+			return fmt.Errorf("proto: TemplateAccount: wiretype end group for non-group")
+		}
+		if fieldNum <= 0 {
+			return fmt.Errorf("proto: TemplateAccount: illegal tag %d (wire type %d)", fieldNum, wire)
+		}
+		switch fieldNum {
+		case 1:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType)
+			}
+			var stringLen uint64
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowSpec
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				stringLen |= (uint64(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			intStringLen := int(stringLen)
+			if intStringLen < 0 {
+				return ErrInvalidLengthSpec
+			}
+			postIndex := iNdEx + intStringLen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			m.Name = string(dAtA[iNdEx:postIndex])
+			iNdEx = postIndex
+		case 2:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Address", wireType)
+			}
+			var byteLen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowSpec
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				byteLen |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if byteLen < 0 {
+				return ErrInvalidLengthSpec
+			}
+			postIndex := iNdEx + byteLen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			var v github_com_hyperledger_burrow_crypto.Address
+			m.Address = &v
+			if err := m.Address.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+				return err
+			}
+			iNdEx = postIndex
+		case 3:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field NodeAddress", wireType)
+			}
+			var byteLen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowSpec
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				byteLen |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if byteLen < 0 {
+				return ErrInvalidLengthSpec
+			}
+			postIndex := iNdEx + byteLen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			var v github_com_hyperledger_burrow_crypto.Address
+			m.NodeAddress = &v
+			if err := m.NodeAddress.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+				return err
+			}
+			iNdEx = postIndex
+		case 4:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field PublicKey", wireType)
+			}
+			var msglen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowSpec
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				msglen |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if msglen < 0 {
+				return ErrInvalidLengthSpec
+			}
+			postIndex := iNdEx + msglen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			if m.PublicKey == nil {
+				m.PublicKey = &crypto.PublicKey{}
+			}
+			if err := m.PublicKey.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+				return err
+			}
+			iNdEx = postIndex
+		case 5:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Amount", wireType)
+			}
+			var v uint64
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowSpec
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				v |= (uint64(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			m.Amount = &v
+		case 6:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Power", wireType)
+			}
+			var v uint64
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowSpec
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				v |= (uint64(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			m.Power = &v
+		case 7:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Permissions", wireType)
+			}
+			var stringLen uint64
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowSpec
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				stringLen |= (uint64(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			intStringLen := int(stringLen)
+			if intStringLen < 0 {
+				return ErrInvalidLengthSpec
+			}
+			postIndex := iNdEx + intStringLen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			m.Permissions = append(m.Permissions, string(dAtA[iNdEx:postIndex]))
+			iNdEx = postIndex
+		case 8:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Roles", wireType)
+			}
+			var stringLen uint64
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowSpec
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				stringLen |= (uint64(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			intStringLen := int(stringLen)
+			if intStringLen < 0 {
+				return ErrInvalidLengthSpec
+			}
+			postIndex := iNdEx + intStringLen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			m.Roles = append(m.Roles, string(dAtA[iNdEx:postIndex]))
+			iNdEx = postIndex
+		default:
+			iNdEx = preIndex
+			skippy, err := skipSpec(dAtA[iNdEx:])
+			if err != nil {
+				return err
+			}
+			if skippy < 0 {
+				return ErrInvalidLengthSpec
+			}
+			if (iNdEx + skippy) > l {
+				return io.ErrUnexpectedEOF
+			}
+			iNdEx += skippy
+		}
+	}
+
+	if iNdEx > l {
+		return io.ErrUnexpectedEOF
+	}
+	return nil
+}
+func skipSpec(dAtA []byte) (n int, err error) {
+	l := len(dAtA)
+	iNdEx := 0
+	for iNdEx < l {
+		var wire uint64
+		for shift := uint(0); ; shift += 7 {
+			if shift >= 64 {
+				return 0, ErrIntOverflowSpec
+			}
+			if iNdEx >= l {
+				return 0, io.ErrUnexpectedEOF
+			}
+			b := dAtA[iNdEx]
+			iNdEx++
+			wire |= (uint64(b) & 0x7F) << shift
+			if b < 0x80 {
+				break
+			}
+		}
+		wireType := int(wire & 0x7)
+		switch wireType {
+		case 0:
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return 0, ErrIntOverflowSpec
+				}
+				if iNdEx >= l {
+					return 0, io.ErrUnexpectedEOF
+				}
+				iNdEx++
+				if dAtA[iNdEx-1] < 0x80 {
+					break
+				}
+			}
+			return iNdEx, nil
+		case 1:
+			iNdEx += 8
+			return iNdEx, nil
+		case 2:
+			var length int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return 0, ErrIntOverflowSpec
+				}
+				if iNdEx >= l {
+					return 0, io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				length |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			iNdEx += length
+			if length < 0 {
+				return 0, ErrInvalidLengthSpec
+			}
+			return iNdEx, nil
+		case 3:
+			for {
+				var innerWire uint64
+				var start int = iNdEx
+				for shift := uint(0); ; shift += 7 {
+					if shift >= 64 {
+						return 0, ErrIntOverflowSpec
+					}
+					if iNdEx >= l {
+						return 0, io.ErrUnexpectedEOF
+					}
+					b := dAtA[iNdEx]
+					iNdEx++
+					innerWire |= (uint64(b) & 0x7F) << shift
+					if b < 0x80 {
+						break
+					}
+				}
+				innerWireType := int(innerWire & 0x7)
+				if innerWireType == 4 {
+					break
+				}
+				next, err := skipSpec(dAtA[start:])
+				if err != nil {
+					return 0, err
+				}
+				iNdEx = start + next
+			}
+			return iNdEx, nil
+		case 4:
+			return iNdEx, nil
+		case 5:
+			iNdEx += 4
+			return iNdEx, nil
+		default:
+			return 0, fmt.Errorf("proto: illegal wireType %d", wireType)
+		}
+	}
+	panic("unreachable")
+}
+
+var (
+	ErrInvalidLengthSpec = fmt.Errorf("proto: negative length found during unmarshaling")
+	ErrIntOverflowSpec   = fmt.Errorf("proto: integer overflow")
+)
+
+func init() { proto.RegisterFile("spec.proto", fileDescriptorSpec) }
+func init() { golang_proto.RegisterFile("spec.proto", fileDescriptorSpec) }
+
+var fileDescriptorSpec = []byte{
+	// 359 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x92, 0x3f, 0x6f, 0xe2, 0x30,
+	0x18, 0x87, 0xf1, 0x11, 0xe0, 0x30, 0x48, 0x27, 0x3c, 0x59, 0x0c, 0x49, 0xc4, 0x2d, 0xd1, 0x89,
+	0x23, 0xd2, 0x6d, 0x47, 0x97, 0x12, 0xa9, 0x53, 0x25, 0x84, 0x28, 0x53, 0x37, 0x92, 0xbc, 0x0d,
+	0x91, 0x62, 0x1c, 0xd9, 0x8e, 0x50, 0x3e, 0x4e, 0xbf, 0x49, 0x47, 0x46, 0xe6, 0x0e, 0x51, 0x05,
+	0x43, 0xa5, 0x8e, 0xfd, 0x04, 0x55, 0x42, 0x28, 0x4c, 0x55, 0x96, 0x6e, 0xef, 0x1f, 0x3d, 0xbf,
+	0xc7, 0xb2, 0x8d, 0xb1, 0x8c, 0xc1, 0x1b, 0xc5, 0x82, 0x2b, 0x4e, 0xb4, 0xbc, 0xee, 0xff, 0x0d,
+	0x42, 0xb5, 0x4a, 0xdc, 0x91, 0xc7, 0x99, 0x1d, 0xf0, 0x80, 0xdb, 0xc5, 0xd2, 0x4d, 0x1e, 0x8a,
+	0xae, 0x68, 0x8a, 0xea, 0x08, 0xf5, 0xbb, 0x9e, 0x48, 0x63, 0x55, 0x76, 0x83, 0x57, 0x0d, 0xff,
+	0x5a, 0x00, 0x8b, 0xa3, 0xa5, 0x82, 0x89, 0xe7, 0xf1, 0x64, 0xad, 0x08, 0xc5, 0xda, 0x74, 0xc9,
+	0x80, 0x22, 0x13, 0x59, 0x6d, 0x47, 0xdb, 0x66, 0x46, 0x6d, 0x5e, 0x4c, 0x08, 0xc3, 0xad, 0x89,
+	0xef, 0x0b, 0x90, 0x92, 0xfe, 0x30, 0x91, 0xd5, 0x75, 0xee, 0x9e, 0x33, 0x63, 0x78, 0xe1, 0x5f,
+	0xa5, 0x31, 0x88, 0x08, 0xfc, 0x00, 0x84, 0xed, 0x26, 0x42, 0xf0, 0x8d, 0x5d, 0xea, 0x4a, 0xee,
+	0x2d, 0x33, 0xf0, 0x90, 0xb3, 0x50, 0x01, 0x8b, 0x55, 0xfa, 0x9e, 0x19, 0x3d, 0xc5, 0x59, 0x34,
+	0x1e, 0x9c, 0x67, 0x83, 0xf9, 0xc9, 0x41, 0x12, 0xdc, 0x99, 0x72, 0x1f, 0x4e, 0xca, 0xfa, 0xf7,
+	0x29, 0x2f, 0x3d, 0x64, 0x81, 0xdb, 0xb3, 0xc4, 0x8d, 0x42, 0xef, 0x16, 0x52, 0xaa, 0x99, 0xc8,
+	0xea, 0xfc, 0xeb, 0x8d, 0xca, 0xcc, 0xcf, 0x85, 0xf3, 0xbb, 0x4a, 0xee, 0x39, 0x88, 0x5c, 0xe1,
+	0xe6, 0x84, 0xe5, 0xf7, 0x4b, 0x1b, 0x26, 0xb2, 0xb4, 0x6a, 0x7c, 0x89, 0x90, 0xff, 0xb8, 0x31,
+	0xe3, 0x1b, 0x10, 0xb4, 0x59, 0x9d, 0x3d, 0x12, 0xe4, 0x06, 0x77, 0x66, 0x20, 0x58, 0x28, 0x65,
+	0xc8, 0xd7, 0x92, 0xb6, 0xcc, 0xba, 0xd5, 0xae, 0x16, 0x70, 0xc9, 0xe5, 0x27, 0x98, 0xf3, 0x08,
+	0x24, 0xfd, 0x59, 0x3d, 0xe0, 0x48, 0x8c, 0xb5, 0xdd, 0xa3, 0x51, 0x73, 0xae, 0xb7, 0x7b, 0x1d,
+	0xed, 0xf6, 0x3a, 0x7a, 0xd9, 0xeb, 0xe8, 0xe9, 0xa0, 0xa3, 0xed, 0x41, 0x47, 0xf7, 0x7f, 0xbe,
+	0x7e, 0xc9, 0x00, 0xd6, 0x20, 0x43, 0x69, 0xe7, 0x1f, 0xfd, 0x23, 0x00, 0x00, 0xff, 0xff, 0x4b,
+	0xcc, 0xe3, 0x66, 0xfb, 0x02, 0x00, 0x00,
+}
diff --git a/genesis/spec/template_account.go b/genesis/spec/template_account.go
index 9d3c2acc4d60bbcc4465ef250b94335260bac715..1362ec117623dcd038f82460883ccecfb378bf15 100644
--- a/genesis/spec/template_account.go
+++ b/genesis/spec/template_account.go
@@ -7,22 +7,8 @@ import (
 	"github.com/hyperledger/burrow/genesis"
 	"github.com/hyperledger/burrow/keys"
 	"github.com/hyperledger/burrow/permission"
-	ptypes "github.com/hyperledger/burrow/permission/types"
 )
 
-type TemplateAccount struct {
-	// Template accounts sharing a name will be merged when merging genesis specs
-	Name string `json:",omitempty" toml:",omitempty"`
-	// Address  is convenient to have in file for reference, but otherwise ignored since derived from PublicKey
-	Address     *crypto.Address   `json:",omitempty" toml:",omitempty"`
-	NodeAddress *crypto.Address   `json:",omitempty" toml:",omitempty"`
-	PublicKey   *crypto.PublicKey `json:",omitempty" toml:",omitempty"`
-	Amount      *uint64           `json:",omitempty" toml:",omitempty"`
-	Power       *uint64           `json:",omitempty" toml:",omitempty"`
-	Permissions []string          `json:",omitempty" toml:",omitempty"`
-	Roles       []string          `json:",omitempty" toml:",omitempty"`
-}
-
 func (ta TemplateAccount) Validator(keyClient keys.KeyClient, index int, generateNodeKeys bool) (*genesis.Validator, error) {
 	var err error
 	gv := new(genesis.Validator)
@@ -58,12 +44,12 @@ func (ta TemplateAccount) Validator(keyClient keys.KeyClient, index int, generat
 	return gv, nil
 }
 
-func (ta TemplateAccount) AccountPermissions() (ptypes.AccountPermissions, error) {
+func (ta TemplateAccount) AccountPermissions() (permission.AccountPermissions, error) {
 	basePerms, err := permission.BasePermissionsFromStringList(ta.Permissions)
 	if err != nil {
 		return permission.ZeroAccountPermissions, nil
 	}
-	return ptypes.AccountPermissions{
+	return permission.AccountPermissions{
 		Base:  basePerms,
 		Roles: ta.Roles,
 	}, nil
diff --git a/core/kernel_test.go b/integration/core/kernel_test.go
similarity index 61%
rename from core/kernel_test.go
rename to integration/core/kernel_test.go
index be0c5106875518518a4c53cf95c4f04d465c7f35..d4003e2127c916b97fd2bc9bf5feae91e6f7b928 100644
--- a/core/kernel_test.go
+++ b/integration/core/kernel_test.go
@@ -1,3 +1,5 @@
+// +build integration
+
 package core
 
 import (
@@ -7,12 +9,15 @@ import (
 	"testing"
 	"time"
 
-	"github.com/hyperledger/burrow/consensus/tendermint"
+	"github.com/hyperledger/burrow/config"
 	"github.com/hyperledger/burrow/consensus/tendermint/validator"
+	"github.com/hyperledger/burrow/core"
+	"github.com/hyperledger/burrow/event"
+	"github.com/hyperledger/burrow/execution/exec"
 	"github.com/hyperledger/burrow/genesis"
+	"github.com/hyperledger/burrow/integration"
 	"github.com/hyperledger/burrow/keys"
 	"github.com/hyperledger/burrow/logging"
-	"github.com/hyperledger/burrow/rpc"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
 	tmConfig "github.com/tendermint/tendermint/config"
@@ -30,7 +35,7 @@ func TestBootThenShutdown(t *testing.T) {
 	logger := logging.NewNoopLogger()
 	genesisDoc, _, privateValidators := genesis.NewDeterministicGenesis(123).GenesisDoc(1, true, 1000, 1, true, 1000)
 	privValidator := validator.NewPrivValidatorMemory(privateValidators[0], privateValidators[0])
-	assert.NoError(t, bootWaitBlocksShutdown(privValidator, genesisDoc, tmConf, logger, nil))
+	assert.NoError(t, bootWaitBlocksShutdown(privValidator, integration.NewTestConfig(genesisDoc), tmConf, logger, nil))
 }
 
 func TestBootShutdownResume(t *testing.T) {
@@ -43,31 +48,36 @@ func TestBootShutdownResume(t *testing.T) {
 	genesisDoc, _, privateValidators := genesis.NewDeterministicGenesis(123).GenesisDoc(1, true, 1000, 1, true, 1000)
 	privValidator := validator.NewPrivValidatorMemory(privateValidators[0], privateValidators[0])
 
-	i := int64(0)
+	i := uint64(0)
 	// asserts we get a consecutive run of blocks
-	blockChecker := func(block *tmTypes.EventDataNewBlock) bool {
-		assert.Equal(t, i+1, block.Block.Height)
+	blockChecker := func(block *exec.BlockExecution) bool {
+		assert.Equal(t, i+1, block.Height)
 		i++
 		// stop every third block
 		return i%3 != 0
 	}
+	testConfig := integration.NewTestConfig(genesisDoc)
 	// First run
-	require.NoError(t, bootWaitBlocksShutdown(privValidator, genesisDoc, tmConf, logger, blockChecker))
+	require.NoError(t, bootWaitBlocksShutdown(privValidator, testConfig, tmConf, logger, blockChecker))
 	// Resume and check we pick up where we left off
-	require.NoError(t, bootWaitBlocksShutdown(privValidator, genesisDoc, tmConf, logger, blockChecker))
+	require.NoError(t, bootWaitBlocksShutdown(privValidator, testConfig, tmConf, logger, blockChecker))
 	// Resuming with mismatched genesis should fail
 	genesisDoc.Salt = []byte("foo")
-	assert.Error(t, bootWaitBlocksShutdown(privValidator, genesisDoc, tmConf, logger, blockChecker))
+	assert.Error(t, bootWaitBlocksShutdown(privValidator, testConfig, tmConf, logger, blockChecker))
 }
 
-func bootWaitBlocksShutdown(privValidator tmTypes.PrivValidator, genesisDoc *genesis.GenesisDoc,
+func bootWaitBlocksShutdown(privValidator tmTypes.PrivValidator, testConfig *config.BurrowConfig,
 	tmConf *tmConfig.Config, logger *logging.Logger,
-	blockChecker func(block *tmTypes.EventDataNewBlock) (cont bool)) error {
+	blockChecker func(block *exec.BlockExecution) (cont bool)) error {
 
 	keyStore := keys.NewKeyStore(keys.DefaultKeysDir, false, logger)
 	keyClient := keys.NewLocalKeyClient(keyStore, logging.NewNoopLogger())
-	kern, err := NewKernel(context.Background(), keyClient, privValidator, genesisDoc, tmConf,
-		rpc.DefaultRPCConfig(), keys.DefaultKeysConfig(), keyStore, nil, logger)
+	kern, err := core.NewKernel(context.Background(), keyClient, privValidator,
+		testConfig.GenesisDoc,
+		testConfig.Tendermint.TendermintConfig(),
+		testConfig.RPC,
+		testConfig.Keys,
+		keyStore, nil, logger)
 	if err != nil {
 		return err
 	}
@@ -77,10 +87,12 @@ func bootWaitBlocksShutdown(privValidator tmTypes.PrivValidator, genesisDoc *gen
 		return err
 	}
 
-	ch, err := tendermint.SubscribeNewBlock(context.Background(), kern.Emitter)
+	subID := event.GenSubID()
+	ch, err := kern.Emitter.Subscribe(context.Background(), subID, exec.QueryForBlockExecution(), 10)
 	if err != nil {
 		return err
 	}
+	defer kern.Emitter.UnsubscribeAll(context.Background(), subID)
 	cont := true
 	for cont {
 		select {
@@ -88,11 +100,11 @@ func bootWaitBlocksShutdown(privValidator tmTypes.PrivValidator, genesisDoc *gen
 			if err != nil {
 				return fmt.Errorf("timed out waiting for block")
 			}
-		case ednb := <-ch:
+		case msg := <-ch:
 			if blockChecker == nil {
 				cont = false
 			} else {
-				cont = blockChecker(ednb)
+				cont = blockChecker(msg.(*exec.BlockExecution))
 			}
 		}
 	}
diff --git a/rpc/tm/integration/main_test.go b/integration/core/main_test.go
similarity index 75%
rename from rpc/tm/integration/main_test.go
rename to integration/core/main_test.go
index 9833d45c9668313b8104da27c639286373b376d0..af90e852e37a5aed272ec671b8b192ba8e17d27f 100644
--- a/rpc/tm/integration/main_test.go
+++ b/integration/core/main_test.go
@@ -15,23 +15,19 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package integration
+package core
 
 import (
 	"os"
 	"testing"
-	"time"
 
-	"github.com/hyperledger/burrow/core"
-	"github.com/hyperledger/burrow/core/integration"
+	"github.com/hyperledger/burrow/integration"
 )
 
+var _ = integration.ClaimPorts()
+
 // Needs to be in a _test.go file to be picked up
 func TestMain(m *testing.M) {
-	returnValue := integration.TestWrapper(privateAccounts, genesisDoc, func(*core.Kernel) int {
-		return m.Run()
-	})
-
-	time.Sleep(3 * time.Second)
+	returnValue := m.Run()
 	os.Exit(returnValue)
 }
diff --git a/core/integration/test_wrapper.go b/integration/integration.go
similarity index 53%
rename from core/integration/test_wrapper.go
rename to integration/integration.go
index 79b5db460b908c8c5f8f387a5194efa95578cecd..388cae7d617b7b366195479fc85357c404616894 100644
--- a/core/integration/test_wrapper.go
+++ b/integration/integration.go
@@ -1,6 +1,3 @@
-// +build integration
-
-// Space above here matters
 // Copyright 2017 Monax Industries Limited
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
@@ -19,24 +16,26 @@ package integration
 
 import (
 	"context"
+	"encoding/binary"
 	"fmt"
 	"os"
+	"runtime"
 	"strconv"
+	"sync/atomic"
 	"time"
 
-	acm "github.com/hyperledger/burrow/account"
+	"github.com/hyperledger/burrow/acm"
+	"github.com/hyperledger/burrow/config"
 	"github.com/hyperledger/burrow/consensus/tendermint/validator"
 	"github.com/hyperledger/burrow/core"
+	"github.com/hyperledger/burrow/execution/evm/sha3"
 	"github.com/hyperledger/burrow/genesis"
-	"github.com/hyperledger/burrow/keys"
 	"github.com/hyperledger/burrow/keys/mock"
 	"github.com/hyperledger/burrow/logging"
-	"github.com/hyperledger/burrow/logging/config"
+	lConfig "github.com/hyperledger/burrow/logging/config"
 	"github.com/hyperledger/burrow/logging/lifecycle"
 	"github.com/hyperledger/burrow/logging/structure"
 	"github.com/hyperledger/burrow/permission"
-	"github.com/hyperledger/burrow/rpc"
-	tm_config "github.com/tendermint/tendermint/config"
 )
 
 const (
@@ -48,31 +47,42 @@ const (
 //var debugLogging = true
 var debugLogging = false
 
+// Starting point for assigning range of ports for tests
+// Start at unprivileged port (hoping for the best)
+const startingPort uint16 = 1024
+
+// For each port claimant assign a bucket
+const startingPortSeparation uint16 = 10
+const startingPortBuckets = 1000
+
+// Mutable port to assign to next claimant
+var port = uint32(startingPort)
+
 // We use this to wrap tests
-func TestWrapper(privateAccounts []acm.PrivateAccount, genesisDoc *genesis.GenesisDoc, runner func(*core.Kernel) int) int {
-	fmt.Println("Running with integration TestWrapper (core/integration/test_wrapper.go)...")
+func TestWrapper(privateAccounts []*acm.PrivateAccount, testConfig *config.BurrowConfig, runner func(*core.Kernel) int) int {
+	fmt.Println("Running with integration TestWrapper (core/integration/integration.go)...")
 
 	os.RemoveAll(testDir)
 	os.MkdirAll(testDir, 0777)
 	os.Chdir(testDir)
 
-	tmConf := tm_config.DefaultConfig()
 	os.MkdirAll("config", 0777)
+
 	logger := logging.NewNoopLogger()
 	if debugLogging {
 		var err error
 		// Change config as needed
-		logger, err = lifecycle.NewLoggerFromLoggingConfig(&config.LoggingConfig{
+		logger, err = lifecycle.NewLoggerFromLoggingConfig(&lConfig.LoggingConfig{
 			ExcludeTrace: false,
-			RootSink: config.Sink().
-				SetTransform(config.FilterTransform(config.IncludeWhenAnyMatches,
+			RootSink: lConfig.Sink().
+				SetTransform(lConfig.FilterTransform(lConfig.IncludeWhenAnyMatches,
 					structure.ComponentKey, "Tendermint",
 					structure.ScopeKey, "executor.Execute\\(tx txs.Tx\\)",
 				)).
 				//AddSinks(config.Sink().SetTransform(config.FilterTransform(config.ExcludeWhenAnyMatches, "run_call", "false")).
-				AddSinks(config.Sink().SetTransform(config.PruneTransform("log_channel", "trace", "scope", "returns", "run_id", "args")).
-					AddSinks(config.Sink().SetTransform(config.SortTransform("tx_hash", "time", "message", "method")).
-						SetOutput(config.StdoutOutput()))),
+				AddSinks(lConfig.Sink().SetTransform(lConfig.PruneTransform("log_channel", "trace", "scope", "returns", "run_id", "args")).
+					AddSinks(lConfig.Sink().SetTransform(lConfig.SortTransform("tx_hash", "time", "message", "method")).
+						SetOutput(lConfig.StdoutOutput()))),
 		})
 		if err != nil {
 			panic(err)
@@ -82,14 +92,18 @@ func TestWrapper(privateAccounts []acm.PrivateAccount, genesisDoc *genesis.Genes
 	validatorAccount := privateAccounts[0]
 	privValidator := validator.NewPrivValidatorMemory(validatorAccount, validatorAccount)
 	keyClient := mock.NewKeyClient(privateAccounts...)
-	kernel, err := core.NewKernel(context.Background(), keyClient, privValidator, genesisDoc, tmConf, rpc.DefaultRPCConfig(), keys.DefaultKeysConfig(),
+	kernel, err := core.NewKernel(context.Background(), keyClient, privValidator,
+		testConfig.GenesisDoc,
+		testConfig.Tendermint.TendermintConfig(),
+		testConfig.RPC,
+		testConfig.Keys,
 		nil, nil, logger)
 	if err != nil {
 		panic(err)
 	}
 	// Sometimes better to not shutdown as logging errors on shutdown may obscure real issue
 	defer func() {
-		//kernel.Shutdown(context.Background())
+		kernel.Shutdown(context.Background())
 	}()
 
 	err = kernel.Boot()
@@ -100,7 +114,7 @@ func TestWrapper(privateAccounts []acm.PrivateAccount, genesisDoc *genesis.Genes
 	return runner(kernel)
 }
 
-func TestGenesisDoc(addressables []acm.PrivateAccount) *genesis.GenesisDoc {
+func TestGenesisDoc(addressables []*acm.PrivateAccount) *genesis.GenesisDoc {
 	accounts := make(map[string]acm.Account, len(addressables))
 	for i, pa := range addressables {
 		account := acm.FromAddressable(pa)
@@ -119,10 +133,48 @@ func TestGenesisDoc(addressables []acm.PrivateAccount) *genesis.GenesisDoc {
 }
 
 // Deterministic account generation helper. Pass number of accounts to make
-func MakePrivateAccounts(n int) []acm.PrivateAccount {
-	accounts := make([]acm.PrivateAccount, n)
+func MakePrivateAccounts(n int) []*acm.PrivateAccount {
+	accounts := make([]*acm.PrivateAccount, n)
 	for i := 0; i < n; i++ {
 		accounts[i] = acm.GeneratePrivateAccountFromSecret("mysecret" + strconv.Itoa(i))
 	}
 	return accounts
 }
+
+// Some helpers for setting Burrow's various ports in non-colliding ranges for tests
+func ClaimPorts() uint16 {
+	_, file, _, _ := runtime.Caller(1)
+	startIndex := uint16(binary.LittleEndian.Uint16(sha3.Sha3([]byte(file)))) % startingPortBuckets
+	newPort := startingPort + startIndex*startingPortSeparation
+	// In case overflow
+	if newPort < startingPort {
+		newPort += startingPort
+	}
+	if !atomic.CompareAndSwapUint32(&port, uint32(startingPort), uint32(newPort)) {
+		panic("GetPort() called before ClaimPorts() or ClaimPorts() called twice")
+	}
+	return uint16(atomic.LoadUint32(&port))
+}
+
+func GetPort() uint16 {
+	return uint16(atomic.AddUint32(&port, 1))
+}
+
+func GetLocalAddress() string {
+	return fmt.Sprintf("localhost:%v", GetPort())
+}
+
+func GetTCPLocalAddress() string {
+	return fmt.Sprintf("tcp://localhost:%v", GetPort())
+}
+
+func NewTestConfig(genesisDoc *genesis.GenesisDoc) *config.BurrowConfig {
+	cnf := config.DefaultBurrowConfig()
+	cnf.GenesisDoc = genesisDoc
+	cnf.Tendermint.ListenAddress = GetTCPLocalAddress()
+	cnf.RPC.GRPC.ListenAddress = GetLocalAddress()
+	cnf.RPC.Metrics.ListenAddress = GetTCPLocalAddress()
+	cnf.RPC.TM.ListenAddress = GetTCPLocalAddress()
+	cnf.Keys.RemoteAddress = ""
+	return cnf
+}
diff --git a/integration/rpcevents/execution_events_server_test.go b/integration/rpcevents/execution_events_server_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..19c96d3bbe4cbbfe4fb762789ef309e4c0ac93dd
--- /dev/null
+++ b/integration/rpcevents/execution_events_server_test.go
@@ -0,0 +1,192 @@
+// +build integration
+
+// Space above here matters
+// Copyright 2017 Monax Industries Limited
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package rpcevents
+
+import (
+	"context"
+	"io"
+	"testing"
+
+	"time"
+
+	"strconv"
+
+	"github.com/hyperledger/burrow/event"
+	"github.com/hyperledger/burrow/event/query"
+	"github.com/hyperledger/burrow/execution/exec"
+	"github.com/hyperledger/burrow/integration/rpctest"
+	"github.com/hyperledger/burrow/rpc/rpcevents"
+	"github.com/hyperledger/burrow/rpc/rpctransact"
+	"github.com/hyperledger/burrow/txs/payload"
+	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/require"
+)
+
+func TestGetBlocks(t *testing.T) {
+	request := &rpcevents.BlocksRequest{
+		BlockRange: rpcevents.NewBlockRange(rpcevents.LatestBound(), rpcevents.StreamBound()),
+	}
+	tcli := rpctest.NewTransactClient(t, testConfig.RPC.GRPC.ListenAddress)
+	ecli := rpctest.NewExecutionEventsClient(t, testConfig.RPC.GRPC.ListenAddress)
+	stream, err := ecli.GetBlocks(context.Background(), request)
+	require.NoError(t, err)
+	pulls := 3
+	sendsPerPull := 4
+	var blocks []*exec.BlockExecution
+	for i := 0; i < pulls; i++ {
+		doSends(t, sendsPerPull, tcli)
+		block, err := stream.Recv()
+		require.NoError(t, err)
+		blocks = append(blocks, block)
+	}
+	assert.True(t, len(blocks) > 0, "should see at least one block (height 2)")
+	var height uint64
+	for _, b := range blocks {
+		if height > 0 {
+			assert.Equal(t, height+1, b.Height)
+		}
+		height = b.Height
+	}
+	require.NoError(t, stream.CloseSend())
+}
+func TestGetBlocksContains2(t *testing.T) {
+	request := &rpcevents.BlocksRequest{
+		BlockRange: rpcevents.NewBlockRange(rpcevents.LatestBound(), rpcevents.StreamBound()),
+		Query:      "Height CONTAINS '2'",
+	}
+	tcli := rpctest.NewTransactClient(t, testConfig.RPC.GRPC.ListenAddress)
+	ecli := rpctest.NewExecutionEventsClient(t, testConfig.RPC.GRPC.ListenAddress)
+	stream, err := ecli.GetBlocks(context.Background(), request)
+	require.NoError(t, err)
+	pulls := 2
+	sendsPerPull := 4
+	var blocks []*exec.BlockExecution
+	for i := 0; i < pulls; i++ {
+		doSends(t, sendsPerPull, tcli)
+		block, err := stream.Recv()
+		require.NoError(t, err)
+		blocks = append(blocks, block)
+		assert.Contains(t, strconv.FormatUint(block.Height, 10), "2")
+	}
+	assert.True(t, len(blocks) > 0, "should see at least one block (height 2)")
+	require.NoError(t, stream.CloseSend())
+}
+
+func TestGetEventsSend(t *testing.T) {
+	request := &rpcevents.BlocksRequest{
+		BlockRange: rpcevents.NewBlockRange(rpcevents.AbsoluteBound(kern.Blockchain.LastBlockHeight()),
+			rpcevents.LatestBound()),
+	}
+	numSends := 1100
+	responses := testGetEventsSend(t, numSends, request)
+	assert.Equal(t, numSends*2, countEventsAndCheckConsecutive(t, responses),
+		"should receive 1 input, 1 output per send")
+}
+
+func TestGetEventsSendContainsAA(t *testing.T) {
+	request := &rpcevents.BlocksRequest{
+		BlockRange: rpcevents.NewBlockRange(rpcevents.AbsoluteBound(kern.Blockchain.LastBlockHeight()),
+			rpcevents.LatestBound()),
+		Query: "TxHash CONTAINS 'AA'",
+	}
+	numSends := 1100
+	responses := testGetEventsSend(t, numSends, request)
+	for _, response := range responses {
+		for _, ev := range response.Events {
+			require.Contains(t, ev.Header.TxHash.String(), "AA")
+		}
+	}
+}
+
+func TestGetEventsSendFiltered(t *testing.T) {
+	request := &rpcevents.BlocksRequest{
+		BlockRange: rpcevents.NewBlockRange(rpcevents.AbsoluteBound(kern.Blockchain.LastBlockHeight()),
+			rpcevents.LatestBound()),
+		Query: query.NewBuilder().AndEquals(event.EventTypeKey, exec.TypeAccountInput.String()).String(),
+	}
+	numSends := 500
+	responses := testGetEventsSend(t, numSends, request)
+	assert.Equal(t, numSends, countEventsAndCheckConsecutive(t, responses), "should receive a single input event per send")
+}
+
+func testGetEventsSend(t *testing.T, numSends int, request *rpcevents.BlocksRequest) []*rpcevents.GetEventsResponse {
+
+	doSends(t, numSends, rpctest.NewTransactClient(t, testConfig.RPC.GRPC.ListenAddress))
+	ecli := rpctest.NewExecutionEventsClient(t, testConfig.RPC.GRPC.ListenAddress)
+	evs, err := ecli.GetEvents(context.Background(), request)
+	require.NoError(t, err)
+	var responses []*rpcevents.GetEventsResponse
+	for {
+		resp, err := evs.Recv()
+		if err != nil {
+			if err == io.EOF {
+				break
+			}
+			require.NoError(t, err)
+		}
+		responses = append(responses, resp)
+	}
+	return responses
+}
+
+func doSends(t *testing.T, numSends int, cli rpctransact.TransactClient) {
+	countCh := rpctest.CommittedTxCount(t, kern.Emitter)
+	amt := uint64(2004)
+	for i := 0; i < numSends; i++ {
+		// Slow us down a bit to ensure spread across blocks
+		time.Sleep(time.Millisecond)
+		receipt, err := cli.SendTxAsync(context.Background(),
+			&payload.SendTx{
+				Inputs: []*payload.TxInput{{
+					Address: inputAddress,
+					Amount:  amt,
+				}},
+				Outputs: []*payload.TxOutput{{
+					Address: rpctest.PrivateAccounts[4].Address(),
+					Amount:  amt,
+				}},
+			})
+		require.NoError(t, err)
+		assert.False(t, receipt.CreatesContract)
+	}
+	require.Equal(t, numSends, <-countCh)
+}
+
+func countEventsAndCheckConsecutive(t *testing.T, respones []*rpcevents.GetEventsResponse) int {
+	i := 0
+	var height uint64
+	var index uint64
+	txHash := ""
+	for _, resp := range respones {
+		require.True(t, resp.Height > height, "must not receive multiple GetEventsResponses for the same block")
+		height := resp.Height
+		for _, ev := range resp.Events {
+			require.Equal(t, ev.Header.Height, height, "height of event headers much match height of GetEventsResponse")
+			if txHash != ev.Header.TxHash.String() {
+				txHash = ev.Header.TxHash.String()
+				index = 0
+			}
+			if ev.Header.Index > index {
+				require.Equal(t, index+1, ev.Header.Index)
+				index++
+			}
+			i++
+		}
+	}
+	return i
+}
diff --git a/rpc/rpcevents/integration/main_test.go b/integration/rpcevents/main_test.go
similarity index 62%
rename from rpc/rpcevents/integration/main_test.go
rename to integration/rpcevents/main_test.go
index 338b533457def710c8e5d9e6895a8606d8d49c97..8418fbd740cffae49f2d109dbfadad1a6f739f15 100644
--- a/rpc/rpcevents/integration/main_test.go
+++ b/integration/rpcevents/main_test.go
@@ -15,30 +15,29 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package integration
+package rpcevents
 
 import (
 	"os"
 	"testing"
-	"time"
 
 	"github.com/hyperledger/burrow/core"
-	"github.com/hyperledger/burrow/core/integration"
-	"github.com/hyperledger/burrow/execution/pbtransactor"
+	"github.com/hyperledger/burrow/integration"
+	"github.com/hyperledger/burrow/integration/rpctest"
 )
 
-var privateAccounts = integration.MakePrivateAccounts(5) // make keys
-var genesisDoc = integration.TestGenesisDoc(privateAccounts)
-var inputAccount = &pbtransactor.InputAccount{Address: privateAccounts[0].Address().Bytes()}
+var _ = integration.ClaimPorts()
+var inputAddress = rpctest.PrivateAccounts[0].Address()
+var testConfig = integration.NewTestConfig(rpctest.GenesisDoc)
 var kern *core.Kernel
 
 // Needs to be in a _test.go file to be picked up
 func TestMain(m *testing.M) {
-	returnValue := integration.TestWrapper(privateAccounts, genesisDoc, func(k *core.Kernel) int {
-		kern = k
-		return m.Run()
-	})
+	returnValue := integration.TestWrapper(rpctest.PrivateAccounts, testConfig,
+		func(k *core.Kernel) int {
+			kern = k
+			return m.Run()
+		})
 
-	time.Sleep(3 * time.Second)
 	os.Exit(returnValue)
 }
diff --git a/rpc/rpctransactor/integration/main_test.go b/integration/rpcquery/main_test.go
similarity index 69%
rename from rpc/rpctransactor/integration/main_test.go
rename to integration/rpcquery/main_test.go
index a83a08b5158c70bc5236c3a042e1e6ceab4eb827..423a22bd5b0791222a3733bdf84e54c44d8c9b62 100644
--- a/rpc/rpctransactor/integration/main_test.go
+++ b/integration/rpcquery/main_test.go
@@ -15,28 +15,28 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package integration
+package rpcquery
 
 import (
 	"os"
 	"testing"
-	"time"
 
 	"github.com/hyperledger/burrow/core"
-	"github.com/hyperledger/burrow/core/integration"
+	"github.com/hyperledger/burrow/integration"
+	"github.com/hyperledger/burrow/integration/rpctest"
 )
 
-var privateAccounts = integration.MakePrivateAccounts(5) // make keys
-var genesisDoc = integration.TestGenesisDoc(privateAccounts)
+var _ = integration.ClaimPorts()
+var testConfig = integration.NewTestConfig(rpctest.GenesisDoc)
 var kern *core.Kernel
 
 // Needs to be in a _test.go file to be picked up
 func TestMain(m *testing.M) {
-	returnValue := integration.TestWrapper(privateAccounts, genesisDoc, func(k *core.Kernel) int {
-		kern = k
-		return m.Run()
-	})
+	returnValue := integration.TestWrapper(rpctest.PrivateAccounts, testConfig,
+		func(k *core.Kernel) int {
+			kern = k
+			return m.Run()
+		})
 
-	time.Sleep(3 * time.Second)
 	os.Exit(returnValue)
 }
diff --git a/integration/rpcquery/query_server_test.go b/integration/rpcquery/query_server_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..05bb7e858e712a2868d6da4f24a89a3b3e4a620c
--- /dev/null
+++ b/integration/rpcquery/query_server_test.go
@@ -0,0 +1,87 @@
+// +build integration
+
+package rpcquery
+
+import (
+	"context"
+	"fmt"
+	"io"
+	"testing"
+
+	"github.com/hyperledger/burrow/acm"
+	"github.com/hyperledger/burrow/event/query"
+	"github.com/hyperledger/burrow/execution/names"
+	"github.com/hyperledger/burrow/genesis"
+	"github.com/hyperledger/burrow/integration/rpctest"
+	"github.com/hyperledger/burrow/rpc/rpcquery"
+	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/require"
+)
+
+func TestGetAccount(t *testing.T) {
+	cli := rpctest.NewQueryClient(t, testConfig.RPC.GRPC.ListenAddress)
+	ca, err := cli.GetAccount(context.Background(), &rpcquery.GetAccountParam{
+		Address: rpctest.PrivateAccounts[2].Address(),
+	})
+	require.NoError(t, err)
+	genAcc := rpctest.GenesisDoc.Accounts[2]
+	genAccOut := genesis.GenesisAccountFromAccount(rpctest.GenesisDoc.Accounts[2].Name, ca.Account())
+	// Normalise
+	genAcc.Permissions.Roles = nil
+	genAccOut.Permissions.Roles = nil
+	assert.Equal(t, genAcc, genAccOut)
+}
+
+func TestListAccounts(t *testing.T) {
+	cli := rpctest.NewQueryClient(t, testConfig.RPC.GRPC.ListenAddress)
+	stream, err := cli.ListAccounts(context.Background(), &rpcquery.ListAccountsParam{})
+	require.NoError(t, err)
+	var accs []acm.Account
+	acc, err := stream.Recv()
+	for err == nil {
+		accs = append(accs, acc.Account())
+		acc, err = stream.Recv()
+	}
+	if err != nil && err != io.EOF {
+		t.Fatalf("unexpected error: %v", err)
+	}
+	assert.Len(t, accs, len(rpctest.GenesisDoc.Accounts)+1)
+}
+
+func TestListNames(t *testing.T) {
+	tcli := rpctest.NewTransactClient(t, testConfig.RPC.GRPC.ListenAddress)
+	dataA, dataB := "NO TAMBOURINES", "ELEPHANTS WELCOME"
+	n := 8
+	for i := 0; i < n; i++ {
+		name := fmt.Sprintf("Flub/%v", i)
+		if i%2 == 0 {
+			rpctest.UpdateName(t, tcli, rpctest.PrivateAccounts[0].Address(), name, dataA, 200)
+		} else {
+			rpctest.UpdateName(t, tcli, rpctest.PrivateAccounts[1].Address(), name, dataB, 200)
+		}
+	}
+	qcli := rpctest.NewQueryClient(t, testConfig.RPC.GRPC.ListenAddress)
+	entries := receiveNames(t, qcli, "")
+	assert.Len(t, entries, n)
+	entries = receiveNames(t, qcli, query.NewBuilder().AndEquals("Data", dataA).String())
+	if assert.Len(t, entries, n/2) {
+		assert.Equal(t, dataA, entries[0].Data)
+	}
+}
+
+func receiveNames(t testing.TB, qcli rpcquery.QueryClient, query string) []*names.Entry {
+	stream, err := qcli.ListNames(context.Background(), &rpcquery.ListNamesParam{
+		Query: query,
+	})
+	require.NoError(t, err)
+	var entries []*names.Entry
+	entry, err := stream.Recv()
+	for err == nil {
+		entries = append(entries, entry)
+		entry, err = stream.Recv()
+	}
+	if err != nil && err != io.EOF {
+		t.Fatalf("unexpected error: %v", err)
+	}
+	return entries
+}
diff --git a/integration/rpctest/helpers.go b/integration/rpctest/helpers.go
new file mode 100644
index 0000000000000000000000000000000000000000..9fb660f0dabf03be6e181f4b0514c43964224f28
--- /dev/null
+++ b/integration/rpctest/helpers.go
@@ -0,0 +1,188 @@
+package rpctest
+
+import (
+	"context"
+	"fmt"
+	"testing"
+
+	"github.com/hyperledger/burrow/acm"
+	"github.com/hyperledger/burrow/crypto"
+	"github.com/hyperledger/burrow/event"
+	"github.com/hyperledger/burrow/execution/evm/abi"
+	"github.com/hyperledger/burrow/execution/exec"
+	"github.com/hyperledger/burrow/execution/names"
+	"github.com/hyperledger/burrow/integration"
+	"github.com/hyperledger/burrow/rpc"
+	"github.com/hyperledger/burrow/rpc/rpcevents"
+	"github.com/hyperledger/burrow/rpc/rpcquery"
+	"github.com/hyperledger/burrow/rpc/rpctransact"
+	"github.com/hyperledger/burrow/rpc/tm/tmclient"
+	"github.com/hyperledger/burrow/txs"
+	"github.com/hyperledger/burrow/txs/payload"
+	"github.com/stretchr/testify/require"
+	"google.golang.org/grpc"
+)
+
+// Recursive call count for UpsieDownsie() function call from strange_loop.sol
+// Equals initial call, then depth from 17 -> 34, one for the bounce, then depth from 34 -> 23,
+// so... (I didn't say it had to make sense):
+const UpsieDownsieCallCount = 1 + (34 - 17) + 1 + (34 - 23)
+
+var i = UpsieDownsieCallCount
+
+var PrivateAccounts = integration.MakePrivateAccounts(10) // make keys
+var GenesisDoc = integration.TestGenesisDoc(PrivateAccounts)
+
+// Helpers
+func NewTransactClient(t testing.TB, listenAddress string) rpctransact.TransactClient {
+	conn, err := grpc.Dial(listenAddress, grpc.WithInsecure())
+	require.NoError(t, err)
+	return rpctransact.NewTransactClient(conn)
+}
+
+func NewExecutionEventsClient(t testing.TB, listenAddress string) rpcevents.ExecutionEventsClient {
+	conn, err := grpc.Dial(listenAddress, grpc.WithInsecure())
+	require.NoError(t, err)
+	return rpcevents.NewExecutionEventsClient(conn)
+}
+
+func NewQueryClient(t testing.TB, listenAddress string) rpcquery.QueryClient {
+	conn, err := grpc.Dial(listenAddress, grpc.WithInsecure())
+	require.NoError(t, err)
+	return rpcquery.NewQueryClient(conn)
+}
+
+func CommittedTxCount(t *testing.T, em event.Emitter) chan int {
+	var numTxs int32
+	emptyBlocks := 0
+	maxEmptyBlocks := 2
+	outCh := make(chan int)
+	subID := event.GenSubID()
+	ch, err := em.Subscribe(context.Background(), subID, exec.QueryForBlockExecution(), 1)
+	require.NoError(t, err)
+
+	go func() {
+		defer em.UnsubscribeAll(context.Background(), subID)
+		for msg := range ch {
+			be := msg.(*exec.BlockExecution)
+			if be.BlockHeader.NumTxs == 0 {
+				emptyBlocks++
+			} else {
+				emptyBlocks = 0
+			}
+			if emptyBlocks > maxEmptyBlocks {
+				break
+			}
+			numTxs += be.BlockHeader.NumTxs
+			fmt.Printf("Total TXs committed at block %v: %v (+%v)\n", be.Height, numTxs, be.BlockHeader.NumTxs)
+		}
+		outCh <- int(numTxs)
+	}()
+	return outCh
+}
+
+func CreateContract(t testing.TB, cli rpctransact.TransactClient, inputAddress crypto.Address) *exec.TxExecution {
+	txe, err := cli.CallTxSync(context.Background(), &payload.CallTx{
+		Input: &payload.TxInput{
+			Address: inputAddress,
+			Amount:  2,
+		},
+		Address:  nil,
+		Data:     Bytecode_strange_loop,
+		Fee:      2,
+		GasLimit: 10000,
+	})
+	require.NoError(t, err)
+	return txe
+}
+
+func CallContract(t testing.TB, cli rpctransact.TransactClient, inputAddress,
+	contractAddress crypto.Address) *exec.TxExecution {
+
+	functionID := abi.FunctionID("UpsieDownsie()")
+	txe, err := cli.CallTxSync(context.Background(), &payload.CallTx{
+		Input: &payload.TxInput{
+			Address: inputAddress,
+			Amount:  2,
+		},
+		Address:  &contractAddress,
+		Data:     functionID[:],
+		Fee:      2,
+		GasLimit: 10000,
+	})
+	require.NoError(t, err)
+	return txe
+}
+
+func UpdateName(t testing.TB, cli rpctransact.TransactClient, inputAddress crypto.Address, name, data string,
+	expiresIn uint64) *exec.TxExecution {
+
+	txe, err := cli.NameTxSync(context.Background(), &payload.NameTx{
+		Input: &payload.TxInput{
+			Address: inputAddress,
+			Amount:  names.NameCostForExpiryIn(name, data, expiresIn),
+		},
+		Name: name,
+		Data: data,
+	})
+	require.NoError(t, err)
+	return txe
+}
+
+//-------------------------------------------------------------------------------
+// some default transaction functions
+
+func MakeDefaultCallTx(t *testing.T, client tmclient.RPCClient, addr *crypto.Address, code []byte, amt, gasLim,
+	fee uint64) *txs.Envelope {
+	sequence := GetSequence(t, client, PrivateAccounts[0].Address())
+	tx := payload.NewCallTxWithSequence(PrivateAccounts[0].PublicKey(), addr, code, amt, gasLim, fee, sequence+1)
+	txEnv := txs.Enclose(GenesisDoc.ChainID(), tx)
+	require.NoError(t, txEnv.Sign(PrivateAccounts[0]))
+	return txEnv
+}
+
+//-------------------------------------------------------------------------------
+// rpc call wrappers (fail on err)
+
+// get an account's sequence number
+func GetSequence(t *testing.T, client tmclient.RPCClient, addr crypto.Address) uint64 {
+	acc, err := tmclient.GetAccount(client, addr)
+	if err != nil {
+		t.Fatal(err)
+	}
+	if acc == nil {
+		return 0
+	}
+	return acc.Sequence()
+}
+
+// get the account
+func GetAccount(t *testing.T, client tmclient.RPCClient, addr crypto.Address) acm.Account {
+	ac, err := tmclient.GetAccount(client, addr)
+	if err != nil {
+		t.Fatal(err)
+	}
+	return ac
+}
+
+// dump all storage for an account. currently unused
+func DumpStorage(t *testing.T, client tmclient.RPCClient, addr crypto.Address) *rpc.ResultDumpStorage {
+	resp, err := tmclient.DumpStorage(client, addr)
+	if err != nil {
+		t.Fatal(err)
+	}
+	return resp
+}
+
+func GetStorage(t *testing.T, client tmclient.RPCClient, addr crypto.Address, key []byte) []byte {
+	resp, err := tmclient.GetStorage(client, addr, key)
+	if err != nil {
+		t.Fatal(err)
+	}
+	return resp
+}
+
+//--------------------------------------------------------------------------------
+// utility verification function
+
+// simple call contract calls another contract
diff --git a/rpc/test/strange_loop.sol b/integration/rpctest/strange_loop.sol
similarity index 100%
rename from rpc/test/strange_loop.sol
rename to integration/rpctest/strange_loop.sol
diff --git a/rpc/test/strange_loop.sol.go b/integration/rpctest/strange_loop.sol.go
similarity index 99%
rename from rpc/test/strange_loop.sol.go
rename to integration/rpctest/strange_loop.sol.go
index 57a1f061fb43f6474291a716e6bda51d0c5f28c2..d01c57b636113bfcfb1aa5d6554dadb9ea4fbb95 100644
--- a/rpc/test/strange_loop.sol.go
+++ b/integration/rpctest/strange_loop.sol.go
@@ -1,4 +1,4 @@
-package test
+package rpctest
 
 import "github.com/tmthrgd/go-hex"
 
diff --git a/integration/rpctransact/call_test.go b/integration/rpctransact/call_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..fca4a232d37f858c09d265e7f75542a33b766666
--- /dev/null
+++ b/integration/rpctransact/call_test.go
@@ -0,0 +1,343 @@
+// +build integration
+
+package rpctransact
+
+import (
+	"context"
+	"sync"
+	"testing"
+
+	"strings"
+
+	"fmt"
+
+	"github.com/hyperledger/burrow/binary"
+	"github.com/hyperledger/burrow/crypto"
+	"github.com/hyperledger/burrow/execution/evm/asm"
+	"github.com/hyperledger/burrow/execution/evm/asm/bc"
+	"github.com/hyperledger/burrow/execution/exec"
+	"github.com/hyperledger/burrow/integration/rpctest"
+	"github.com/hyperledger/burrow/rpc/rpctransact"
+	"github.com/hyperledger/burrow/txs/payload"
+	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/require"
+)
+
+func TestCallTxNoCode(t *testing.T) {
+	cli := rpctest.NewTransactClient(t, testConfig.RPC.GRPC.ListenAddress)
+
+	// Flip flops between sending private key and input address to test private key and address based signing
+	toAddress := rpctest.PrivateAccounts[2].Address()
+
+	numCreates := 1000
+	countCh := rpctest.CommittedTxCount(t, kern.Emitter)
+	for i := 0; i < numCreates; i++ {
+		receipt, err := cli.CallTxAsync(context.Background(), &payload.CallTx{
+			Input: &payload.TxInput{
+				Address: inputAddress,
+				Amount:  2,
+			},
+			Address:  &toAddress,
+			Data:     []byte{},
+			Fee:      2,
+			GasLimit: 10000 + uint64(i),
+		})
+		require.NoError(t, err)
+		assert.False(t, receipt.CreatesContract)
+		assert.Equal(t, toAddress, receipt.ContractAddress)
+	}
+	require.Equal(t, numCreates, <-countCh)
+}
+
+func TestCreateContract(t *testing.T) {
+	cli := rpctest.NewTransactClient(t, testConfig.RPC.GRPC.ListenAddress)
+	numGoroutines := 100
+	numCreates := 50
+	wg := new(sync.WaitGroup)
+	wg.Add(numGoroutines)
+	countCh := rpctest.CommittedTxCount(t, kern.Emitter)
+	for i := 0; i < numGoroutines; i++ {
+		go func() {
+			for j := 0; j < numCreates; j++ {
+				receipt, err := cli.CallTxAsync(context.Background(), &payload.CallTx{
+					Input: &payload.TxInput{
+						Address: inputAddress,
+						Amount:  2,
+					},
+					Address:  nil,
+					Data:     rpctest.Bytecode_strange_loop,
+					Fee:      2,
+					GasLimit: 10000,
+				})
+				if assert.NoError(t, err) {
+					assert.True(t, receipt.CreatesContract)
+				}
+			}
+			wg.Done()
+		}()
+	}
+	wg.Wait()
+
+	require.Equal(t, numGoroutines*numCreates, <-countCh)
+}
+
+func BenchmarkCreateContract(b *testing.B) {
+	cli := rpctest.NewTransactClient(b, testConfig.RPC.GRPC.ListenAddress)
+	for i := 0; i < b.N; i++ {
+		create, err := cli.CallTxAsync(context.Background(), &payload.CallTx{
+			Input: &payload.TxInput{
+				Address: inputAddress,
+				Amount:  2,
+			},
+			Address:  nil,
+			Data:     rpctest.Bytecode_strange_loop,
+			Fee:      2,
+			GasLimit: 10000,
+		})
+		require.NoError(b, err)
+		assert.True(b, create.CreatesContract)
+	}
+}
+
+func TestCallTxSync(t *testing.T) {
+	cli := rpctest.NewTransactClient(t, testConfig.RPC.GRPC.ListenAddress)
+	numGoroutines := 3
+	numRuns := 2
+	countCh := rpctest.CommittedTxCount(t, kern.Emitter)
+	for i := 0; i < numGoroutines; i++ {
+		for j := 0; j < numRuns; j++ {
+			createTxe := rpctest.CreateContract(t, cli, inputAddress)
+			callTxe := rpctest.CallContract(t, cli, inputAddress, lastCall(createTxe.Events).CallData.Callee)
+			depth := binary.Uint64FromWord256(binary.LeftPadWord256(lastCall(callTxe.Events).Return))
+			// Would give 23 if taken from wrong frame (i.e. not the outer stackdepth == 0 one)
+			assert.Equal(t, 18, int(depth))
+		}
+	}
+	require.Equal(t, numGoroutines*numRuns*2, <-countCh)
+}
+
+func TestSendTxAsync(t *testing.T) {
+	cli := rpctest.NewTransactClient(t, testConfig.RPC.GRPC.ListenAddress)
+	numSends := 1000
+	countCh := rpctest.CommittedTxCount(t, kern.Emitter)
+	for i := 0; i < numSends; i++ {
+		receipt, err := cli.SendTxAsync(context.Background(), &payload.SendTx{
+			Inputs: []*payload.TxInput{{
+				Address: inputAddress,
+				Amount:  2003,
+			}},
+			Outputs: []*payload.TxOutput{{
+				Address: rpctest.PrivateAccounts[3].Address(),
+				Amount:  2003,
+			}},
+		})
+		require.NoError(t, err)
+		assert.False(t, receipt.CreatesContract)
+	}
+	require.Equal(t, numSends, <-countCh)
+}
+
+func TestCallCode(t *testing.T) {
+	cli := rpctest.NewTransactClient(t, testConfig.RPC.GRPC.ListenAddress)
+	// add two integers and return the result
+	var i, j byte = 123, 21
+	_, contractCode, expectedReturn := simpleContract(i, j)
+	txe, err := cli.CallCodeSim(context.Background(), &rpctransact.CallCodeParam{
+		FromAddress: inputAddress,
+		Code:        contractCode,
+	})
+	require.NoError(t, err)
+	assert.Equal(t, expectedReturn, txe.Result.Return)
+
+	// pass two ints as calldata, add, and return the result
+	txe, err = cli.CallCodeSim(context.Background(), &rpctransact.CallCodeParam{
+		FromAddress: inputAddress,
+		Code: bc.MustSplice(asm.PUSH1, 0x0, asm.CALLDATALOAD, asm.PUSH1, 0x20, asm.CALLDATALOAD, asm.ADD, asm.PUSH1,
+			0x0, asm.MSTORE, asm.PUSH1, 0x20, asm.PUSH1, 0x0, asm.RETURN),
+		Data: bc.MustSplice(binary.LeftPadWord256([]byte{i}), binary.LeftPadWord256([]byte{j})),
+	})
+	require.NoError(t, err)
+	assert.Equal(t, expectedReturn, txe.Result.Return)
+}
+
+func TestCallContract(t *testing.T) {
+	initCode, _, expectedReturn := simpleContract(43, 1)
+	cli := rpctest.NewTransactClient(t, testConfig.RPC.GRPC.ListenAddress)
+	txe, err := cli.CallTxSync(context.Background(), &payload.CallTx{
+		Input: &payload.TxInput{
+			Address: inputAddress,
+			Amount:  uint64(6969),
+		},
+		Address:  nil,
+		Data:     initCode,
+		Fee:      uint64(1000),
+		GasLimit: uint64(1000),
+	})
+	require.NoError(t, err)
+	assert.Equal(t, true, txe.Receipt.CreatesContract, "This transaction should"+
+		" create a contract")
+	assert.NotEqual(t, 0, len(txe.TxHash), "Receipt should contain a"+
+		" transaction hash")
+	contractAddress := txe.Receipt.ContractAddress
+	assert.NotEqual(t, 0, len(contractAddress), "Transactions claims to have"+
+		" created a contract but the contract address is empty")
+
+	txe, err = cli.CallTxSync(context.Background(), &payload.CallTx{
+		Input: &payload.TxInput{
+			Address: inputAddress,
+			Amount:  uint64(6969),
+		},
+		Address:  &contractAddress,
+		Fee:      uint64(1000),
+		GasLimit: uint64(1000),
+	})
+	require.NoError(t, err)
+
+	assert.Equal(t, expectedReturn, txe.Result.Return)
+}
+
+// create two contracts, one of which calls the other
+func TestNestedCall(t *testing.T) {
+	code, _, expectedReturn := simpleContract(5, 6)
+
+	// Deploy callee contract
+	cli := rpctest.NewTransactClient(t, testConfig.RPC.GRPC.ListenAddress)
+	txe, err := cli.CallTxSync(context.Background(), &payload.CallTx{
+		Input: &payload.TxInput{
+			Address: inputAddress,
+			Amount:  uint64(6969),
+		},
+		Data:     code,
+		GasLimit: 10000,
+	})
+	require.NoError(t, err)
+	assert.True(t, txe.Receipt.CreatesContract)
+	calleeContractAddress := txe.Receipt.ContractAddress
+
+	// Deploy caller contract
+	code, _, _ = simpleCallContract(calleeContractAddress)
+	txe, err = cli.CallTxSync(context.Background(), &payload.CallTx{
+		Input: &payload.TxInput{
+			Address: inputAddress,
+			Amount:  uint64(6969),
+		},
+		Data:     code,
+		GasLimit: 10000,
+	})
+	require.NoError(t, err)
+	assert.True(t, txe.Receipt.CreatesContract)
+	callerContractAddress := txe.Receipt.ContractAddress
+
+	// Call caller contract
+	txe, err = cli.CallTxSync(context.Background(), &payload.CallTx{
+		Input: &payload.TxInput{
+			Address: inputAddress,
+			Amount:  uint64(6969),
+		},
+		Address:  &callerContractAddress,
+		GasLimit: 10000,
+	})
+	require.NoError(t, err)
+	assert.Equal(t, expectedReturn, txe.Result.Return)
+}
+
+func TestCallEvents(t *testing.T) {
+	cli := rpctest.NewTransactClient(t, testConfig.RPC.GRPC.ListenAddress)
+	createTxe := rpctest.CreateContract(t, cli, inputAddress)
+	address := lastCall(createTxe.Events).CallData.Callee
+	callTxe := rpctest.CallContract(t, cli, inputAddress, address)
+	callEvents := filterCalls(callTxe.Events)
+	require.Len(t, callEvents, rpctest.UpsieDownsieCallCount, "should see 30 recursive call events")
+	for i, ev := range callEvents {
+		assert.Equal(t, uint64(rpctest.UpsieDownsieCallCount-i-1), ev.StackDepth)
+	}
+}
+
+func TestLogEvents(t *testing.T) {
+	cli := rpctest.NewTransactClient(t, testConfig.RPC.GRPC.ListenAddress)
+	createTxe := rpctest.CreateContract(t, cli, inputAddress)
+	address := lastCall(createTxe.Events).CallData.Callee
+	callTxe := rpctest.CallContract(t, cli, inputAddress, address)
+	evs := filterLogs(callTxe.Events)
+	require.Len(t, evs, rpctest.UpsieDownsieCallCount-2)
+	log := evs[0]
+	depth := binary.Int64FromWord256(log.Topics[2])
+	direction := strings.TrimRight(string(log.Topics[1][:]), "\x00")
+	assert.Equal(t, int64(18), depth)
+	assert.Equal(t, "Upsie!", direction)
+}
+
+func filterCalls(evs []*exec.Event) []*exec.CallEvent {
+	var callEvs []*exec.CallEvent
+	for _, ev := range evs {
+		if ev.Call != nil {
+			callEvs = append(callEvs, ev.Call)
+		}
+	}
+	return callEvs
+}
+
+func filterLogs(evs []*exec.Event) []*exec.LogEvent {
+	var logEvs []*exec.LogEvent
+	for _, ev := range evs {
+		if ev.Log != nil {
+			logEvs = append(logEvs, ev.Log)
+		}
+	}
+	return logEvs
+}
+
+func lastCall(evs []*exec.Event) *exec.CallEvent {
+	callEvs := filterCalls(evs)
+	return callEvs[len(callEvs)-1]
+}
+
+func TestName(t *testing.T) {
+	initcode, contractcode, returncode := simpleContract(5, 6)
+	fmt.Println(asm.OpCode(0x7f).Name(), initcode, contractcode, returncode)
+
+}
+
+// simple contract returns 5 + 6 = 0xb
+func simpleContract(i, j byte) ([]byte, []byte, []byte) {
+	// this is the code we want to run when the contract is called
+	contractCode := bc.MustSplice(asm.PUSH1, i, asm.PUSH1, j, asm.ADD, asm.PUSH1, 0x0, asm.MSTORE, asm.PUSH1, 0x20, asm.PUSH1,
+		0x0, asm.RETURN)
+	// the is the code we need to return the contractCode when the contract is initialized
+	lenCode := len(contractCode)
+	// push code to the stack
+	initCode := bc.MustSplice(asm.PUSH32, binary.RightPadWord256(contractCode),
+		// store it in memory
+		asm.PUSH1, 0x0, asm.MSTORE,
+		// return whats in memory
+		asm.PUSH1, lenCode, asm.PUSH1, 0x0, asm.RETURN)
+	// return init code, contract code, expected return
+	return initCode, contractCode, binary.LeftPadBytes([]byte{i + j}, 32)
+}
+
+func simpleCallContract(address crypto.Address) ([]byte, []byte, []byte) {
+	gas1, gas2 := byte(0x1), byte(0x1)
+	value := byte(0x1)
+	inOff, inSize := byte(0x0), byte(0x0) // no call data
+	retOff, retSize := byte(0x0), byte(0x20)
+	// this is the code we want to run (call a contract and return)
+	contractCode := []byte{0x60, retSize, 0x60, retOff, 0x60, inSize, 0x60, inOff,
+		0x60, value, 0x73}
+	contractCode = append(contractCode, address.Bytes()...)
+	contractCode = append(contractCode, []byte{0x61, gas1, gas2, 0xf1, 0x60, 0x20,
+		0x60, 0x0, 0xf3}...)
+
+	// the is the code we need to return; the contractCode when the contract is initialized
+	// it should copy the code from the input into memory
+	lenCode := len(contractCode)
+	memOff := byte(0x0)
+	inOff = byte(0xc) // length of code before codeContract
+	length := byte(lenCode)
+
+	code := []byte{0x60, length, 0x60, inOff, 0x60, memOff, 0x37}
+	// return whats in memory
+	code = append(code, []byte{0x60, byte(lenCode), 0x60, 0x0, 0xf3}...)
+	code = append(code, contractCode...)
+	// return init code, contract code, expected return
+	return code, contractCode, binary.LeftPadBytes([]byte{0xb}, 32)
+}
diff --git a/rpc/v0/integration/main_test.go b/integration/rpctransact/main_test.go
similarity index 69%
rename from rpc/v0/integration/main_test.go
rename to integration/rpctransact/main_test.go
index a83a08b5158c70bc5236c3a042e1e6ceab4eb827..bda89290e649e0046a1564904829e1072ffee103 100644
--- a/rpc/v0/integration/main_test.go
+++ b/integration/rpctransact/main_test.go
@@ -15,28 +15,28 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package integration
+package rpctransact
 
 import (
 	"os"
 	"testing"
-	"time"
 
 	"github.com/hyperledger/burrow/core"
-	"github.com/hyperledger/burrow/core/integration"
+	"github.com/hyperledger/burrow/integration"
+	"github.com/hyperledger/burrow/integration/rpctest"
 )
 
-var privateAccounts = integration.MakePrivateAccounts(5) // make keys
-var genesisDoc = integration.TestGenesisDoc(privateAccounts)
+var _ = integration.ClaimPorts()
+var testConfig = integration.NewTestConfig(rpctest.GenesisDoc)
 var kern *core.Kernel
 
 // Needs to be in a _test.go file to be picked up
 func TestMain(m *testing.M) {
-	returnValue := integration.TestWrapper(privateAccounts, genesisDoc, func(k *core.Kernel) int {
-		kern = k
-		return m.Run()
-	})
+	returnValue := integration.TestWrapper(rpctest.PrivateAccounts, testConfig,
+		func(k *core.Kernel) int {
+			kern = k
+			return m.Run()
+		})
 
-	time.Sleep(3 * time.Second)
 	os.Exit(returnValue)
 }
diff --git a/integration/rpctransact/name_test.go b/integration/rpctransact/name_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..3ba4a77f5bdebbf4953a8534d32528de00a32984
--- /dev/null
+++ b/integration/rpctransact/name_test.go
@@ -0,0 +1,117 @@
+// +build integration
+
+package rpctransact
+
+import (
+	"context"
+	"testing"
+
+	"github.com/hyperledger/burrow/event"
+	"github.com/hyperledger/burrow/execution/exec"
+	"github.com/hyperledger/burrow/execution/names"
+	"github.com/hyperledger/burrow/integration/rpctest"
+	"github.com/hyperledger/burrow/rpc/rpcquery"
+	"github.com/hyperledger/burrow/txs/payload"
+	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/require"
+)
+
+func TestNameTxSync(t *testing.T) {
+	cli := rpctest.NewTransactClient(t, testConfig.RPC.GRPC.ListenAddress)
+	name := "Flub"
+	data := "floooo"
+	expiresIn := uint64(100)
+	_, err := cli.NameTxSync(context.Background(), &payload.NameTx{
+		Input: &payload.TxInput{
+			Address: inputAddress,
+			Amount:  names.NameCostForExpiryIn(name, data, expiresIn),
+		},
+		Name: name,
+		Data: data,
+	})
+	require.NoError(t, err)
+
+	qcli := rpctest.NewQueryClient(t, testConfig.RPC.GRPC.ListenAddress)
+	entry, err := qcli.GetName(context.Background(), &rpcquery.GetNameParam{
+		Name: name,
+	})
+	require.NoError(t, err)
+	assert.Equal(t, name, entry.Name)
+	assert.Equal(t, data, entry.Data)
+	assert.Equal(t, inputAddress, entry.Owner)
+	assert.True(t, entry.Expires >= expiresIn, "expiry should be later than expiresIn")
+}
+
+func TestNameReg(t *testing.T) {
+	tcli := rpctest.NewTransactClient(t, testConfig.RPC.GRPC.ListenAddress)
+	qcli := rpctest.NewQueryClient(t, testConfig.RPC.GRPC.ListenAddress)
+	names.MinNameRegistrationPeriod = 1
+
+	// register a new name, check if its there
+	// since entries ought to be unique and these run against different clients, we append the client
+	name := "ye_old_domain_name"
+	const data = "if not now, when"
+	numDesiredBlocks := uint64(2)
+
+	txe := rpctest.UpdateName(t, tcli, inputAddress, name, data, numDesiredBlocks)
+
+	entry := txe.Result.NameEntry
+	assert.NotNil(t, entry, "name shoudl return")
+	_, ok := txe.Envelope.Tx.Payload.(*payload.NameTx)
+	require.True(t, ok, "should be NameTx: %v", txe.Envelope.Tx.Payload)
+
+	assert.Equal(t, name, entry.Name)
+	assert.Equal(t, data, entry.Data)
+
+	entryQuery, err := qcli.GetName(context.Background(), &rpcquery.GetNameParam{Name: name})
+	require.NoError(t, err)
+
+	assert.Equal(t, entry, entryQuery)
+
+	// update the data as the owner, make sure still there
+	numDesiredBlocks = uint64(3)
+	const updatedData = "these are amongst the things I wish to bestow upon " +
+		"the youth of generations come: a safe supply of honey, and a better " +
+		"money. For what else shall they need"
+	rpctest.UpdateName(t, tcli, inputAddress, name, updatedData, numDesiredBlocks)
+
+	entry, err = qcli.GetName(context.Background(), &rpcquery.GetNameParam{Name: name})
+	require.NoError(t, err)
+
+	assert.Equal(t, updatedData, entry.Data)
+
+	// try to update as non owner, should fail
+	txe, err = tcli.NameTxSync(context.Background(), &payload.NameTx{
+		Input: &payload.TxInput{
+			Address: rpctest.PrivateAccounts[1].Address(),
+			Amount:  names.NameCostForExpiryIn(name, data, numDesiredBlocks),
+		},
+		Name: name,
+		Data: "flub flub floo",
+	})
+	require.Error(t, err, "updating as non-owner on non-expired name should fail")
+	assert.Contains(t, err.Error(), "permission denied")
+
+	waitNBlocks(t, numDesiredBlocks)
+	//now the entry should be expired, so we can update as non owner
+	const data2 = "this is not my beautiful house"
+	owner := rpctest.PrivateAccounts[3].Address()
+	txe = rpctest.UpdateName(t, tcli, owner, name, data2, numDesiredBlocks)
+	entry = txe.Result.NameEntry
+
+	entryQuery, err = qcli.GetName(context.Background(), &rpcquery.GetNameParam{Name: name})
+	require.NoError(t, err)
+	assert.Equal(t, entry, entryQuery)
+	assert.Equal(t, data2, entry.Data)
+	assert.Equal(t, owner, entry.Owner)
+}
+
+func waitNBlocks(t testing.TB, n uint64) {
+	subID := event.GenSubID()
+	ch, err := kern.Emitter.Subscribe(context.Background(), subID, exec.QueryForBlockExecution(), 10)
+	require.NoError(t, err)
+	defer kern.Emitter.UnsubscribeAll(context.Background(), subID)
+	for i := uint64(0); i < n; i++ {
+		<-ch
+	}
+}
diff --git a/integration/rpctransact/send_test.go b/integration/rpctransact/send_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..4b465dbc9d9cc922bc6d7f65ad17e175ba110700
--- /dev/null
+++ b/integration/rpctransact/send_test.go
@@ -0,0 +1,31 @@
+// +build integration
+
+package rpctransact
+
+import (
+	"context"
+	"testing"
+
+	"github.com/hyperledger/burrow/integration/rpctest"
+	"github.com/hyperledger/burrow/txs/payload"
+	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/require"
+)
+
+func TestSendTxSync(t *testing.T) {
+	cli := rpctest.NewTransactClient(t, testConfig.RPC.GRPC.ListenAddress)
+	for i := 0; i < 2; i++ {
+		txe, err := cli.SendTxSync(context.Background(), &payload.SendTx{
+			Inputs: []*payload.TxInput{{
+				Address: inputAddress,
+				Amount:  2003,
+			}},
+			Outputs: []*payload.TxOutput{{
+				Address: rpctest.PrivateAccounts[3].Address(),
+				Amount:  2003,
+			}},
+		})
+		require.NoError(t, err)
+		assert.False(t, txe.Receipt.CreatesContract)
+	}
+}
diff --git a/integration/rpctransact/transact_server_test.go b/integration/rpctransact/transact_server_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..6ab30c545161e70bafbab0efaf558776399e8a23
--- /dev/null
+++ b/integration/rpctransact/transact_server_test.go
@@ -0,0 +1,109 @@
+// +build integration
+
+// Space above here matters
+// Copyright 2017 Monax Industries Limited
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package rpctransact
+
+import (
+	"context"
+	"fmt"
+	"testing"
+
+	"time"
+
+	"github.com/hyperledger/burrow/execution/exec"
+	"github.com/hyperledger/burrow/integration/rpctest"
+	"github.com/hyperledger/burrow/rpc/rpcevents"
+	"github.com/hyperledger/burrow/rpc/rpcquery"
+	"github.com/hyperledger/burrow/rpc/rpctransact"
+	"github.com/hyperledger/burrow/txs"
+	"github.com/hyperledger/burrow/txs/payload"
+	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/require"
+)
+
+var inputAccount = rpctest.PrivateAccounts[0]
+var inputAddress = inputAccount.Address()
+
+func TestBroadcastTxLocallySigned(t *testing.T) {
+	qcli := rpctest.NewQueryClient(t, testConfig.RPC.GRPC.ListenAddress)
+	acc, err := qcli.GetAccount(context.Background(), &rpcquery.GetAccountParam{
+		Address: inputAddress,
+	})
+	require.NoError(t, err)
+	amount := uint64(2123)
+	txEnv := txs.Enclose(rpctest.GenesisDoc.ChainID(), &payload.SendTx{
+		Inputs: []*payload.TxInput{{
+			Address:  inputAddress,
+			Sequence: acc.Sequence + 1,
+			Amount:   amount,
+		}},
+		Outputs: []*payload.TxOutput{{
+			Address: rpctest.PrivateAccounts[1].Address(),
+			Amount:  amount,
+		}},
+	})
+	require.NoError(t, txEnv.Sign(inputAccount))
+
+	// Test subscribing to transaction before sending it
+	ch := make(chan *exec.TxExecution)
+	go func() {
+		ecli := rpctest.NewExecutionEventsClient(t, testConfig.RPC.GRPC.ListenAddress)
+		txe, err := ecli.GetTx(context.Background(), &rpcevents.GetTxRequest{
+			TxHash: txEnv.Tx.Hash(),
+			Wait:   true,
+		})
+		require.NoError(t, err)
+		ch <- txe
+	}()
+
+	// Make it wait
+	time.Sleep(time.Second)
+
+	// No broadcast
+	cli := rpctest.NewTransactClient(t, testConfig.RPC.GRPC.ListenAddress)
+	receipt, err := cli.BroadcastTxAsync(context.Background(), &rpctransact.TxEnvelopeParam{Envelope: txEnv})
+	require.NoError(t, err)
+	assert.False(t, receipt.CreatesContract, "This tx should not create a contract")
+	require.NotEmpty(t, receipt.TxHash, "Failed to compute tx hash")
+	assert.Equal(t, txEnv.Tx.Hash(), receipt.TxHash)
+
+	txe := <-ch
+	require.True(t, len(txe.Events) > 0)
+	assert.NotNil(t, txe.Events[0].Input)
+}
+
+func TestFormulateTx(t *testing.T) {
+	cli := rpctest.NewTransactClient(t, testConfig.RPC.GRPC.ListenAddress)
+	txEnv, err := cli.FormulateTx(context.Background(), &rpctransact.PayloadParam{
+		CallTx: &payload.CallTx{
+			Input: &payload.TxInput{
+				Address: inputAddress,
+				Amount:  230,
+			},
+			Data: []byte{2, 3, 6, 4, 3},
+		},
+	})
+	require.NoError(t, err)
+	bs, err := txEnv.Marshal()
+	require.NoError(t, err)
+	// We should see the sign bytes embedded
+	if !assert.Contains(t, string(bs), fmt.Sprintf("{\"ChainID\":\"%s\",\"Type\":\"CallTx\","+
+		"\"Payload\":{\"Input\":{\"Address\":\"4A6DFB649EF0D50780998A686BD69AB175C08E26\",\"Amount\":230},"+
+		"\"Data\":\"0203060403\"}}", rpctest.GenesisDoc.ChainID())) {
+		fmt.Println(string(bs))
+	}
+}
diff --git a/integration/tm/main_test.go b/integration/tm/main_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..cdee8c090e6460240c21842b944fc1116daf8f4d
--- /dev/null
+++ b/integration/tm/main_test.go
@@ -0,0 +1,49 @@
+// +build integration
+
+// Space above here matters
+// Copyright 2017 Monax Industries Limited
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package tm
+
+import (
+	"os"
+	"testing"
+
+	"github.com/hyperledger/burrow/core"
+	"github.com/hyperledger/burrow/integration"
+	"github.com/hyperledger/burrow/integration/rpctest"
+	rpcClient "github.com/hyperledger/burrow/rpc/lib/client"
+	tmClient "github.com/hyperledger/burrow/rpc/tm/tmclient"
+)
+
+var kern *core.Kernel
+var _ = integration.ClaimPorts()
+var testConfig = integration.NewTestConfig(rpctest.GenesisDoc)
+var jsonRpcClient = rpcClient.NewJSONRPCClient(testConfig.RPC.TM.ListenAddress)
+var httpClient = rpcClient.NewURIClient(testConfig.RPC.TM.ListenAddress)
+var clients = map[string]tmClient.RPCClient{
+	"JSONRPC": jsonRpcClient,
+	"HTTP":    httpClient,
+}
+
+// Needs to be in a _test.go file to be picked up
+func TestMain(m *testing.M) {
+	returnValue := integration.TestWrapper(rpctest.PrivateAccounts, testConfig, func(k *core.Kernel) int {
+		kern = k
+		return m.Run()
+	})
+
+	os.Exit(returnValue)
+}
diff --git a/integration/tm/tm_server_test.go b/integration/tm/tm_server_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..09ce3b5815876e70f2018ea31c54b955c0e7532b
--- /dev/null
+++ b/integration/tm/tm_server_test.go
@@ -0,0 +1,224 @@
+// +build integration
+
+// Space above here matters
+// Copyright 2017 Monax Industries Limited
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package tm
+
+import (
+	"context"
+	"fmt"
+	"strings"
+	"testing"
+	"time"
+
+	"github.com/hyperledger/burrow/binary"
+	"github.com/hyperledger/burrow/event"
+	"github.com/hyperledger/burrow/execution/exec"
+	"github.com/hyperledger/burrow/integration/rpctest"
+	"github.com/hyperledger/burrow/rpc/rpctransact"
+	"github.com/hyperledger/burrow/rpc/tm/tmclient"
+	"github.com/hyperledger/burrow/txs"
+	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/require"
+	"github.com/tendermint/tendermint/consensus/types"
+)
+
+const timeout = 5 * time.Second
+
+func testWithAllClients(t *testing.T, testFunction func(*testing.T, string, tmclient.RPCClient)) {
+	for clientName, client := range clients {
+		testFunction(t, clientName, client)
+	}
+}
+
+//--------------------------------------------------------------------------------
+func TestStatus(t *testing.T) {
+	testWithAllClients(t, func(t *testing.T, clientName string, client tmclient.RPCClient) {
+		resp, err := tmclient.Status(client)
+		assert.NoError(t, err)
+		assert.Equal(t, rpctest.GenesisDoc.ChainID(), resp.NodeInfo.Network,
+			"ChainID should match NodeInfo.Network")
+	})
+}
+
+func TestGetAccount(t *testing.T) {
+	if testing.Short() {
+		t.Skip("skipping test in short mode.")
+	}
+	testWithAllClients(t, func(t *testing.T, clientName string, client tmclient.RPCClient) {
+		acc := rpctest.GetAccount(t, client, rpctest.PrivateAccounts[0].Address())
+		if acc == nil {
+			t.Fatal("Account was nil")
+		}
+		if acc.Address() != rpctest.PrivateAccounts[0].Address() {
+			t.Fatalf("Failed to get correct account. Got %s, expected %s", acc.Address(),
+				rpctest.PrivateAccounts[0].Address())
+		}
+	})
+}
+
+func TestGetStorage(t *testing.T) {
+	if testing.Short() {
+		t.Skip("skipping test in short mode.")
+	}
+	testWithAllClients(t, func(t *testing.T, clientName string, client tmclient.RPCClient) {
+		amt, gasLim, fee := uint64(1100), uint64(1000), uint64(1000)
+		code := []byte{0x60, 0x5, 0x60, 0x1, 0x55}
+		// Call with nil address will create a contract
+		tx := rpctest.MakeDefaultCallTx(t, client, nil, code, amt, gasLim, fee)
+		txe := broadcastTxSync(t, tx)
+		assert.Equal(t, true, txe.Receipt.CreatesContract, "This transaction should"+
+			" create a contract")
+		assert.NotEqual(t, 0, len(txe.TxHash), "Receipt should contain a"+
+			" transaction hash")
+		contractAddr := txe.Receipt.ContractAddress
+		assert.NotEqual(t, 0, len(contractAddr), "Transactions claims to have"+
+			" created a contract but the contract address is empty")
+
+		v := rpctest.GetStorage(t, client, contractAddr, []byte{0x1})
+		got := binary.LeftPadWord256(v)
+		expected := binary.LeftPadWord256([]byte{0x5})
+		if got.Compare(expected) != 0 {
+			t.Fatalf("Wrong storage value. Got %x, expected %x", got.Bytes(),
+				expected.Bytes())
+		}
+	})
+}
+
+func TestWaitBlocks(t *testing.T) {
+	waitNBlocks(t, 5)
+}
+
+func TestBlockchainInfo(t *testing.T) {
+	testWithAllClients(t, func(t *testing.T, clientName string, client tmclient.RPCClient) {
+		// wait a mimimal number of blocks to ensure that the later query for block
+		// headers has a non-trivial length
+		nBlocks := 4
+		waitNBlocks(t, nBlocks)
+
+		resp, err := tmclient.ListBlocks(client, 0, 0)
+		if err != nil {
+			t.Fatalf("Failed to get blockchain info: %v", err)
+		}
+		lastBlockHeight := resp.LastHeight
+		nMetaBlocks := len(resp.BlockMetas)
+		assert.True(t, uint64(nMetaBlocks) <= lastBlockHeight,
+			"Logically number of block metas should be equal or less than block height.")
+		assert.True(t, nBlocks <= len(resp.BlockMetas),
+			"Should see at least %v BlockMetas after waiting for %v blocks but saw %v",
+			nBlocks, nBlocks, len(resp.BlockMetas))
+		// For the maximum number (default to 20) of retrieved block headers,
+		// check that they correctly chain to each other.
+		lastBlockHash := resp.BlockMetas[nMetaBlocks-1].Header.Hash()
+		for i := nMetaBlocks - 2; i >= 0; i-- {
+			// the blockhash in header of height h should be identical to the hash
+			// in the LastBlockID of the header of block height h+1.
+			assert.Equal(t, lastBlockHash, resp.BlockMetas[i].Header.LastBlockID.Hash,
+				"Blockchain should be a hash tree!")
+			lastBlockHash = resp.BlockMetas[i].Header.Hash()
+		}
+
+		// Now retrieve only two blockheaders (h=1, and h=2) and check that we got
+		// two results.
+		resp, err = tmclient.ListBlocks(client, 1, 2)
+		assert.NoError(t, err)
+		assert.Equal(t, 2, len(resp.BlockMetas),
+			"Should see 2 BlockMetas after extracting 2 blocks")
+	})
+}
+
+func TestListUnconfirmedTxs(t *testing.T) {
+	if testing.Short() {
+		t.Skip("skipping test in short mode.")
+	}
+	testWithAllClients(t, func(t *testing.T, clientName string, client tmclient.RPCClient) {
+		amt, gasLim, fee := uint64(1100), uint64(1000), uint64(1000)
+		code := []byte{0x60, 0x5, 0x60, 0x1, 0x55}
+		// Call with nil address will create a contract
+		txEnv := rpctest.MakeDefaultCallTx(t, client, nil, code, amt, gasLim, fee)
+		txChan := make(chan []*txs.Envelope)
+
+		// We want to catch the Tx in mempool before it gets reaped by tendermint
+		// consensus. We should be able to do this almost always if we broadcast our
+		// transaction immediately after a block has been committed. There is about
+		// 1 second between blocks, and we will have the lock on Reap
+		// So we wait for a block here
+		waitNBlocks(t, 1)
+
+		go func() {
+			for {
+				resp, err := tmclient.ListUnconfirmedTxs(client, -1)
+				if err != nil {
+					// We get an error on exit
+					return
+				}
+				if resp.NumTxs > 0 {
+					txChan <- resp.Txs
+				}
+			}
+		}()
+
+		broadcastTxSync(t, txEnv)
+		select {
+		case <-time.After(time.Second * timeout):
+			t.Fatal("Timeout out waiting for unconfirmed transactions to appear")
+		case transactions := <-txChan:
+			assert.Len(t, transactions, 1, "There should only be a single transaction in the "+
+				"mempool during this test (previous txs should have made it into a block)")
+			assert.Contains(t, transactions, txEnv, "Transaction should be returned by ListUnconfirmedTxs")
+		}
+	})
+}
+
+func TestListValidators(t *testing.T) {
+	testWithAllClients(t, func(t *testing.T, clientName string, client tmclient.RPCClient) {
+		resp, err := tmclient.ListValidators(client)
+		assert.NoError(t, err)
+		assert.Len(t, resp.BondedValidators, 1)
+		validator := resp.BondedValidators[0]
+		assert.Equal(t, rpctest.GenesisDoc.Validators[0].PublicKey, validator.PublicKey)
+	})
+}
+
+func TestDumpConsensusState(t *testing.T) {
+	startTime := time.Now()
+	testWithAllClients(t, func(t *testing.T, clientName string, client tmclient.RPCClient) {
+		resp, err := tmclient.DumpConsensusState(client)
+		assert.NoError(t, err)
+		assert.NotZero(t, startTime)
+		assert.Equal(t, fmt.Sprintf("/0/%d", types.RoundStepNewHeight),
+			strings.TrimLeft(resp.RoundState.HeightRoundStep, "0123456789"))
+	})
+}
+
+func waitNBlocks(t testing.TB, n int) {
+	subID := event.GenSubID()
+	ch, err := kern.Emitter.Subscribe(context.Background(), subID, exec.QueryForBlockExecution(), 10)
+	require.NoError(t, err)
+	defer kern.Emitter.UnsubscribeAll(context.Background(), subID)
+	for i := 0; i < n; i++ {
+		<-ch
+	}
+}
+
+func broadcastTxSync(t testing.TB, txEnv *txs.Envelope) *exec.TxExecution {
+	cli := rpctest.NewTransactClient(t, testConfig.RPC.GRPC.ListenAddress)
+	txe, err := cli.BroadcastTxSync(context.Background(), &rpctransact.TxEnvelopeParam{
+		Envelope: txEnv,
+	})
+	require.NoError(t, err)
+	return txe
+}
diff --git a/keys/key_client.go b/keys/key_client.go
index bae1d0ae70d4cf987f856204b96f8e0d465dbb8a..ae6a92c7aef1a8bff974be885f0a513d2f157ac7 100644
--- a/keys/key_client.go
+++ b/keys/key_client.go
@@ -20,7 +20,6 @@ import (
 	"time"
 
 	"github.com/hyperledger/burrow/crypto"
-	"github.com/hyperledger/burrow/keys/pbkeys"
 	"github.com/hyperledger/burrow/logging"
 	"google.golang.org/grpc"
 )
@@ -49,16 +48,16 @@ type localKeyClient struct {
 
 type remoteKeyClient struct {
 	rpcAddress string
-	kc         pbkeys.KeysClient
+	kc         KeysClient
 	logger     *logging.Logger
 }
 
 func (l *localKeyClient) Sign(signAddress crypto.Address, message []byte) (signature crypto.Signature, err error) {
-	resp, err := l.ks.Sign(nil, &pbkeys.SignRequest{Address: signAddress.String(), Message: message})
+	resp, err := l.ks.Sign(nil, &SignRequest{Address: signAddress.String(), Message: message})
 	if err != nil {
 		return crypto.Signature{}, err
 	}
-	curveType, err := crypto.CurveTypeFromString(resp.GetCurvetype())
+	curveType, err := crypto.CurveTypeFromString(resp.GetCurveType())
 	if err != nil {
 		return crypto.Signature{}, err
 	}
@@ -66,20 +65,20 @@ func (l *localKeyClient) Sign(signAddress crypto.Address, message []byte) (signa
 }
 
 func (l *localKeyClient) PublicKey(address crypto.Address) (publicKey crypto.PublicKey, err error) {
-	resp, err := l.ks.PublicKey(nil, &pbkeys.PubRequest{Address: address.String()})
+	resp, err := l.ks.PublicKey(nil, &PubRequest{Address: address.String()})
 	if err != nil {
 		return crypto.PublicKey{}, err
 	}
-	curveType, err := crypto.CurveTypeFromString(resp.GetCurvetype())
+	curveType, err := crypto.CurveTypeFromString(resp.GetCurveType())
 	if err != nil {
 		return crypto.PublicKey{}, err
 	}
-	return crypto.PublicKeyFromBytes(resp.GetPub(), curveType)
+	return crypto.PublicKeyFromBytes(resp.GetPublicKey(), curveType)
 }
 
 // Generate requests that a key be generate within the keys instance and returns the address
 func (l *localKeyClient) Generate(keyName string, curveType crypto.CurveType) (keyAddress crypto.Address, err error) {
-	resp, err := l.ks.GenerateKey(nil, &pbkeys.GenRequest{Keyname: keyName, Curvetype: curveType.String()})
+	resp, err := l.ks.GenerateKey(nil, &GenRequest{KeyName: keyName, CurveType: curveType.String()})
 	if err != nil {
 		return crypto.Address{}, err
 	}
@@ -94,7 +93,7 @@ func (l *localKeyClient) HealthCheck() error {
 func (l *remoteKeyClient) Sign(signAddress crypto.Address, message []byte) (signature crypto.Signature, err error) {
 	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
 	defer cancel()
-	req := pbkeys.SignRequest{Address: signAddress.String(), Message: message}
+	req := SignRequest{Address: signAddress.String(), Message: message}
 	l.logger.TraceMsg("Sending Sign request to remote key server: ", fmt.Sprintf("%v", req))
 	resp, err := l.kc.Sign(ctx, &req)
 	if err != nil {
@@ -102,7 +101,7 @@ func (l *remoteKeyClient) Sign(signAddress crypto.Address, message []byte) (sign
 		return crypto.Signature{}, err
 	}
 	l.logger.TraceMsg("Received Sign response to remote key server: %v", resp)
-	curveType, err := crypto.CurveTypeFromString(resp.GetCurvetype())
+	curveType, err := crypto.CurveTypeFromString(resp.GetCurveType())
 	if err != nil {
 		return crypto.Signature{}, err
 	}
@@ -112,26 +111,26 @@ func (l *remoteKeyClient) Sign(signAddress crypto.Address, message []byte) (sign
 func (l *remoteKeyClient) PublicKey(address crypto.Address) (publicKey crypto.PublicKey, err error) {
 	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
 	defer cancel()
-	req := pbkeys.PubRequest{Address: address.String()}
+	req := PubRequest{Address: address.String()}
 	l.logger.TraceMsg("Sending PublicKey request to remote key server: ", fmt.Sprintf("%v", req))
 	resp, err := l.kc.PublicKey(ctx, &req)
 	if err != nil {
 		l.logger.TraceMsg("Received PublicKey error response: ", err)
 		return crypto.PublicKey{}, err
 	}
-	curveType, err := crypto.CurveTypeFromString(resp.GetCurvetype())
+	curveType, err := crypto.CurveTypeFromString(resp.GetCurveType())
 	if err != nil {
 		return crypto.PublicKey{}, err
 	}
 	l.logger.TraceMsg("Received PublicKey response to remote key server: ", fmt.Sprintf("%v", resp))
-	return crypto.PublicKeyFromBytes(resp.GetPub(), curveType)
+	return crypto.PublicKeyFromBytes(resp.GetPublicKey(), curveType)
 }
 
 // Generate requests that a key be generate within the keys instance and returns the address
 func (l *remoteKeyClient) Generate(keyName string, curveType crypto.CurveType) (keyAddress crypto.Address, err error) {
 	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
 	defer cancel()
-	req := pbkeys.GenRequest{Keyname: keyName, Curvetype: curveType.String()}
+	req := GenRequest{KeyName: keyName, CurveType: curveType.String()}
 	l.logger.TraceMsg("Sending Generate request to remote key server: ", fmt.Sprintf("%v", req))
 	resp, err := l.kc.GenerateKey(ctx, &req)
 	if err != nil {
@@ -146,7 +145,7 @@ func (l *remoteKeyClient) Generate(keyName string, curveType crypto.CurveType) (
 func (l *remoteKeyClient) HealthCheck() error {
 	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
 	defer cancel()
-	_, err := l.kc.List(ctx, &pbkeys.ListRequest{})
+	_, err := l.kc.List(ctx, &ListRequest{})
 	return err
 }
 
@@ -160,7 +159,7 @@ func NewRemoteKeyClient(rpcAddress string, logger *logging.Logger) (KeyClient, e
 	if err != nil {
 		return nil, err
 	}
-	kc := pbkeys.NewKeysClient(conn)
+	kc := NewKeysClient(conn)
 
 	return &remoteKeyClient{kc: kc, rpcAddress: rpcAddress, logger: logger}, nil
 }
diff --git a/keys/key_store.go b/keys/key_store.go
index 0a8a1cf5a338698ab0f3ebaebfcfcfe3c50dea30..c2326cf382c45286edfa0f7bffe12a1ed1993702 100644
--- a/keys/key_store.go
+++ b/keys/key_store.go
@@ -15,8 +15,8 @@ import (
 	"github.com/hyperledger/burrow/crypto"
 	"github.com/hyperledger/burrow/logging"
 	"github.com/hyperledger/burrow/logging/structure"
-	"github.com/tmthrgd/go-hex"
 
+	"github.com/tmthrgd/go-hex"
 	"golang.org/x/crypto/scrypt"
 )
 
diff --git a/keys/keys.pb.go b/keys/keys.pb.go
new file mode 100644
index 0000000000000000000000000000000000000000..6d8212e6a3e934c5440e5a519d8b11e83cc584dd
--- /dev/null
+++ b/keys/keys.pb.go
@@ -0,0 +1,4538 @@
+// Code generated by protoc-gen-gogo. DO NOT EDIT.
+// source: keys.proto
+
+/*
+	Package keys is a generated protocol buffer package.
+
+	It is generated from these files:
+		keys.proto
+
+	It has these top-level messages:
+		ListRequest
+		VerifyResponse
+		RemoveNameResponse
+		AddNameResponse
+		RemoveNameRequest
+		GenRequest
+		GenResponse
+		PubRequest
+		PubResponse
+		ImportJSONRequest
+		ImportResponse
+		ImportRequest
+		ExportRequest
+		ExportResponse
+		SignRequest
+		SignResponse
+		VerifyRequest
+		HashRequest
+		HashResponse
+		KeyID
+		ListResponse
+		AddNameRequest
+*/
+package keys
+
+import proto "github.com/gogo/protobuf/proto"
+import golang_proto "github.com/golang/protobuf/proto"
+import fmt "fmt"
+import math "math"
+import _ "github.com/gogo/protobuf/gogoproto"
+
+import context "golang.org/x/net/context"
+import grpc "google.golang.org/grpc"
+
+import io "io"
+
+// Reference imports to suppress errors if they are not otherwise used.
+var _ = proto.Marshal
+var _ = golang_proto.Marshal
+var _ = fmt.Errorf
+var _ = math.Inf
+
+// This is a compile-time assertion to ensure that this generated file
+// is compatible with the proto package it is being compiled against.
+// A compilation error at this line likely means your copy of the
+// proto package needs to be updated.
+const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package
+
+type ListRequest struct {
+}
+
+func (m *ListRequest) Reset()                    { *m = ListRequest{} }
+func (m *ListRequest) String() string            { return proto.CompactTextString(m) }
+func (*ListRequest) ProtoMessage()               {}
+func (*ListRequest) Descriptor() ([]byte, []int) { return fileDescriptorKeys, []int{0} }
+
+func (*ListRequest) XXX_MessageName() string {
+	return "keys.ListRequest"
+}
+
+type VerifyResponse struct {
+}
+
+func (m *VerifyResponse) Reset()                    { *m = VerifyResponse{} }
+func (m *VerifyResponse) String() string            { return proto.CompactTextString(m) }
+func (*VerifyResponse) ProtoMessage()               {}
+func (*VerifyResponse) Descriptor() ([]byte, []int) { return fileDescriptorKeys, []int{1} }
+
+func (*VerifyResponse) XXX_MessageName() string {
+	return "keys.VerifyResponse"
+}
+
+type RemoveNameResponse struct {
+}
+
+func (m *RemoveNameResponse) Reset()                    { *m = RemoveNameResponse{} }
+func (m *RemoveNameResponse) String() string            { return proto.CompactTextString(m) }
+func (*RemoveNameResponse) ProtoMessage()               {}
+func (*RemoveNameResponse) Descriptor() ([]byte, []int) { return fileDescriptorKeys, []int{2} }
+
+func (*RemoveNameResponse) XXX_MessageName() string {
+	return "keys.RemoveNameResponse"
+}
+
+type AddNameResponse struct {
+}
+
+func (m *AddNameResponse) Reset()                    { *m = AddNameResponse{} }
+func (m *AddNameResponse) String() string            { return proto.CompactTextString(m) }
+func (*AddNameResponse) ProtoMessage()               {}
+func (*AddNameResponse) Descriptor() ([]byte, []int) { return fileDescriptorKeys, []int{3} }
+
+func (*AddNameResponse) XXX_MessageName() string {
+	return "keys.AddNameResponse"
+}
+
+type RemoveNameRequest struct {
+	KeyName string `protobuf:"bytes,1,opt,name=KeyName,proto3" json:"KeyName,omitempty"`
+}
+
+func (m *RemoveNameRequest) Reset()                    { *m = RemoveNameRequest{} }
+func (m *RemoveNameRequest) String() string            { return proto.CompactTextString(m) }
+func (*RemoveNameRequest) ProtoMessage()               {}
+func (*RemoveNameRequest) Descriptor() ([]byte, []int) { return fileDescriptorKeys, []int{4} }
+
+func (m *RemoveNameRequest) GetKeyName() string {
+	if m != nil {
+		return m.KeyName
+	}
+	return ""
+}
+
+func (*RemoveNameRequest) XXX_MessageName() string {
+	return "keys.RemoveNameRequest"
+}
+
+type GenRequest struct {
+	Passphrase string `protobuf:"bytes,1,opt,name=Passphrase,proto3" json:"Passphrase,omitempty"`
+	CurveType  string `protobuf:"bytes,2,opt,name=CurveType,proto3" json:"CurveType,omitempty"`
+	KeyName    string `protobuf:"bytes,3,opt,name=KeyName,proto3" json:"KeyName,omitempty"`
+}
+
+func (m *GenRequest) Reset()                    { *m = GenRequest{} }
+func (m *GenRequest) String() string            { return proto.CompactTextString(m) }
+func (*GenRequest) ProtoMessage()               {}
+func (*GenRequest) Descriptor() ([]byte, []int) { return fileDescriptorKeys, []int{5} }
+
+func (m *GenRequest) GetPassphrase() string {
+	if m != nil {
+		return m.Passphrase
+	}
+	return ""
+}
+
+func (m *GenRequest) GetCurveType() string {
+	if m != nil {
+		return m.CurveType
+	}
+	return ""
+}
+
+func (m *GenRequest) GetKeyName() string {
+	if m != nil {
+		return m.KeyName
+	}
+	return ""
+}
+
+func (*GenRequest) XXX_MessageName() string {
+	return "keys.GenRequest"
+}
+
+type GenResponse struct {
+	Address string `protobuf:"bytes,1,opt,name=Address,proto3" json:"Address,omitempty"`
+}
+
+func (m *GenResponse) Reset()                    { *m = GenResponse{} }
+func (m *GenResponse) String() string            { return proto.CompactTextString(m) }
+func (*GenResponse) ProtoMessage()               {}
+func (*GenResponse) Descriptor() ([]byte, []int) { return fileDescriptorKeys, []int{6} }
+
+func (m *GenResponse) GetAddress() string {
+	if m != nil {
+		return m.Address
+	}
+	return ""
+}
+
+func (*GenResponse) XXX_MessageName() string {
+	return "keys.GenResponse"
+}
+
+type PubRequest struct {
+	Address string `protobuf:"bytes,1,opt,name=Address,proto3" json:"Address,omitempty"`
+	Name    string `protobuf:"bytes,2,opt,name=Name,proto3" json:"Name,omitempty"`
+}
+
+func (m *PubRequest) Reset()                    { *m = PubRequest{} }
+func (m *PubRequest) String() string            { return proto.CompactTextString(m) }
+func (*PubRequest) ProtoMessage()               {}
+func (*PubRequest) Descriptor() ([]byte, []int) { return fileDescriptorKeys, []int{7} }
+
+func (m *PubRequest) GetAddress() string {
+	if m != nil {
+		return m.Address
+	}
+	return ""
+}
+
+func (m *PubRequest) GetName() string {
+	if m != nil {
+		return m.Name
+	}
+	return ""
+}
+
+func (*PubRequest) XXX_MessageName() string {
+	return "keys.PubRequest"
+}
+
+type PubResponse struct {
+	PublicKey []byte `protobuf:"bytes,1,opt,name=PublicKey,proto3" json:"PublicKey,omitempty"`
+	CurveType string `protobuf:"bytes,2,opt,name=CurveType,proto3" json:"CurveType,omitempty"`
+}
+
+func (m *PubResponse) Reset()                    { *m = PubResponse{} }
+func (m *PubResponse) String() string            { return proto.CompactTextString(m) }
+func (*PubResponse) ProtoMessage()               {}
+func (*PubResponse) Descriptor() ([]byte, []int) { return fileDescriptorKeys, []int{8} }
+
+func (m *PubResponse) GetPublicKey() []byte {
+	if m != nil {
+		return m.PublicKey
+	}
+	return nil
+}
+
+func (m *PubResponse) GetCurveType() string {
+	if m != nil {
+		return m.CurveType
+	}
+	return ""
+}
+
+func (*PubResponse) XXX_MessageName() string {
+	return "keys.PubResponse"
+}
+
+type ImportJSONRequest struct {
+	Passphrase string `protobuf:"bytes,1,opt,name=Passphrase,proto3" json:"Passphrase,omitempty"`
+	JSON       string `protobuf:"bytes,2,opt,name=JSON,proto3" json:"JSON,omitempty"`
+}
+
+func (m *ImportJSONRequest) Reset()                    { *m = ImportJSONRequest{} }
+func (m *ImportJSONRequest) String() string            { return proto.CompactTextString(m) }
+func (*ImportJSONRequest) ProtoMessage()               {}
+func (*ImportJSONRequest) Descriptor() ([]byte, []int) { return fileDescriptorKeys, []int{9} }
+
+func (m *ImportJSONRequest) GetPassphrase() string {
+	if m != nil {
+		return m.Passphrase
+	}
+	return ""
+}
+
+func (m *ImportJSONRequest) GetJSON() string {
+	if m != nil {
+		return m.JSON
+	}
+	return ""
+}
+
+func (*ImportJSONRequest) XXX_MessageName() string {
+	return "keys.ImportJSONRequest"
+}
+
+type ImportResponse struct {
+	Address string `protobuf:"bytes,1,opt,name=Address,proto3" json:"Address,omitempty"`
+}
+
+func (m *ImportResponse) Reset()                    { *m = ImportResponse{} }
+func (m *ImportResponse) String() string            { return proto.CompactTextString(m) }
+func (*ImportResponse) ProtoMessage()               {}
+func (*ImportResponse) Descriptor() ([]byte, []int) { return fileDescriptorKeys, []int{10} }
+
+func (m *ImportResponse) GetAddress() string {
+	if m != nil {
+		return m.Address
+	}
+	return ""
+}
+
+func (*ImportResponse) XXX_MessageName() string {
+	return "keys.ImportResponse"
+}
+
+type ImportRequest struct {
+	Passphrase string `protobuf:"bytes,1,opt,name=Passphrase,proto3" json:"Passphrase,omitempty"`
+	Name       string `protobuf:"bytes,2,opt,name=Name,proto3" json:"Name,omitempty"`
+	CurveType  string `protobuf:"bytes,3,opt,name=CurveType,proto3" json:"CurveType,omitempty"`
+	KeyBytes   []byte `protobuf:"bytes,4,opt,name=KeyBytes,proto3" json:"KeyBytes,omitempty"`
+}
+
+func (m *ImportRequest) Reset()                    { *m = ImportRequest{} }
+func (m *ImportRequest) String() string            { return proto.CompactTextString(m) }
+func (*ImportRequest) ProtoMessage()               {}
+func (*ImportRequest) Descriptor() ([]byte, []int) { return fileDescriptorKeys, []int{11} }
+
+func (m *ImportRequest) GetPassphrase() string {
+	if m != nil {
+		return m.Passphrase
+	}
+	return ""
+}
+
+func (m *ImportRequest) GetName() string {
+	if m != nil {
+		return m.Name
+	}
+	return ""
+}
+
+func (m *ImportRequest) GetCurveType() string {
+	if m != nil {
+		return m.CurveType
+	}
+	return ""
+}
+
+func (m *ImportRequest) GetKeyBytes() []byte {
+	if m != nil {
+		return m.KeyBytes
+	}
+	return nil
+}
+
+func (*ImportRequest) XXX_MessageName() string {
+	return "keys.ImportRequest"
+}
+
+type ExportRequest struct {
+	Passphrase string `protobuf:"bytes,1,opt,name=Passphrase,proto3" json:"Passphrase,omitempty"`
+	Name       string `protobuf:"bytes,2,opt,name=Name,proto3" json:"Name,omitempty"`
+	Address    string `protobuf:"bytes,3,opt,name=Address,proto3" json:"Address,omitempty"`
+}
+
+func (m *ExportRequest) Reset()                    { *m = ExportRequest{} }
+func (m *ExportRequest) String() string            { return proto.CompactTextString(m) }
+func (*ExportRequest) ProtoMessage()               {}
+func (*ExportRequest) Descriptor() ([]byte, []int) { return fileDescriptorKeys, []int{12} }
+
+func (m *ExportRequest) GetPassphrase() string {
+	if m != nil {
+		return m.Passphrase
+	}
+	return ""
+}
+
+func (m *ExportRequest) GetName() string {
+	if m != nil {
+		return m.Name
+	}
+	return ""
+}
+
+func (m *ExportRequest) GetAddress() string {
+	if m != nil {
+		return m.Address
+	}
+	return ""
+}
+
+func (*ExportRequest) XXX_MessageName() string {
+	return "keys.ExportRequest"
+}
+
+type ExportResponse struct {
+	Publickey  []byte `protobuf:"bytes,1,opt,name=Publickey,proto3" json:"Publickey,omitempty"`
+	Privatekey []byte `protobuf:"bytes,2,opt,name=Privatekey,proto3" json:"Privatekey,omitempty"`
+	Address    []byte `protobuf:"bytes,3,opt,name=Address,proto3" json:"Address,omitempty"`
+	CurveType  string `protobuf:"bytes,4,opt,name=CurveType,proto3" json:"CurveType,omitempty"`
+}
+
+func (m *ExportResponse) Reset()                    { *m = ExportResponse{} }
+func (m *ExportResponse) String() string            { return proto.CompactTextString(m) }
+func (*ExportResponse) ProtoMessage()               {}
+func (*ExportResponse) Descriptor() ([]byte, []int) { return fileDescriptorKeys, []int{13} }
+
+func (m *ExportResponse) GetPublickey() []byte {
+	if m != nil {
+		return m.Publickey
+	}
+	return nil
+}
+
+func (m *ExportResponse) GetPrivatekey() []byte {
+	if m != nil {
+		return m.Privatekey
+	}
+	return nil
+}
+
+func (m *ExportResponse) GetAddress() []byte {
+	if m != nil {
+		return m.Address
+	}
+	return nil
+}
+
+func (m *ExportResponse) GetCurveType() string {
+	if m != nil {
+		return m.CurveType
+	}
+	return ""
+}
+
+func (*ExportResponse) XXX_MessageName() string {
+	return "keys.ExportResponse"
+}
+
+type SignRequest struct {
+	Passphrase string `protobuf:"bytes,1,opt,name=Passphrase,proto3" json:"Passphrase,omitempty"`
+	Address    string `protobuf:"bytes,2,opt,name=Address,proto3" json:"Address,omitempty"`
+	Name       string `protobuf:"bytes,3,opt,name=Name,proto3" json:"Name,omitempty"`
+	Message    []byte `protobuf:"bytes,4,opt,name=Message,proto3" json:"Message,omitempty"`
+}
+
+func (m *SignRequest) Reset()                    { *m = SignRequest{} }
+func (m *SignRequest) String() string            { return proto.CompactTextString(m) }
+func (*SignRequest) ProtoMessage()               {}
+func (*SignRequest) Descriptor() ([]byte, []int) { return fileDescriptorKeys, []int{14} }
+
+func (m *SignRequest) GetPassphrase() string {
+	if m != nil {
+		return m.Passphrase
+	}
+	return ""
+}
+
+func (m *SignRequest) GetAddress() string {
+	if m != nil {
+		return m.Address
+	}
+	return ""
+}
+
+func (m *SignRequest) GetName() string {
+	if m != nil {
+		return m.Name
+	}
+	return ""
+}
+
+func (m *SignRequest) GetMessage() []byte {
+	if m != nil {
+		return m.Message
+	}
+	return nil
+}
+
+func (*SignRequest) XXX_MessageName() string {
+	return "keys.SignRequest"
+}
+
+type SignResponse struct {
+	Signature []byte `protobuf:"bytes,1,opt,name=Signature,proto3" json:"Signature,omitempty"`
+	CurveType string `protobuf:"bytes,2,opt,name=CurveType,proto3" json:"CurveType,omitempty"`
+}
+
+func (m *SignResponse) Reset()                    { *m = SignResponse{} }
+func (m *SignResponse) String() string            { return proto.CompactTextString(m) }
+func (*SignResponse) ProtoMessage()               {}
+func (*SignResponse) Descriptor() ([]byte, []int) { return fileDescriptorKeys, []int{15} }
+
+func (m *SignResponse) GetSignature() []byte {
+	if m != nil {
+		return m.Signature
+	}
+	return nil
+}
+
+func (m *SignResponse) GetCurveType() string {
+	if m != nil {
+		return m.CurveType
+	}
+	return ""
+}
+
+func (*SignResponse) XXX_MessageName() string {
+	return "keys.SignResponse"
+}
+
+type VerifyRequest struct {
+	CurveType string `protobuf:"bytes,1,opt,name=CurveType,proto3" json:"CurveType,omitempty"`
+	PublicKey []byte `protobuf:"bytes,2,opt,name=PublicKey,proto3" json:"PublicKey,omitempty"`
+	Message   []byte `protobuf:"bytes,3,opt,name=Message,proto3" json:"Message,omitempty"`
+	Signature []byte `protobuf:"bytes,4,opt,name=Signature,proto3" json:"Signature,omitempty"`
+}
+
+func (m *VerifyRequest) Reset()                    { *m = VerifyRequest{} }
+func (m *VerifyRequest) String() string            { return proto.CompactTextString(m) }
+func (*VerifyRequest) ProtoMessage()               {}
+func (*VerifyRequest) Descriptor() ([]byte, []int) { return fileDescriptorKeys, []int{16} }
+
+func (m *VerifyRequest) GetCurveType() string {
+	if m != nil {
+		return m.CurveType
+	}
+	return ""
+}
+
+func (m *VerifyRequest) GetPublicKey() []byte {
+	if m != nil {
+		return m.PublicKey
+	}
+	return nil
+}
+
+func (m *VerifyRequest) GetMessage() []byte {
+	if m != nil {
+		return m.Message
+	}
+	return nil
+}
+
+func (m *VerifyRequest) GetSignature() []byte {
+	if m != nil {
+		return m.Signature
+	}
+	return nil
+}
+
+func (*VerifyRequest) XXX_MessageName() string {
+	return "keys.VerifyRequest"
+}
+
+type HashRequest struct {
+	Hashtype string `protobuf:"bytes,1,opt,name=Hashtype,proto3" json:"Hashtype,omitempty"`
+	Message  []byte `protobuf:"bytes,2,opt,name=Message,proto3" json:"Message,omitempty"`
+}
+
+func (m *HashRequest) Reset()                    { *m = HashRequest{} }
+func (m *HashRequest) String() string            { return proto.CompactTextString(m) }
+func (*HashRequest) ProtoMessage()               {}
+func (*HashRequest) Descriptor() ([]byte, []int) { return fileDescriptorKeys, []int{17} }
+
+func (m *HashRequest) GetHashtype() string {
+	if m != nil {
+		return m.Hashtype
+	}
+	return ""
+}
+
+func (m *HashRequest) GetMessage() []byte {
+	if m != nil {
+		return m.Message
+	}
+	return nil
+}
+
+func (*HashRequest) XXX_MessageName() string {
+	return "keys.HashRequest"
+}
+
+type HashResponse struct {
+	Hash string `protobuf:"bytes,1,opt,name=Hash,proto3" json:"Hash,omitempty"`
+}
+
+func (m *HashResponse) Reset()                    { *m = HashResponse{} }
+func (m *HashResponse) String() string            { return proto.CompactTextString(m) }
+func (*HashResponse) ProtoMessage()               {}
+func (*HashResponse) Descriptor() ([]byte, []int) { return fileDescriptorKeys, []int{18} }
+
+func (m *HashResponse) GetHash() string {
+	if m != nil {
+		return m.Hash
+	}
+	return ""
+}
+
+func (*HashResponse) XXX_MessageName() string {
+	return "keys.HashResponse"
+}
+
+type KeyID struct {
+	Address string `protobuf:"bytes,1,opt,name=Address,proto3" json:"Address,omitempty"`
+	KeyName string `protobuf:"bytes,2,opt,name=KeyName,proto3" json:"KeyName,omitempty"`
+}
+
+func (m *KeyID) Reset()                    { *m = KeyID{} }
+func (m *KeyID) String() string            { return proto.CompactTextString(m) }
+func (*KeyID) ProtoMessage()               {}
+func (*KeyID) Descriptor() ([]byte, []int) { return fileDescriptorKeys, []int{19} }
+
+func (m *KeyID) GetAddress() string {
+	if m != nil {
+		return m.Address
+	}
+	return ""
+}
+
+func (m *KeyID) GetKeyName() string {
+	if m != nil {
+		return m.KeyName
+	}
+	return ""
+}
+
+func (*KeyID) XXX_MessageName() string {
+	return "keys.KeyID"
+}
+
+type ListResponse struct {
+	Key []*KeyID `protobuf:"bytes,1,rep,name=key" json:"key,omitempty"`
+}
+
+func (m *ListResponse) Reset()                    { *m = ListResponse{} }
+func (m *ListResponse) String() string            { return proto.CompactTextString(m) }
+func (*ListResponse) ProtoMessage()               {}
+func (*ListResponse) Descriptor() ([]byte, []int) { return fileDescriptorKeys, []int{20} }
+
+func (m *ListResponse) GetKey() []*KeyID {
+	if m != nil {
+		return m.Key
+	}
+	return nil
+}
+
+func (*ListResponse) XXX_MessageName() string {
+	return "keys.ListResponse"
+}
+
+type AddNameRequest struct {
+	Keyname string `protobuf:"bytes,1,opt,name=Keyname,proto3" json:"Keyname,omitempty"`
+	Address string `protobuf:"bytes,2,opt,name=Address,proto3" json:"Address,omitempty"`
+}
+
+func (m *AddNameRequest) Reset()                    { *m = AddNameRequest{} }
+func (m *AddNameRequest) String() string            { return proto.CompactTextString(m) }
+func (*AddNameRequest) ProtoMessage()               {}
+func (*AddNameRequest) Descriptor() ([]byte, []int) { return fileDescriptorKeys, []int{21} }
+
+func (m *AddNameRequest) GetKeyname() string {
+	if m != nil {
+		return m.Keyname
+	}
+	return ""
+}
+
+func (m *AddNameRequest) GetAddress() string {
+	if m != nil {
+		return m.Address
+	}
+	return ""
+}
+
+func (*AddNameRequest) XXX_MessageName() string {
+	return "keys.AddNameRequest"
+}
+func init() {
+	proto.RegisterType((*ListRequest)(nil), "keys.ListRequest")
+	golang_proto.RegisterType((*ListRequest)(nil), "keys.ListRequest")
+	proto.RegisterType((*VerifyResponse)(nil), "keys.VerifyResponse")
+	golang_proto.RegisterType((*VerifyResponse)(nil), "keys.VerifyResponse")
+	proto.RegisterType((*RemoveNameResponse)(nil), "keys.RemoveNameResponse")
+	golang_proto.RegisterType((*RemoveNameResponse)(nil), "keys.RemoveNameResponse")
+	proto.RegisterType((*AddNameResponse)(nil), "keys.AddNameResponse")
+	golang_proto.RegisterType((*AddNameResponse)(nil), "keys.AddNameResponse")
+	proto.RegisterType((*RemoveNameRequest)(nil), "keys.RemoveNameRequest")
+	golang_proto.RegisterType((*RemoveNameRequest)(nil), "keys.RemoveNameRequest")
+	proto.RegisterType((*GenRequest)(nil), "keys.GenRequest")
+	golang_proto.RegisterType((*GenRequest)(nil), "keys.GenRequest")
+	proto.RegisterType((*GenResponse)(nil), "keys.GenResponse")
+	golang_proto.RegisterType((*GenResponse)(nil), "keys.GenResponse")
+	proto.RegisterType((*PubRequest)(nil), "keys.PubRequest")
+	golang_proto.RegisterType((*PubRequest)(nil), "keys.PubRequest")
+	proto.RegisterType((*PubResponse)(nil), "keys.PubResponse")
+	golang_proto.RegisterType((*PubResponse)(nil), "keys.PubResponse")
+	proto.RegisterType((*ImportJSONRequest)(nil), "keys.ImportJSONRequest")
+	golang_proto.RegisterType((*ImportJSONRequest)(nil), "keys.ImportJSONRequest")
+	proto.RegisterType((*ImportResponse)(nil), "keys.ImportResponse")
+	golang_proto.RegisterType((*ImportResponse)(nil), "keys.ImportResponse")
+	proto.RegisterType((*ImportRequest)(nil), "keys.ImportRequest")
+	golang_proto.RegisterType((*ImportRequest)(nil), "keys.ImportRequest")
+	proto.RegisterType((*ExportRequest)(nil), "keys.ExportRequest")
+	golang_proto.RegisterType((*ExportRequest)(nil), "keys.ExportRequest")
+	proto.RegisterType((*ExportResponse)(nil), "keys.ExportResponse")
+	golang_proto.RegisterType((*ExportResponse)(nil), "keys.ExportResponse")
+	proto.RegisterType((*SignRequest)(nil), "keys.SignRequest")
+	golang_proto.RegisterType((*SignRequest)(nil), "keys.SignRequest")
+	proto.RegisterType((*SignResponse)(nil), "keys.SignResponse")
+	golang_proto.RegisterType((*SignResponse)(nil), "keys.SignResponse")
+	proto.RegisterType((*VerifyRequest)(nil), "keys.VerifyRequest")
+	golang_proto.RegisterType((*VerifyRequest)(nil), "keys.VerifyRequest")
+	proto.RegisterType((*HashRequest)(nil), "keys.HashRequest")
+	golang_proto.RegisterType((*HashRequest)(nil), "keys.HashRequest")
+	proto.RegisterType((*HashResponse)(nil), "keys.HashResponse")
+	golang_proto.RegisterType((*HashResponse)(nil), "keys.HashResponse")
+	proto.RegisterType((*KeyID)(nil), "keys.KeyID")
+	golang_proto.RegisterType((*KeyID)(nil), "keys.KeyID")
+	proto.RegisterType((*ListResponse)(nil), "keys.ListResponse")
+	golang_proto.RegisterType((*ListResponse)(nil), "keys.ListResponse")
+	proto.RegisterType((*AddNameRequest)(nil), "keys.AddNameRequest")
+	golang_proto.RegisterType((*AddNameRequest)(nil), "keys.AddNameRequest")
+}
+
+// Reference imports to suppress errors if they are not otherwise used.
+var _ context.Context
+var _ grpc.ClientConn
+
+// This is a compile-time assertion to ensure that this generated file
+// is compatible with the grpc package it is being compiled against.
+const _ = grpc.SupportPackageIsVersion4
+
+// Client API for Keys service
+
+type KeysClient interface {
+	GenerateKey(ctx context.Context, in *GenRequest, opts ...grpc.CallOption) (*GenResponse, error)
+	PublicKey(ctx context.Context, in *PubRequest, opts ...grpc.CallOption) (*PubResponse, error)
+	Sign(ctx context.Context, in *SignRequest, opts ...grpc.CallOption) (*SignResponse, error)
+	Verify(ctx context.Context, in *VerifyRequest, opts ...grpc.CallOption) (*VerifyResponse, error)
+	Import(ctx context.Context, in *ImportRequest, opts ...grpc.CallOption) (*ImportResponse, error)
+	ImportJSON(ctx context.Context, in *ImportJSONRequest, opts ...grpc.CallOption) (*ImportResponse, error)
+	Export(ctx context.Context, in *ExportRequest, opts ...grpc.CallOption) (*ExportResponse, error)
+	Hash(ctx context.Context, in *HashRequest, opts ...grpc.CallOption) (*HashResponse, error)
+	RemoveName(ctx context.Context, in *RemoveNameRequest, opts ...grpc.CallOption) (*RemoveNameResponse, error)
+	List(ctx context.Context, in *ListRequest, opts ...grpc.CallOption) (*ListResponse, error)
+	AddName(ctx context.Context, in *AddNameRequest, opts ...grpc.CallOption) (*AddNameResponse, error)
+}
+
+type keysClient struct {
+	cc *grpc.ClientConn
+}
+
+func NewKeysClient(cc *grpc.ClientConn) KeysClient {
+	return &keysClient{cc}
+}
+
+func (c *keysClient) GenerateKey(ctx context.Context, in *GenRequest, opts ...grpc.CallOption) (*GenResponse, error) {
+	out := new(GenResponse)
+	err := grpc.Invoke(ctx, "/keys.Keys/GenerateKey", in, out, c.cc, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *keysClient) PublicKey(ctx context.Context, in *PubRequest, opts ...grpc.CallOption) (*PubResponse, error) {
+	out := new(PubResponse)
+	err := grpc.Invoke(ctx, "/keys.Keys/PublicKey", in, out, c.cc, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *keysClient) Sign(ctx context.Context, in *SignRequest, opts ...grpc.CallOption) (*SignResponse, error) {
+	out := new(SignResponse)
+	err := grpc.Invoke(ctx, "/keys.Keys/Sign", in, out, c.cc, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *keysClient) Verify(ctx context.Context, in *VerifyRequest, opts ...grpc.CallOption) (*VerifyResponse, error) {
+	out := new(VerifyResponse)
+	err := grpc.Invoke(ctx, "/keys.Keys/Verify", in, out, c.cc, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *keysClient) Import(ctx context.Context, in *ImportRequest, opts ...grpc.CallOption) (*ImportResponse, error) {
+	out := new(ImportResponse)
+	err := grpc.Invoke(ctx, "/keys.Keys/Import", in, out, c.cc, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *keysClient) ImportJSON(ctx context.Context, in *ImportJSONRequest, opts ...grpc.CallOption) (*ImportResponse, error) {
+	out := new(ImportResponse)
+	err := grpc.Invoke(ctx, "/keys.Keys/ImportJSON", in, out, c.cc, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *keysClient) Export(ctx context.Context, in *ExportRequest, opts ...grpc.CallOption) (*ExportResponse, error) {
+	out := new(ExportResponse)
+	err := grpc.Invoke(ctx, "/keys.Keys/Export", in, out, c.cc, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *keysClient) Hash(ctx context.Context, in *HashRequest, opts ...grpc.CallOption) (*HashResponse, error) {
+	out := new(HashResponse)
+	err := grpc.Invoke(ctx, "/keys.Keys/Hash", in, out, c.cc, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *keysClient) RemoveName(ctx context.Context, in *RemoveNameRequest, opts ...grpc.CallOption) (*RemoveNameResponse, error) {
+	out := new(RemoveNameResponse)
+	err := grpc.Invoke(ctx, "/keys.Keys/RemoveName", in, out, c.cc, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *keysClient) List(ctx context.Context, in *ListRequest, opts ...grpc.CallOption) (*ListResponse, error) {
+	out := new(ListResponse)
+	err := grpc.Invoke(ctx, "/keys.Keys/List", in, out, c.cc, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *keysClient) AddName(ctx context.Context, in *AddNameRequest, opts ...grpc.CallOption) (*AddNameResponse, error) {
+	out := new(AddNameResponse)
+	err := grpc.Invoke(ctx, "/keys.Keys/AddName", in, out, c.cc, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+// Server API for Keys service
+
+type KeysServer interface {
+	GenerateKey(context.Context, *GenRequest) (*GenResponse, error)
+	PublicKey(context.Context, *PubRequest) (*PubResponse, error)
+	Sign(context.Context, *SignRequest) (*SignResponse, error)
+	Verify(context.Context, *VerifyRequest) (*VerifyResponse, error)
+	Import(context.Context, *ImportRequest) (*ImportResponse, error)
+	ImportJSON(context.Context, *ImportJSONRequest) (*ImportResponse, error)
+	Export(context.Context, *ExportRequest) (*ExportResponse, error)
+	Hash(context.Context, *HashRequest) (*HashResponse, error)
+	RemoveName(context.Context, *RemoveNameRequest) (*RemoveNameResponse, error)
+	List(context.Context, *ListRequest) (*ListResponse, error)
+	AddName(context.Context, *AddNameRequest) (*AddNameResponse, error)
+}
+
+func RegisterKeysServer(s *grpc.Server, srv KeysServer) {
+	s.RegisterService(&_Keys_serviceDesc, srv)
+}
+
+func _Keys_GenerateKey_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(GenRequest)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(KeysServer).GenerateKey(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/keys.Keys/GenerateKey",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(KeysServer).GenerateKey(ctx, req.(*GenRequest))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _Keys_PublicKey_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(PubRequest)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(KeysServer).PublicKey(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/keys.Keys/PublicKey",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(KeysServer).PublicKey(ctx, req.(*PubRequest))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _Keys_Sign_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(SignRequest)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(KeysServer).Sign(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/keys.Keys/Sign",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(KeysServer).Sign(ctx, req.(*SignRequest))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _Keys_Verify_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(VerifyRequest)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(KeysServer).Verify(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/keys.Keys/Verify",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(KeysServer).Verify(ctx, req.(*VerifyRequest))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _Keys_Import_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(ImportRequest)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(KeysServer).Import(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/keys.Keys/Import",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(KeysServer).Import(ctx, req.(*ImportRequest))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _Keys_ImportJSON_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(ImportJSONRequest)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(KeysServer).ImportJSON(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/keys.Keys/ImportJSON",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(KeysServer).ImportJSON(ctx, req.(*ImportJSONRequest))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _Keys_Export_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(ExportRequest)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(KeysServer).Export(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/keys.Keys/Export",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(KeysServer).Export(ctx, req.(*ExportRequest))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _Keys_Hash_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(HashRequest)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(KeysServer).Hash(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/keys.Keys/Hash",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(KeysServer).Hash(ctx, req.(*HashRequest))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _Keys_RemoveName_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(RemoveNameRequest)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(KeysServer).RemoveName(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/keys.Keys/RemoveName",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(KeysServer).RemoveName(ctx, req.(*RemoveNameRequest))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _Keys_List_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(ListRequest)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(KeysServer).List(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/keys.Keys/List",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(KeysServer).List(ctx, req.(*ListRequest))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _Keys_AddName_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(AddNameRequest)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(KeysServer).AddName(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/keys.Keys/AddName",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(KeysServer).AddName(ctx, req.(*AddNameRequest))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+var _Keys_serviceDesc = grpc.ServiceDesc{
+	ServiceName: "keys.Keys",
+	HandlerType: (*KeysServer)(nil),
+	Methods: []grpc.MethodDesc{
+		{
+			MethodName: "GenerateKey",
+			Handler:    _Keys_GenerateKey_Handler,
+		},
+		{
+			MethodName: "PublicKey",
+			Handler:    _Keys_PublicKey_Handler,
+		},
+		{
+			MethodName: "Sign",
+			Handler:    _Keys_Sign_Handler,
+		},
+		{
+			MethodName: "Verify",
+			Handler:    _Keys_Verify_Handler,
+		},
+		{
+			MethodName: "Import",
+			Handler:    _Keys_Import_Handler,
+		},
+		{
+			MethodName: "ImportJSON",
+			Handler:    _Keys_ImportJSON_Handler,
+		},
+		{
+			MethodName: "Export",
+			Handler:    _Keys_Export_Handler,
+		},
+		{
+			MethodName: "Hash",
+			Handler:    _Keys_Hash_Handler,
+		},
+		{
+			MethodName: "RemoveName",
+			Handler:    _Keys_RemoveName_Handler,
+		},
+		{
+			MethodName: "List",
+			Handler:    _Keys_List_Handler,
+		},
+		{
+			MethodName: "AddName",
+			Handler:    _Keys_AddName_Handler,
+		},
+	},
+	Streams:  []grpc.StreamDesc{},
+	Metadata: "keys.proto",
+}
+
+func (m *ListRequest) Marshal() (dAtA []byte, err error) {
+	size := m.Size()
+	dAtA = make([]byte, size)
+	n, err := m.MarshalTo(dAtA)
+	if err != nil {
+		return nil, err
+	}
+	return dAtA[:n], nil
+}
+
+func (m *ListRequest) MarshalTo(dAtA []byte) (int, error) {
+	var i int
+	_ = i
+	var l int
+	_ = l
+	return i, nil
+}
+
+func (m *VerifyResponse) Marshal() (dAtA []byte, err error) {
+	size := m.Size()
+	dAtA = make([]byte, size)
+	n, err := m.MarshalTo(dAtA)
+	if err != nil {
+		return nil, err
+	}
+	return dAtA[:n], nil
+}
+
+func (m *VerifyResponse) MarshalTo(dAtA []byte) (int, error) {
+	var i int
+	_ = i
+	var l int
+	_ = l
+	return i, nil
+}
+
+func (m *RemoveNameResponse) Marshal() (dAtA []byte, err error) {
+	size := m.Size()
+	dAtA = make([]byte, size)
+	n, err := m.MarshalTo(dAtA)
+	if err != nil {
+		return nil, err
+	}
+	return dAtA[:n], nil
+}
+
+func (m *RemoveNameResponse) MarshalTo(dAtA []byte) (int, error) {
+	var i int
+	_ = i
+	var l int
+	_ = l
+	return i, nil
+}
+
+func (m *AddNameResponse) Marshal() (dAtA []byte, err error) {
+	size := m.Size()
+	dAtA = make([]byte, size)
+	n, err := m.MarshalTo(dAtA)
+	if err != nil {
+		return nil, err
+	}
+	return dAtA[:n], nil
+}
+
+func (m *AddNameResponse) MarshalTo(dAtA []byte) (int, error) {
+	var i int
+	_ = i
+	var l int
+	_ = l
+	return i, nil
+}
+
+func (m *RemoveNameRequest) Marshal() (dAtA []byte, err error) {
+	size := m.Size()
+	dAtA = make([]byte, size)
+	n, err := m.MarshalTo(dAtA)
+	if err != nil {
+		return nil, err
+	}
+	return dAtA[:n], nil
+}
+
+func (m *RemoveNameRequest) MarshalTo(dAtA []byte) (int, error) {
+	var i int
+	_ = i
+	var l int
+	_ = l
+	if len(m.KeyName) > 0 {
+		dAtA[i] = 0xa
+		i++
+		i = encodeVarintKeys(dAtA, i, uint64(len(m.KeyName)))
+		i += copy(dAtA[i:], m.KeyName)
+	}
+	return i, nil
+}
+
+func (m *GenRequest) Marshal() (dAtA []byte, err error) {
+	size := m.Size()
+	dAtA = make([]byte, size)
+	n, err := m.MarshalTo(dAtA)
+	if err != nil {
+		return nil, err
+	}
+	return dAtA[:n], nil
+}
+
+func (m *GenRequest) MarshalTo(dAtA []byte) (int, error) {
+	var i int
+	_ = i
+	var l int
+	_ = l
+	if len(m.Passphrase) > 0 {
+		dAtA[i] = 0xa
+		i++
+		i = encodeVarintKeys(dAtA, i, uint64(len(m.Passphrase)))
+		i += copy(dAtA[i:], m.Passphrase)
+	}
+	if len(m.CurveType) > 0 {
+		dAtA[i] = 0x12
+		i++
+		i = encodeVarintKeys(dAtA, i, uint64(len(m.CurveType)))
+		i += copy(dAtA[i:], m.CurveType)
+	}
+	if len(m.KeyName) > 0 {
+		dAtA[i] = 0x1a
+		i++
+		i = encodeVarintKeys(dAtA, i, uint64(len(m.KeyName)))
+		i += copy(dAtA[i:], m.KeyName)
+	}
+	return i, nil
+}
+
+func (m *GenResponse) Marshal() (dAtA []byte, err error) {
+	size := m.Size()
+	dAtA = make([]byte, size)
+	n, err := m.MarshalTo(dAtA)
+	if err != nil {
+		return nil, err
+	}
+	return dAtA[:n], nil
+}
+
+func (m *GenResponse) MarshalTo(dAtA []byte) (int, error) {
+	var i int
+	_ = i
+	var l int
+	_ = l
+	if len(m.Address) > 0 {
+		dAtA[i] = 0xa
+		i++
+		i = encodeVarintKeys(dAtA, i, uint64(len(m.Address)))
+		i += copy(dAtA[i:], m.Address)
+	}
+	return i, nil
+}
+
+func (m *PubRequest) Marshal() (dAtA []byte, err error) {
+	size := m.Size()
+	dAtA = make([]byte, size)
+	n, err := m.MarshalTo(dAtA)
+	if err != nil {
+		return nil, err
+	}
+	return dAtA[:n], nil
+}
+
+func (m *PubRequest) MarshalTo(dAtA []byte) (int, error) {
+	var i int
+	_ = i
+	var l int
+	_ = l
+	if len(m.Address) > 0 {
+		dAtA[i] = 0xa
+		i++
+		i = encodeVarintKeys(dAtA, i, uint64(len(m.Address)))
+		i += copy(dAtA[i:], m.Address)
+	}
+	if len(m.Name) > 0 {
+		dAtA[i] = 0x12
+		i++
+		i = encodeVarintKeys(dAtA, i, uint64(len(m.Name)))
+		i += copy(dAtA[i:], m.Name)
+	}
+	return i, nil
+}
+
+func (m *PubResponse) Marshal() (dAtA []byte, err error) {
+	size := m.Size()
+	dAtA = make([]byte, size)
+	n, err := m.MarshalTo(dAtA)
+	if err != nil {
+		return nil, err
+	}
+	return dAtA[:n], nil
+}
+
+func (m *PubResponse) MarshalTo(dAtA []byte) (int, error) {
+	var i int
+	_ = i
+	var l int
+	_ = l
+	if len(m.PublicKey) > 0 {
+		dAtA[i] = 0xa
+		i++
+		i = encodeVarintKeys(dAtA, i, uint64(len(m.PublicKey)))
+		i += copy(dAtA[i:], m.PublicKey)
+	}
+	if len(m.CurveType) > 0 {
+		dAtA[i] = 0x12
+		i++
+		i = encodeVarintKeys(dAtA, i, uint64(len(m.CurveType)))
+		i += copy(dAtA[i:], m.CurveType)
+	}
+	return i, nil
+}
+
+func (m *ImportJSONRequest) Marshal() (dAtA []byte, err error) {
+	size := m.Size()
+	dAtA = make([]byte, size)
+	n, err := m.MarshalTo(dAtA)
+	if err != nil {
+		return nil, err
+	}
+	return dAtA[:n], nil
+}
+
+func (m *ImportJSONRequest) MarshalTo(dAtA []byte) (int, error) {
+	var i int
+	_ = i
+	var l int
+	_ = l
+	if len(m.Passphrase) > 0 {
+		dAtA[i] = 0xa
+		i++
+		i = encodeVarintKeys(dAtA, i, uint64(len(m.Passphrase)))
+		i += copy(dAtA[i:], m.Passphrase)
+	}
+	if len(m.JSON) > 0 {
+		dAtA[i] = 0x12
+		i++
+		i = encodeVarintKeys(dAtA, i, uint64(len(m.JSON)))
+		i += copy(dAtA[i:], m.JSON)
+	}
+	return i, nil
+}
+
+func (m *ImportResponse) Marshal() (dAtA []byte, err error) {
+	size := m.Size()
+	dAtA = make([]byte, size)
+	n, err := m.MarshalTo(dAtA)
+	if err != nil {
+		return nil, err
+	}
+	return dAtA[:n], nil
+}
+
+func (m *ImportResponse) MarshalTo(dAtA []byte) (int, error) {
+	var i int
+	_ = i
+	var l int
+	_ = l
+	if len(m.Address) > 0 {
+		dAtA[i] = 0xa
+		i++
+		i = encodeVarintKeys(dAtA, i, uint64(len(m.Address)))
+		i += copy(dAtA[i:], m.Address)
+	}
+	return i, nil
+}
+
+func (m *ImportRequest) Marshal() (dAtA []byte, err error) {
+	size := m.Size()
+	dAtA = make([]byte, size)
+	n, err := m.MarshalTo(dAtA)
+	if err != nil {
+		return nil, err
+	}
+	return dAtA[:n], nil
+}
+
+func (m *ImportRequest) MarshalTo(dAtA []byte) (int, error) {
+	var i int
+	_ = i
+	var l int
+	_ = l
+	if len(m.Passphrase) > 0 {
+		dAtA[i] = 0xa
+		i++
+		i = encodeVarintKeys(dAtA, i, uint64(len(m.Passphrase)))
+		i += copy(dAtA[i:], m.Passphrase)
+	}
+	if len(m.Name) > 0 {
+		dAtA[i] = 0x12
+		i++
+		i = encodeVarintKeys(dAtA, i, uint64(len(m.Name)))
+		i += copy(dAtA[i:], m.Name)
+	}
+	if len(m.CurveType) > 0 {
+		dAtA[i] = 0x1a
+		i++
+		i = encodeVarintKeys(dAtA, i, uint64(len(m.CurveType)))
+		i += copy(dAtA[i:], m.CurveType)
+	}
+	if len(m.KeyBytes) > 0 {
+		dAtA[i] = 0x22
+		i++
+		i = encodeVarintKeys(dAtA, i, uint64(len(m.KeyBytes)))
+		i += copy(dAtA[i:], m.KeyBytes)
+	}
+	return i, nil
+}
+
+func (m *ExportRequest) Marshal() (dAtA []byte, err error) {
+	size := m.Size()
+	dAtA = make([]byte, size)
+	n, err := m.MarshalTo(dAtA)
+	if err != nil {
+		return nil, err
+	}
+	return dAtA[:n], nil
+}
+
+func (m *ExportRequest) MarshalTo(dAtA []byte) (int, error) {
+	var i int
+	_ = i
+	var l int
+	_ = l
+	if len(m.Passphrase) > 0 {
+		dAtA[i] = 0xa
+		i++
+		i = encodeVarintKeys(dAtA, i, uint64(len(m.Passphrase)))
+		i += copy(dAtA[i:], m.Passphrase)
+	}
+	if len(m.Name) > 0 {
+		dAtA[i] = 0x12
+		i++
+		i = encodeVarintKeys(dAtA, i, uint64(len(m.Name)))
+		i += copy(dAtA[i:], m.Name)
+	}
+	if len(m.Address) > 0 {
+		dAtA[i] = 0x1a
+		i++
+		i = encodeVarintKeys(dAtA, i, uint64(len(m.Address)))
+		i += copy(dAtA[i:], m.Address)
+	}
+	return i, nil
+}
+
+func (m *ExportResponse) Marshal() (dAtA []byte, err error) {
+	size := m.Size()
+	dAtA = make([]byte, size)
+	n, err := m.MarshalTo(dAtA)
+	if err != nil {
+		return nil, err
+	}
+	return dAtA[:n], nil
+}
+
+func (m *ExportResponse) MarshalTo(dAtA []byte) (int, error) {
+	var i int
+	_ = i
+	var l int
+	_ = l
+	if len(m.Publickey) > 0 {
+		dAtA[i] = 0xa
+		i++
+		i = encodeVarintKeys(dAtA, i, uint64(len(m.Publickey)))
+		i += copy(dAtA[i:], m.Publickey)
+	}
+	if len(m.Privatekey) > 0 {
+		dAtA[i] = 0x12
+		i++
+		i = encodeVarintKeys(dAtA, i, uint64(len(m.Privatekey)))
+		i += copy(dAtA[i:], m.Privatekey)
+	}
+	if len(m.Address) > 0 {
+		dAtA[i] = 0x1a
+		i++
+		i = encodeVarintKeys(dAtA, i, uint64(len(m.Address)))
+		i += copy(dAtA[i:], m.Address)
+	}
+	if len(m.CurveType) > 0 {
+		dAtA[i] = 0x22
+		i++
+		i = encodeVarintKeys(dAtA, i, uint64(len(m.CurveType)))
+		i += copy(dAtA[i:], m.CurveType)
+	}
+	return i, nil
+}
+
+func (m *SignRequest) Marshal() (dAtA []byte, err error) {
+	size := m.Size()
+	dAtA = make([]byte, size)
+	n, err := m.MarshalTo(dAtA)
+	if err != nil {
+		return nil, err
+	}
+	return dAtA[:n], nil
+}
+
+func (m *SignRequest) MarshalTo(dAtA []byte) (int, error) {
+	var i int
+	_ = i
+	var l int
+	_ = l
+	if len(m.Passphrase) > 0 {
+		dAtA[i] = 0xa
+		i++
+		i = encodeVarintKeys(dAtA, i, uint64(len(m.Passphrase)))
+		i += copy(dAtA[i:], m.Passphrase)
+	}
+	if len(m.Address) > 0 {
+		dAtA[i] = 0x12
+		i++
+		i = encodeVarintKeys(dAtA, i, uint64(len(m.Address)))
+		i += copy(dAtA[i:], m.Address)
+	}
+	if len(m.Name) > 0 {
+		dAtA[i] = 0x1a
+		i++
+		i = encodeVarintKeys(dAtA, i, uint64(len(m.Name)))
+		i += copy(dAtA[i:], m.Name)
+	}
+	if len(m.Message) > 0 {
+		dAtA[i] = 0x22
+		i++
+		i = encodeVarintKeys(dAtA, i, uint64(len(m.Message)))
+		i += copy(dAtA[i:], m.Message)
+	}
+	return i, nil
+}
+
+func (m *SignResponse) Marshal() (dAtA []byte, err error) {
+	size := m.Size()
+	dAtA = make([]byte, size)
+	n, err := m.MarshalTo(dAtA)
+	if err != nil {
+		return nil, err
+	}
+	return dAtA[:n], nil
+}
+
+func (m *SignResponse) MarshalTo(dAtA []byte) (int, error) {
+	var i int
+	_ = i
+	var l int
+	_ = l
+	if len(m.Signature) > 0 {
+		dAtA[i] = 0xa
+		i++
+		i = encodeVarintKeys(dAtA, i, uint64(len(m.Signature)))
+		i += copy(dAtA[i:], m.Signature)
+	}
+	if len(m.CurveType) > 0 {
+		dAtA[i] = 0x12
+		i++
+		i = encodeVarintKeys(dAtA, i, uint64(len(m.CurveType)))
+		i += copy(dAtA[i:], m.CurveType)
+	}
+	return i, nil
+}
+
+func (m *VerifyRequest) Marshal() (dAtA []byte, err error) {
+	size := m.Size()
+	dAtA = make([]byte, size)
+	n, err := m.MarshalTo(dAtA)
+	if err != nil {
+		return nil, err
+	}
+	return dAtA[:n], nil
+}
+
+func (m *VerifyRequest) MarshalTo(dAtA []byte) (int, error) {
+	var i int
+	_ = i
+	var l int
+	_ = l
+	if len(m.CurveType) > 0 {
+		dAtA[i] = 0xa
+		i++
+		i = encodeVarintKeys(dAtA, i, uint64(len(m.CurveType)))
+		i += copy(dAtA[i:], m.CurveType)
+	}
+	if len(m.PublicKey) > 0 {
+		dAtA[i] = 0x12
+		i++
+		i = encodeVarintKeys(dAtA, i, uint64(len(m.PublicKey)))
+		i += copy(dAtA[i:], m.PublicKey)
+	}
+	if len(m.Message) > 0 {
+		dAtA[i] = 0x1a
+		i++
+		i = encodeVarintKeys(dAtA, i, uint64(len(m.Message)))
+		i += copy(dAtA[i:], m.Message)
+	}
+	if len(m.Signature) > 0 {
+		dAtA[i] = 0x22
+		i++
+		i = encodeVarintKeys(dAtA, i, uint64(len(m.Signature)))
+		i += copy(dAtA[i:], m.Signature)
+	}
+	return i, nil
+}
+
+func (m *HashRequest) Marshal() (dAtA []byte, err error) {
+	size := m.Size()
+	dAtA = make([]byte, size)
+	n, err := m.MarshalTo(dAtA)
+	if err != nil {
+		return nil, err
+	}
+	return dAtA[:n], nil
+}
+
+func (m *HashRequest) MarshalTo(dAtA []byte) (int, error) {
+	var i int
+	_ = i
+	var l int
+	_ = l
+	if len(m.Hashtype) > 0 {
+		dAtA[i] = 0xa
+		i++
+		i = encodeVarintKeys(dAtA, i, uint64(len(m.Hashtype)))
+		i += copy(dAtA[i:], m.Hashtype)
+	}
+	if len(m.Message) > 0 {
+		dAtA[i] = 0x12
+		i++
+		i = encodeVarintKeys(dAtA, i, uint64(len(m.Message)))
+		i += copy(dAtA[i:], m.Message)
+	}
+	return i, nil
+}
+
+func (m *HashResponse) Marshal() (dAtA []byte, err error) {
+	size := m.Size()
+	dAtA = make([]byte, size)
+	n, err := m.MarshalTo(dAtA)
+	if err != nil {
+		return nil, err
+	}
+	return dAtA[:n], nil
+}
+
+func (m *HashResponse) MarshalTo(dAtA []byte) (int, error) {
+	var i int
+	_ = i
+	var l int
+	_ = l
+	if len(m.Hash) > 0 {
+		dAtA[i] = 0xa
+		i++
+		i = encodeVarintKeys(dAtA, i, uint64(len(m.Hash)))
+		i += copy(dAtA[i:], m.Hash)
+	}
+	return i, nil
+}
+
+func (m *KeyID) Marshal() (dAtA []byte, err error) {
+	size := m.Size()
+	dAtA = make([]byte, size)
+	n, err := m.MarshalTo(dAtA)
+	if err != nil {
+		return nil, err
+	}
+	return dAtA[:n], nil
+}
+
+func (m *KeyID) MarshalTo(dAtA []byte) (int, error) {
+	var i int
+	_ = i
+	var l int
+	_ = l
+	if len(m.Address) > 0 {
+		dAtA[i] = 0xa
+		i++
+		i = encodeVarintKeys(dAtA, i, uint64(len(m.Address)))
+		i += copy(dAtA[i:], m.Address)
+	}
+	if len(m.KeyName) > 0 {
+		dAtA[i] = 0x12
+		i++
+		i = encodeVarintKeys(dAtA, i, uint64(len(m.KeyName)))
+		i += copy(dAtA[i:], m.KeyName)
+	}
+	return i, nil
+}
+
+func (m *ListResponse) Marshal() (dAtA []byte, err error) {
+	size := m.Size()
+	dAtA = make([]byte, size)
+	n, err := m.MarshalTo(dAtA)
+	if err != nil {
+		return nil, err
+	}
+	return dAtA[:n], nil
+}
+
+func (m *ListResponse) MarshalTo(dAtA []byte) (int, error) {
+	var i int
+	_ = i
+	var l int
+	_ = l
+	if len(m.Key) > 0 {
+		for _, msg := range m.Key {
+			dAtA[i] = 0xa
+			i++
+			i = encodeVarintKeys(dAtA, i, uint64(msg.Size()))
+			n, err := msg.MarshalTo(dAtA[i:])
+			if err != nil {
+				return 0, err
+			}
+			i += n
+		}
+	}
+	return i, nil
+}
+
+func (m *AddNameRequest) Marshal() (dAtA []byte, err error) {
+	size := m.Size()
+	dAtA = make([]byte, size)
+	n, err := m.MarshalTo(dAtA)
+	if err != nil {
+		return nil, err
+	}
+	return dAtA[:n], nil
+}
+
+func (m *AddNameRequest) MarshalTo(dAtA []byte) (int, error) {
+	var i int
+	_ = i
+	var l int
+	_ = l
+	if len(m.Keyname) > 0 {
+		dAtA[i] = 0xa
+		i++
+		i = encodeVarintKeys(dAtA, i, uint64(len(m.Keyname)))
+		i += copy(dAtA[i:], m.Keyname)
+	}
+	if len(m.Address) > 0 {
+		dAtA[i] = 0x12
+		i++
+		i = encodeVarintKeys(dAtA, i, uint64(len(m.Address)))
+		i += copy(dAtA[i:], m.Address)
+	}
+	return i, nil
+}
+
+func encodeVarintKeys(dAtA []byte, offset int, v uint64) int {
+	for v >= 1<<7 {
+		dAtA[offset] = uint8(v&0x7f | 0x80)
+		v >>= 7
+		offset++
+	}
+	dAtA[offset] = uint8(v)
+	return offset + 1
+}
+func (m *ListRequest) Size() (n int) {
+	var l int
+	_ = l
+	return n
+}
+
+func (m *VerifyResponse) Size() (n int) {
+	var l int
+	_ = l
+	return n
+}
+
+func (m *RemoveNameResponse) Size() (n int) {
+	var l int
+	_ = l
+	return n
+}
+
+func (m *AddNameResponse) Size() (n int) {
+	var l int
+	_ = l
+	return n
+}
+
+func (m *RemoveNameRequest) Size() (n int) {
+	var l int
+	_ = l
+	l = len(m.KeyName)
+	if l > 0 {
+		n += 1 + l + sovKeys(uint64(l))
+	}
+	return n
+}
+
+func (m *GenRequest) Size() (n int) {
+	var l int
+	_ = l
+	l = len(m.Passphrase)
+	if l > 0 {
+		n += 1 + l + sovKeys(uint64(l))
+	}
+	l = len(m.CurveType)
+	if l > 0 {
+		n += 1 + l + sovKeys(uint64(l))
+	}
+	l = len(m.KeyName)
+	if l > 0 {
+		n += 1 + l + sovKeys(uint64(l))
+	}
+	return n
+}
+
+func (m *GenResponse) Size() (n int) {
+	var l int
+	_ = l
+	l = len(m.Address)
+	if l > 0 {
+		n += 1 + l + sovKeys(uint64(l))
+	}
+	return n
+}
+
+func (m *PubRequest) Size() (n int) {
+	var l int
+	_ = l
+	l = len(m.Address)
+	if l > 0 {
+		n += 1 + l + sovKeys(uint64(l))
+	}
+	l = len(m.Name)
+	if l > 0 {
+		n += 1 + l + sovKeys(uint64(l))
+	}
+	return n
+}
+
+func (m *PubResponse) Size() (n int) {
+	var l int
+	_ = l
+	l = len(m.PublicKey)
+	if l > 0 {
+		n += 1 + l + sovKeys(uint64(l))
+	}
+	l = len(m.CurveType)
+	if l > 0 {
+		n += 1 + l + sovKeys(uint64(l))
+	}
+	return n
+}
+
+func (m *ImportJSONRequest) Size() (n int) {
+	var l int
+	_ = l
+	l = len(m.Passphrase)
+	if l > 0 {
+		n += 1 + l + sovKeys(uint64(l))
+	}
+	l = len(m.JSON)
+	if l > 0 {
+		n += 1 + l + sovKeys(uint64(l))
+	}
+	return n
+}
+
+func (m *ImportResponse) Size() (n int) {
+	var l int
+	_ = l
+	l = len(m.Address)
+	if l > 0 {
+		n += 1 + l + sovKeys(uint64(l))
+	}
+	return n
+}
+
+func (m *ImportRequest) Size() (n int) {
+	var l int
+	_ = l
+	l = len(m.Passphrase)
+	if l > 0 {
+		n += 1 + l + sovKeys(uint64(l))
+	}
+	l = len(m.Name)
+	if l > 0 {
+		n += 1 + l + sovKeys(uint64(l))
+	}
+	l = len(m.CurveType)
+	if l > 0 {
+		n += 1 + l + sovKeys(uint64(l))
+	}
+	l = len(m.KeyBytes)
+	if l > 0 {
+		n += 1 + l + sovKeys(uint64(l))
+	}
+	return n
+}
+
+func (m *ExportRequest) Size() (n int) {
+	var l int
+	_ = l
+	l = len(m.Passphrase)
+	if l > 0 {
+		n += 1 + l + sovKeys(uint64(l))
+	}
+	l = len(m.Name)
+	if l > 0 {
+		n += 1 + l + sovKeys(uint64(l))
+	}
+	l = len(m.Address)
+	if l > 0 {
+		n += 1 + l + sovKeys(uint64(l))
+	}
+	return n
+}
+
+func (m *ExportResponse) Size() (n int) {
+	var l int
+	_ = l
+	l = len(m.Publickey)
+	if l > 0 {
+		n += 1 + l + sovKeys(uint64(l))
+	}
+	l = len(m.Privatekey)
+	if l > 0 {
+		n += 1 + l + sovKeys(uint64(l))
+	}
+	l = len(m.Address)
+	if l > 0 {
+		n += 1 + l + sovKeys(uint64(l))
+	}
+	l = len(m.CurveType)
+	if l > 0 {
+		n += 1 + l + sovKeys(uint64(l))
+	}
+	return n
+}
+
+func (m *SignRequest) Size() (n int) {
+	var l int
+	_ = l
+	l = len(m.Passphrase)
+	if l > 0 {
+		n += 1 + l + sovKeys(uint64(l))
+	}
+	l = len(m.Address)
+	if l > 0 {
+		n += 1 + l + sovKeys(uint64(l))
+	}
+	l = len(m.Name)
+	if l > 0 {
+		n += 1 + l + sovKeys(uint64(l))
+	}
+	l = len(m.Message)
+	if l > 0 {
+		n += 1 + l + sovKeys(uint64(l))
+	}
+	return n
+}
+
+func (m *SignResponse) Size() (n int) {
+	var l int
+	_ = l
+	l = len(m.Signature)
+	if l > 0 {
+		n += 1 + l + sovKeys(uint64(l))
+	}
+	l = len(m.CurveType)
+	if l > 0 {
+		n += 1 + l + sovKeys(uint64(l))
+	}
+	return n
+}
+
+func (m *VerifyRequest) Size() (n int) {
+	var l int
+	_ = l
+	l = len(m.CurveType)
+	if l > 0 {
+		n += 1 + l + sovKeys(uint64(l))
+	}
+	l = len(m.PublicKey)
+	if l > 0 {
+		n += 1 + l + sovKeys(uint64(l))
+	}
+	l = len(m.Message)
+	if l > 0 {
+		n += 1 + l + sovKeys(uint64(l))
+	}
+	l = len(m.Signature)
+	if l > 0 {
+		n += 1 + l + sovKeys(uint64(l))
+	}
+	return n
+}
+
+func (m *HashRequest) Size() (n int) {
+	var l int
+	_ = l
+	l = len(m.Hashtype)
+	if l > 0 {
+		n += 1 + l + sovKeys(uint64(l))
+	}
+	l = len(m.Message)
+	if l > 0 {
+		n += 1 + l + sovKeys(uint64(l))
+	}
+	return n
+}
+
+func (m *HashResponse) Size() (n int) {
+	var l int
+	_ = l
+	l = len(m.Hash)
+	if l > 0 {
+		n += 1 + l + sovKeys(uint64(l))
+	}
+	return n
+}
+
+func (m *KeyID) Size() (n int) {
+	var l int
+	_ = l
+	l = len(m.Address)
+	if l > 0 {
+		n += 1 + l + sovKeys(uint64(l))
+	}
+	l = len(m.KeyName)
+	if l > 0 {
+		n += 1 + l + sovKeys(uint64(l))
+	}
+	return n
+}
+
+func (m *ListResponse) Size() (n int) {
+	var l int
+	_ = l
+	if len(m.Key) > 0 {
+		for _, e := range m.Key {
+			l = e.Size()
+			n += 1 + l + sovKeys(uint64(l))
+		}
+	}
+	return n
+}
+
+func (m *AddNameRequest) Size() (n int) {
+	var l int
+	_ = l
+	l = len(m.Keyname)
+	if l > 0 {
+		n += 1 + l + sovKeys(uint64(l))
+	}
+	l = len(m.Address)
+	if l > 0 {
+		n += 1 + l + sovKeys(uint64(l))
+	}
+	return n
+}
+
+func sovKeys(x uint64) (n int) {
+	for {
+		n++
+		x >>= 7
+		if x == 0 {
+			break
+		}
+	}
+	return n
+}
+func sozKeys(x uint64) (n int) {
+	return sovKeys(uint64((x << 1) ^ uint64((int64(x) >> 63))))
+}
+func (m *ListRequest) Unmarshal(dAtA []byte) error {
+	l := len(dAtA)
+	iNdEx := 0
+	for iNdEx < l {
+		preIndex := iNdEx
+		var wire uint64
+		for shift := uint(0); ; shift += 7 {
+			if shift >= 64 {
+				return ErrIntOverflowKeys
+			}
+			if iNdEx >= l {
+				return io.ErrUnexpectedEOF
+			}
+			b := dAtA[iNdEx]
+			iNdEx++
+			wire |= (uint64(b) & 0x7F) << shift
+			if b < 0x80 {
+				break
+			}
+		}
+		fieldNum := int32(wire >> 3)
+		wireType := int(wire & 0x7)
+		if wireType == 4 {
+			return fmt.Errorf("proto: ListRequest: wiretype end group for non-group")
+		}
+		if fieldNum <= 0 {
+			return fmt.Errorf("proto: ListRequest: illegal tag %d (wire type %d)", fieldNum, wire)
+		}
+		switch fieldNum {
+		default:
+			iNdEx = preIndex
+			skippy, err := skipKeys(dAtA[iNdEx:])
+			if err != nil {
+				return err
+			}
+			if skippy < 0 {
+				return ErrInvalidLengthKeys
+			}
+			if (iNdEx + skippy) > l {
+				return io.ErrUnexpectedEOF
+			}
+			iNdEx += skippy
+		}
+	}
+
+	if iNdEx > l {
+		return io.ErrUnexpectedEOF
+	}
+	return nil
+}
+func (m *VerifyResponse) Unmarshal(dAtA []byte) error {
+	l := len(dAtA)
+	iNdEx := 0
+	for iNdEx < l {
+		preIndex := iNdEx
+		var wire uint64
+		for shift := uint(0); ; shift += 7 {
+			if shift >= 64 {
+				return ErrIntOverflowKeys
+			}
+			if iNdEx >= l {
+				return io.ErrUnexpectedEOF
+			}
+			b := dAtA[iNdEx]
+			iNdEx++
+			wire |= (uint64(b) & 0x7F) << shift
+			if b < 0x80 {
+				break
+			}
+		}
+		fieldNum := int32(wire >> 3)
+		wireType := int(wire & 0x7)
+		if wireType == 4 {
+			return fmt.Errorf("proto: VerifyResponse: wiretype end group for non-group")
+		}
+		if fieldNum <= 0 {
+			return fmt.Errorf("proto: VerifyResponse: illegal tag %d (wire type %d)", fieldNum, wire)
+		}
+		switch fieldNum {
+		default:
+			iNdEx = preIndex
+			skippy, err := skipKeys(dAtA[iNdEx:])
+			if err != nil {
+				return err
+			}
+			if skippy < 0 {
+				return ErrInvalidLengthKeys
+			}
+			if (iNdEx + skippy) > l {
+				return io.ErrUnexpectedEOF
+			}
+			iNdEx += skippy
+		}
+	}
+
+	if iNdEx > l {
+		return io.ErrUnexpectedEOF
+	}
+	return nil
+}
+func (m *RemoveNameResponse) Unmarshal(dAtA []byte) error {
+	l := len(dAtA)
+	iNdEx := 0
+	for iNdEx < l {
+		preIndex := iNdEx
+		var wire uint64
+		for shift := uint(0); ; shift += 7 {
+			if shift >= 64 {
+				return ErrIntOverflowKeys
+			}
+			if iNdEx >= l {
+				return io.ErrUnexpectedEOF
+			}
+			b := dAtA[iNdEx]
+			iNdEx++
+			wire |= (uint64(b) & 0x7F) << shift
+			if b < 0x80 {
+				break
+			}
+		}
+		fieldNum := int32(wire >> 3)
+		wireType := int(wire & 0x7)
+		if wireType == 4 {
+			return fmt.Errorf("proto: RemoveNameResponse: wiretype end group for non-group")
+		}
+		if fieldNum <= 0 {
+			return fmt.Errorf("proto: RemoveNameResponse: illegal tag %d (wire type %d)", fieldNum, wire)
+		}
+		switch fieldNum {
+		default:
+			iNdEx = preIndex
+			skippy, err := skipKeys(dAtA[iNdEx:])
+			if err != nil {
+				return err
+			}
+			if skippy < 0 {
+				return ErrInvalidLengthKeys
+			}
+			if (iNdEx + skippy) > l {
+				return io.ErrUnexpectedEOF
+			}
+			iNdEx += skippy
+		}
+	}
+
+	if iNdEx > l {
+		return io.ErrUnexpectedEOF
+	}
+	return nil
+}
+func (m *AddNameResponse) Unmarshal(dAtA []byte) error {
+	l := len(dAtA)
+	iNdEx := 0
+	for iNdEx < l {
+		preIndex := iNdEx
+		var wire uint64
+		for shift := uint(0); ; shift += 7 {
+			if shift >= 64 {
+				return ErrIntOverflowKeys
+			}
+			if iNdEx >= l {
+				return io.ErrUnexpectedEOF
+			}
+			b := dAtA[iNdEx]
+			iNdEx++
+			wire |= (uint64(b) & 0x7F) << shift
+			if b < 0x80 {
+				break
+			}
+		}
+		fieldNum := int32(wire >> 3)
+		wireType := int(wire & 0x7)
+		if wireType == 4 {
+			return fmt.Errorf("proto: AddNameResponse: wiretype end group for non-group")
+		}
+		if fieldNum <= 0 {
+			return fmt.Errorf("proto: AddNameResponse: illegal tag %d (wire type %d)", fieldNum, wire)
+		}
+		switch fieldNum {
+		default:
+			iNdEx = preIndex
+			skippy, err := skipKeys(dAtA[iNdEx:])
+			if err != nil {
+				return err
+			}
+			if skippy < 0 {
+				return ErrInvalidLengthKeys
+			}
+			if (iNdEx + skippy) > l {
+				return io.ErrUnexpectedEOF
+			}
+			iNdEx += skippy
+		}
+	}
+
+	if iNdEx > l {
+		return io.ErrUnexpectedEOF
+	}
+	return nil
+}
+func (m *RemoveNameRequest) Unmarshal(dAtA []byte) error {
+	l := len(dAtA)
+	iNdEx := 0
+	for iNdEx < l {
+		preIndex := iNdEx
+		var wire uint64
+		for shift := uint(0); ; shift += 7 {
+			if shift >= 64 {
+				return ErrIntOverflowKeys
+			}
+			if iNdEx >= l {
+				return io.ErrUnexpectedEOF
+			}
+			b := dAtA[iNdEx]
+			iNdEx++
+			wire |= (uint64(b) & 0x7F) << shift
+			if b < 0x80 {
+				break
+			}
+		}
+		fieldNum := int32(wire >> 3)
+		wireType := int(wire & 0x7)
+		if wireType == 4 {
+			return fmt.Errorf("proto: RemoveNameRequest: wiretype end group for non-group")
+		}
+		if fieldNum <= 0 {
+			return fmt.Errorf("proto: RemoveNameRequest: illegal tag %d (wire type %d)", fieldNum, wire)
+		}
+		switch fieldNum {
+		case 1:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field KeyName", wireType)
+			}
+			var stringLen uint64
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowKeys
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				stringLen |= (uint64(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			intStringLen := int(stringLen)
+			if intStringLen < 0 {
+				return ErrInvalidLengthKeys
+			}
+			postIndex := iNdEx + intStringLen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			m.KeyName = string(dAtA[iNdEx:postIndex])
+			iNdEx = postIndex
+		default:
+			iNdEx = preIndex
+			skippy, err := skipKeys(dAtA[iNdEx:])
+			if err != nil {
+				return err
+			}
+			if skippy < 0 {
+				return ErrInvalidLengthKeys
+			}
+			if (iNdEx + skippy) > l {
+				return io.ErrUnexpectedEOF
+			}
+			iNdEx += skippy
+		}
+	}
+
+	if iNdEx > l {
+		return io.ErrUnexpectedEOF
+	}
+	return nil
+}
+func (m *GenRequest) Unmarshal(dAtA []byte) error {
+	l := len(dAtA)
+	iNdEx := 0
+	for iNdEx < l {
+		preIndex := iNdEx
+		var wire uint64
+		for shift := uint(0); ; shift += 7 {
+			if shift >= 64 {
+				return ErrIntOverflowKeys
+			}
+			if iNdEx >= l {
+				return io.ErrUnexpectedEOF
+			}
+			b := dAtA[iNdEx]
+			iNdEx++
+			wire |= (uint64(b) & 0x7F) << shift
+			if b < 0x80 {
+				break
+			}
+		}
+		fieldNum := int32(wire >> 3)
+		wireType := int(wire & 0x7)
+		if wireType == 4 {
+			return fmt.Errorf("proto: GenRequest: wiretype end group for non-group")
+		}
+		if fieldNum <= 0 {
+			return fmt.Errorf("proto: GenRequest: illegal tag %d (wire type %d)", fieldNum, wire)
+		}
+		switch fieldNum {
+		case 1:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Passphrase", wireType)
+			}
+			var stringLen uint64
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowKeys
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				stringLen |= (uint64(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			intStringLen := int(stringLen)
+			if intStringLen < 0 {
+				return ErrInvalidLengthKeys
+			}
+			postIndex := iNdEx + intStringLen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			m.Passphrase = string(dAtA[iNdEx:postIndex])
+			iNdEx = postIndex
+		case 2:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field CurveType", wireType)
+			}
+			var stringLen uint64
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowKeys
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				stringLen |= (uint64(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			intStringLen := int(stringLen)
+			if intStringLen < 0 {
+				return ErrInvalidLengthKeys
+			}
+			postIndex := iNdEx + intStringLen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			m.CurveType = string(dAtA[iNdEx:postIndex])
+			iNdEx = postIndex
+		case 3:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field KeyName", wireType)
+			}
+			var stringLen uint64
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowKeys
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				stringLen |= (uint64(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			intStringLen := int(stringLen)
+			if intStringLen < 0 {
+				return ErrInvalidLengthKeys
+			}
+			postIndex := iNdEx + intStringLen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			m.KeyName = string(dAtA[iNdEx:postIndex])
+			iNdEx = postIndex
+		default:
+			iNdEx = preIndex
+			skippy, err := skipKeys(dAtA[iNdEx:])
+			if err != nil {
+				return err
+			}
+			if skippy < 0 {
+				return ErrInvalidLengthKeys
+			}
+			if (iNdEx + skippy) > l {
+				return io.ErrUnexpectedEOF
+			}
+			iNdEx += skippy
+		}
+	}
+
+	if iNdEx > l {
+		return io.ErrUnexpectedEOF
+	}
+	return nil
+}
+func (m *GenResponse) Unmarshal(dAtA []byte) error {
+	l := len(dAtA)
+	iNdEx := 0
+	for iNdEx < l {
+		preIndex := iNdEx
+		var wire uint64
+		for shift := uint(0); ; shift += 7 {
+			if shift >= 64 {
+				return ErrIntOverflowKeys
+			}
+			if iNdEx >= l {
+				return io.ErrUnexpectedEOF
+			}
+			b := dAtA[iNdEx]
+			iNdEx++
+			wire |= (uint64(b) & 0x7F) << shift
+			if b < 0x80 {
+				break
+			}
+		}
+		fieldNum := int32(wire >> 3)
+		wireType := int(wire & 0x7)
+		if wireType == 4 {
+			return fmt.Errorf("proto: GenResponse: wiretype end group for non-group")
+		}
+		if fieldNum <= 0 {
+			return fmt.Errorf("proto: GenResponse: illegal tag %d (wire type %d)", fieldNum, wire)
+		}
+		switch fieldNum {
+		case 1:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Address", wireType)
+			}
+			var stringLen uint64
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowKeys
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				stringLen |= (uint64(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			intStringLen := int(stringLen)
+			if intStringLen < 0 {
+				return ErrInvalidLengthKeys
+			}
+			postIndex := iNdEx + intStringLen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			m.Address = string(dAtA[iNdEx:postIndex])
+			iNdEx = postIndex
+		default:
+			iNdEx = preIndex
+			skippy, err := skipKeys(dAtA[iNdEx:])
+			if err != nil {
+				return err
+			}
+			if skippy < 0 {
+				return ErrInvalidLengthKeys
+			}
+			if (iNdEx + skippy) > l {
+				return io.ErrUnexpectedEOF
+			}
+			iNdEx += skippy
+		}
+	}
+
+	if iNdEx > l {
+		return io.ErrUnexpectedEOF
+	}
+	return nil
+}
+func (m *PubRequest) Unmarshal(dAtA []byte) error {
+	l := len(dAtA)
+	iNdEx := 0
+	for iNdEx < l {
+		preIndex := iNdEx
+		var wire uint64
+		for shift := uint(0); ; shift += 7 {
+			if shift >= 64 {
+				return ErrIntOverflowKeys
+			}
+			if iNdEx >= l {
+				return io.ErrUnexpectedEOF
+			}
+			b := dAtA[iNdEx]
+			iNdEx++
+			wire |= (uint64(b) & 0x7F) << shift
+			if b < 0x80 {
+				break
+			}
+		}
+		fieldNum := int32(wire >> 3)
+		wireType := int(wire & 0x7)
+		if wireType == 4 {
+			return fmt.Errorf("proto: PubRequest: wiretype end group for non-group")
+		}
+		if fieldNum <= 0 {
+			return fmt.Errorf("proto: PubRequest: illegal tag %d (wire type %d)", fieldNum, wire)
+		}
+		switch fieldNum {
+		case 1:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Address", wireType)
+			}
+			var stringLen uint64
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowKeys
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				stringLen |= (uint64(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			intStringLen := int(stringLen)
+			if intStringLen < 0 {
+				return ErrInvalidLengthKeys
+			}
+			postIndex := iNdEx + intStringLen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			m.Address = string(dAtA[iNdEx:postIndex])
+			iNdEx = postIndex
+		case 2:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType)
+			}
+			var stringLen uint64
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowKeys
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				stringLen |= (uint64(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			intStringLen := int(stringLen)
+			if intStringLen < 0 {
+				return ErrInvalidLengthKeys
+			}
+			postIndex := iNdEx + intStringLen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			m.Name = string(dAtA[iNdEx:postIndex])
+			iNdEx = postIndex
+		default:
+			iNdEx = preIndex
+			skippy, err := skipKeys(dAtA[iNdEx:])
+			if err != nil {
+				return err
+			}
+			if skippy < 0 {
+				return ErrInvalidLengthKeys
+			}
+			if (iNdEx + skippy) > l {
+				return io.ErrUnexpectedEOF
+			}
+			iNdEx += skippy
+		}
+	}
+
+	if iNdEx > l {
+		return io.ErrUnexpectedEOF
+	}
+	return nil
+}
+func (m *PubResponse) Unmarshal(dAtA []byte) error {
+	l := len(dAtA)
+	iNdEx := 0
+	for iNdEx < l {
+		preIndex := iNdEx
+		var wire uint64
+		for shift := uint(0); ; shift += 7 {
+			if shift >= 64 {
+				return ErrIntOverflowKeys
+			}
+			if iNdEx >= l {
+				return io.ErrUnexpectedEOF
+			}
+			b := dAtA[iNdEx]
+			iNdEx++
+			wire |= (uint64(b) & 0x7F) << shift
+			if b < 0x80 {
+				break
+			}
+		}
+		fieldNum := int32(wire >> 3)
+		wireType := int(wire & 0x7)
+		if wireType == 4 {
+			return fmt.Errorf("proto: PubResponse: wiretype end group for non-group")
+		}
+		if fieldNum <= 0 {
+			return fmt.Errorf("proto: PubResponse: illegal tag %d (wire type %d)", fieldNum, wire)
+		}
+		switch fieldNum {
+		case 1:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field PublicKey", wireType)
+			}
+			var byteLen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowKeys
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				byteLen |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if byteLen < 0 {
+				return ErrInvalidLengthKeys
+			}
+			postIndex := iNdEx + byteLen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			m.PublicKey = append(m.PublicKey[:0], dAtA[iNdEx:postIndex]...)
+			if m.PublicKey == nil {
+				m.PublicKey = []byte{}
+			}
+			iNdEx = postIndex
+		case 2:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field CurveType", wireType)
+			}
+			var stringLen uint64
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowKeys
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				stringLen |= (uint64(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			intStringLen := int(stringLen)
+			if intStringLen < 0 {
+				return ErrInvalidLengthKeys
+			}
+			postIndex := iNdEx + intStringLen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			m.CurveType = string(dAtA[iNdEx:postIndex])
+			iNdEx = postIndex
+		default:
+			iNdEx = preIndex
+			skippy, err := skipKeys(dAtA[iNdEx:])
+			if err != nil {
+				return err
+			}
+			if skippy < 0 {
+				return ErrInvalidLengthKeys
+			}
+			if (iNdEx + skippy) > l {
+				return io.ErrUnexpectedEOF
+			}
+			iNdEx += skippy
+		}
+	}
+
+	if iNdEx > l {
+		return io.ErrUnexpectedEOF
+	}
+	return nil
+}
+func (m *ImportJSONRequest) Unmarshal(dAtA []byte) error {
+	l := len(dAtA)
+	iNdEx := 0
+	for iNdEx < l {
+		preIndex := iNdEx
+		var wire uint64
+		for shift := uint(0); ; shift += 7 {
+			if shift >= 64 {
+				return ErrIntOverflowKeys
+			}
+			if iNdEx >= l {
+				return io.ErrUnexpectedEOF
+			}
+			b := dAtA[iNdEx]
+			iNdEx++
+			wire |= (uint64(b) & 0x7F) << shift
+			if b < 0x80 {
+				break
+			}
+		}
+		fieldNum := int32(wire >> 3)
+		wireType := int(wire & 0x7)
+		if wireType == 4 {
+			return fmt.Errorf("proto: ImportJSONRequest: wiretype end group for non-group")
+		}
+		if fieldNum <= 0 {
+			return fmt.Errorf("proto: ImportJSONRequest: illegal tag %d (wire type %d)", fieldNum, wire)
+		}
+		switch fieldNum {
+		case 1:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Passphrase", wireType)
+			}
+			var stringLen uint64
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowKeys
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				stringLen |= (uint64(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			intStringLen := int(stringLen)
+			if intStringLen < 0 {
+				return ErrInvalidLengthKeys
+			}
+			postIndex := iNdEx + intStringLen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			m.Passphrase = string(dAtA[iNdEx:postIndex])
+			iNdEx = postIndex
+		case 2:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field JSON", wireType)
+			}
+			var stringLen uint64
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowKeys
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				stringLen |= (uint64(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			intStringLen := int(stringLen)
+			if intStringLen < 0 {
+				return ErrInvalidLengthKeys
+			}
+			postIndex := iNdEx + intStringLen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			m.JSON = string(dAtA[iNdEx:postIndex])
+			iNdEx = postIndex
+		default:
+			iNdEx = preIndex
+			skippy, err := skipKeys(dAtA[iNdEx:])
+			if err != nil {
+				return err
+			}
+			if skippy < 0 {
+				return ErrInvalidLengthKeys
+			}
+			if (iNdEx + skippy) > l {
+				return io.ErrUnexpectedEOF
+			}
+			iNdEx += skippy
+		}
+	}
+
+	if iNdEx > l {
+		return io.ErrUnexpectedEOF
+	}
+	return nil
+}
+func (m *ImportResponse) Unmarshal(dAtA []byte) error {
+	l := len(dAtA)
+	iNdEx := 0
+	for iNdEx < l {
+		preIndex := iNdEx
+		var wire uint64
+		for shift := uint(0); ; shift += 7 {
+			if shift >= 64 {
+				return ErrIntOverflowKeys
+			}
+			if iNdEx >= l {
+				return io.ErrUnexpectedEOF
+			}
+			b := dAtA[iNdEx]
+			iNdEx++
+			wire |= (uint64(b) & 0x7F) << shift
+			if b < 0x80 {
+				break
+			}
+		}
+		fieldNum := int32(wire >> 3)
+		wireType := int(wire & 0x7)
+		if wireType == 4 {
+			return fmt.Errorf("proto: ImportResponse: wiretype end group for non-group")
+		}
+		if fieldNum <= 0 {
+			return fmt.Errorf("proto: ImportResponse: illegal tag %d (wire type %d)", fieldNum, wire)
+		}
+		switch fieldNum {
+		case 1:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Address", wireType)
+			}
+			var stringLen uint64
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowKeys
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				stringLen |= (uint64(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			intStringLen := int(stringLen)
+			if intStringLen < 0 {
+				return ErrInvalidLengthKeys
+			}
+			postIndex := iNdEx + intStringLen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			m.Address = string(dAtA[iNdEx:postIndex])
+			iNdEx = postIndex
+		default:
+			iNdEx = preIndex
+			skippy, err := skipKeys(dAtA[iNdEx:])
+			if err != nil {
+				return err
+			}
+			if skippy < 0 {
+				return ErrInvalidLengthKeys
+			}
+			if (iNdEx + skippy) > l {
+				return io.ErrUnexpectedEOF
+			}
+			iNdEx += skippy
+		}
+	}
+
+	if iNdEx > l {
+		return io.ErrUnexpectedEOF
+	}
+	return nil
+}
+func (m *ImportRequest) Unmarshal(dAtA []byte) error {
+	l := len(dAtA)
+	iNdEx := 0
+	for iNdEx < l {
+		preIndex := iNdEx
+		var wire uint64
+		for shift := uint(0); ; shift += 7 {
+			if shift >= 64 {
+				return ErrIntOverflowKeys
+			}
+			if iNdEx >= l {
+				return io.ErrUnexpectedEOF
+			}
+			b := dAtA[iNdEx]
+			iNdEx++
+			wire |= (uint64(b) & 0x7F) << shift
+			if b < 0x80 {
+				break
+			}
+		}
+		fieldNum := int32(wire >> 3)
+		wireType := int(wire & 0x7)
+		if wireType == 4 {
+			return fmt.Errorf("proto: ImportRequest: wiretype end group for non-group")
+		}
+		if fieldNum <= 0 {
+			return fmt.Errorf("proto: ImportRequest: illegal tag %d (wire type %d)", fieldNum, wire)
+		}
+		switch fieldNum {
+		case 1:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Passphrase", wireType)
+			}
+			var stringLen uint64
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowKeys
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				stringLen |= (uint64(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			intStringLen := int(stringLen)
+			if intStringLen < 0 {
+				return ErrInvalidLengthKeys
+			}
+			postIndex := iNdEx + intStringLen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			m.Passphrase = string(dAtA[iNdEx:postIndex])
+			iNdEx = postIndex
+		case 2:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType)
+			}
+			var stringLen uint64
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowKeys
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				stringLen |= (uint64(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			intStringLen := int(stringLen)
+			if intStringLen < 0 {
+				return ErrInvalidLengthKeys
+			}
+			postIndex := iNdEx + intStringLen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			m.Name = string(dAtA[iNdEx:postIndex])
+			iNdEx = postIndex
+		case 3:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field CurveType", wireType)
+			}
+			var stringLen uint64
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowKeys
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				stringLen |= (uint64(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			intStringLen := int(stringLen)
+			if intStringLen < 0 {
+				return ErrInvalidLengthKeys
+			}
+			postIndex := iNdEx + intStringLen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			m.CurveType = string(dAtA[iNdEx:postIndex])
+			iNdEx = postIndex
+		case 4:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field KeyBytes", wireType)
+			}
+			var byteLen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowKeys
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				byteLen |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if byteLen < 0 {
+				return ErrInvalidLengthKeys
+			}
+			postIndex := iNdEx + byteLen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			m.KeyBytes = append(m.KeyBytes[:0], dAtA[iNdEx:postIndex]...)
+			if m.KeyBytes == nil {
+				m.KeyBytes = []byte{}
+			}
+			iNdEx = postIndex
+		default:
+			iNdEx = preIndex
+			skippy, err := skipKeys(dAtA[iNdEx:])
+			if err != nil {
+				return err
+			}
+			if skippy < 0 {
+				return ErrInvalidLengthKeys
+			}
+			if (iNdEx + skippy) > l {
+				return io.ErrUnexpectedEOF
+			}
+			iNdEx += skippy
+		}
+	}
+
+	if iNdEx > l {
+		return io.ErrUnexpectedEOF
+	}
+	return nil
+}
+func (m *ExportRequest) Unmarshal(dAtA []byte) error {
+	l := len(dAtA)
+	iNdEx := 0
+	for iNdEx < l {
+		preIndex := iNdEx
+		var wire uint64
+		for shift := uint(0); ; shift += 7 {
+			if shift >= 64 {
+				return ErrIntOverflowKeys
+			}
+			if iNdEx >= l {
+				return io.ErrUnexpectedEOF
+			}
+			b := dAtA[iNdEx]
+			iNdEx++
+			wire |= (uint64(b) & 0x7F) << shift
+			if b < 0x80 {
+				break
+			}
+		}
+		fieldNum := int32(wire >> 3)
+		wireType := int(wire & 0x7)
+		if wireType == 4 {
+			return fmt.Errorf("proto: ExportRequest: wiretype end group for non-group")
+		}
+		if fieldNum <= 0 {
+			return fmt.Errorf("proto: ExportRequest: illegal tag %d (wire type %d)", fieldNum, wire)
+		}
+		switch fieldNum {
+		case 1:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Passphrase", wireType)
+			}
+			var stringLen uint64
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowKeys
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				stringLen |= (uint64(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			intStringLen := int(stringLen)
+			if intStringLen < 0 {
+				return ErrInvalidLengthKeys
+			}
+			postIndex := iNdEx + intStringLen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			m.Passphrase = string(dAtA[iNdEx:postIndex])
+			iNdEx = postIndex
+		case 2:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType)
+			}
+			var stringLen uint64
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowKeys
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				stringLen |= (uint64(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			intStringLen := int(stringLen)
+			if intStringLen < 0 {
+				return ErrInvalidLengthKeys
+			}
+			postIndex := iNdEx + intStringLen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			m.Name = string(dAtA[iNdEx:postIndex])
+			iNdEx = postIndex
+		case 3:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Address", wireType)
+			}
+			var stringLen uint64
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowKeys
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				stringLen |= (uint64(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			intStringLen := int(stringLen)
+			if intStringLen < 0 {
+				return ErrInvalidLengthKeys
+			}
+			postIndex := iNdEx + intStringLen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			m.Address = string(dAtA[iNdEx:postIndex])
+			iNdEx = postIndex
+		default:
+			iNdEx = preIndex
+			skippy, err := skipKeys(dAtA[iNdEx:])
+			if err != nil {
+				return err
+			}
+			if skippy < 0 {
+				return ErrInvalidLengthKeys
+			}
+			if (iNdEx + skippy) > l {
+				return io.ErrUnexpectedEOF
+			}
+			iNdEx += skippy
+		}
+	}
+
+	if iNdEx > l {
+		return io.ErrUnexpectedEOF
+	}
+	return nil
+}
+func (m *ExportResponse) Unmarshal(dAtA []byte) error {
+	l := len(dAtA)
+	iNdEx := 0
+	for iNdEx < l {
+		preIndex := iNdEx
+		var wire uint64
+		for shift := uint(0); ; shift += 7 {
+			if shift >= 64 {
+				return ErrIntOverflowKeys
+			}
+			if iNdEx >= l {
+				return io.ErrUnexpectedEOF
+			}
+			b := dAtA[iNdEx]
+			iNdEx++
+			wire |= (uint64(b) & 0x7F) << shift
+			if b < 0x80 {
+				break
+			}
+		}
+		fieldNum := int32(wire >> 3)
+		wireType := int(wire & 0x7)
+		if wireType == 4 {
+			return fmt.Errorf("proto: ExportResponse: wiretype end group for non-group")
+		}
+		if fieldNum <= 0 {
+			return fmt.Errorf("proto: ExportResponse: illegal tag %d (wire type %d)", fieldNum, wire)
+		}
+		switch fieldNum {
+		case 1:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Publickey", wireType)
+			}
+			var byteLen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowKeys
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				byteLen |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if byteLen < 0 {
+				return ErrInvalidLengthKeys
+			}
+			postIndex := iNdEx + byteLen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			m.Publickey = append(m.Publickey[:0], dAtA[iNdEx:postIndex]...)
+			if m.Publickey == nil {
+				m.Publickey = []byte{}
+			}
+			iNdEx = postIndex
+		case 2:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Privatekey", wireType)
+			}
+			var byteLen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowKeys
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				byteLen |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if byteLen < 0 {
+				return ErrInvalidLengthKeys
+			}
+			postIndex := iNdEx + byteLen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			m.Privatekey = append(m.Privatekey[:0], dAtA[iNdEx:postIndex]...)
+			if m.Privatekey == nil {
+				m.Privatekey = []byte{}
+			}
+			iNdEx = postIndex
+		case 3:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Address", wireType)
+			}
+			var byteLen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowKeys
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				byteLen |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if byteLen < 0 {
+				return ErrInvalidLengthKeys
+			}
+			postIndex := iNdEx + byteLen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			m.Address = append(m.Address[:0], dAtA[iNdEx:postIndex]...)
+			if m.Address == nil {
+				m.Address = []byte{}
+			}
+			iNdEx = postIndex
+		case 4:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field CurveType", wireType)
+			}
+			var stringLen uint64
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowKeys
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				stringLen |= (uint64(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			intStringLen := int(stringLen)
+			if intStringLen < 0 {
+				return ErrInvalidLengthKeys
+			}
+			postIndex := iNdEx + intStringLen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			m.CurveType = string(dAtA[iNdEx:postIndex])
+			iNdEx = postIndex
+		default:
+			iNdEx = preIndex
+			skippy, err := skipKeys(dAtA[iNdEx:])
+			if err != nil {
+				return err
+			}
+			if skippy < 0 {
+				return ErrInvalidLengthKeys
+			}
+			if (iNdEx + skippy) > l {
+				return io.ErrUnexpectedEOF
+			}
+			iNdEx += skippy
+		}
+	}
+
+	if iNdEx > l {
+		return io.ErrUnexpectedEOF
+	}
+	return nil
+}
+func (m *SignRequest) Unmarshal(dAtA []byte) error {
+	l := len(dAtA)
+	iNdEx := 0
+	for iNdEx < l {
+		preIndex := iNdEx
+		var wire uint64
+		for shift := uint(0); ; shift += 7 {
+			if shift >= 64 {
+				return ErrIntOverflowKeys
+			}
+			if iNdEx >= l {
+				return io.ErrUnexpectedEOF
+			}
+			b := dAtA[iNdEx]
+			iNdEx++
+			wire |= (uint64(b) & 0x7F) << shift
+			if b < 0x80 {
+				break
+			}
+		}
+		fieldNum := int32(wire >> 3)
+		wireType := int(wire & 0x7)
+		if wireType == 4 {
+			return fmt.Errorf("proto: SignRequest: wiretype end group for non-group")
+		}
+		if fieldNum <= 0 {
+			return fmt.Errorf("proto: SignRequest: illegal tag %d (wire type %d)", fieldNum, wire)
+		}
+		switch fieldNum {
+		case 1:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Passphrase", wireType)
+			}
+			var stringLen uint64
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowKeys
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				stringLen |= (uint64(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			intStringLen := int(stringLen)
+			if intStringLen < 0 {
+				return ErrInvalidLengthKeys
+			}
+			postIndex := iNdEx + intStringLen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			m.Passphrase = string(dAtA[iNdEx:postIndex])
+			iNdEx = postIndex
+		case 2:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Address", wireType)
+			}
+			var stringLen uint64
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowKeys
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				stringLen |= (uint64(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			intStringLen := int(stringLen)
+			if intStringLen < 0 {
+				return ErrInvalidLengthKeys
+			}
+			postIndex := iNdEx + intStringLen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			m.Address = string(dAtA[iNdEx:postIndex])
+			iNdEx = postIndex
+		case 3:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType)
+			}
+			var stringLen uint64
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowKeys
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				stringLen |= (uint64(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			intStringLen := int(stringLen)
+			if intStringLen < 0 {
+				return ErrInvalidLengthKeys
+			}
+			postIndex := iNdEx + intStringLen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			m.Name = string(dAtA[iNdEx:postIndex])
+			iNdEx = postIndex
+		case 4:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Message", wireType)
+			}
+			var byteLen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowKeys
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				byteLen |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if byteLen < 0 {
+				return ErrInvalidLengthKeys
+			}
+			postIndex := iNdEx + byteLen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			m.Message = append(m.Message[:0], dAtA[iNdEx:postIndex]...)
+			if m.Message == nil {
+				m.Message = []byte{}
+			}
+			iNdEx = postIndex
+		default:
+			iNdEx = preIndex
+			skippy, err := skipKeys(dAtA[iNdEx:])
+			if err != nil {
+				return err
+			}
+			if skippy < 0 {
+				return ErrInvalidLengthKeys
+			}
+			if (iNdEx + skippy) > l {
+				return io.ErrUnexpectedEOF
+			}
+			iNdEx += skippy
+		}
+	}
+
+	if iNdEx > l {
+		return io.ErrUnexpectedEOF
+	}
+	return nil
+}
+func (m *SignResponse) Unmarshal(dAtA []byte) error {
+	l := len(dAtA)
+	iNdEx := 0
+	for iNdEx < l {
+		preIndex := iNdEx
+		var wire uint64
+		for shift := uint(0); ; shift += 7 {
+			if shift >= 64 {
+				return ErrIntOverflowKeys
+			}
+			if iNdEx >= l {
+				return io.ErrUnexpectedEOF
+			}
+			b := dAtA[iNdEx]
+			iNdEx++
+			wire |= (uint64(b) & 0x7F) << shift
+			if b < 0x80 {
+				break
+			}
+		}
+		fieldNum := int32(wire >> 3)
+		wireType := int(wire & 0x7)
+		if wireType == 4 {
+			return fmt.Errorf("proto: SignResponse: wiretype end group for non-group")
+		}
+		if fieldNum <= 0 {
+			return fmt.Errorf("proto: SignResponse: illegal tag %d (wire type %d)", fieldNum, wire)
+		}
+		switch fieldNum {
+		case 1:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Signature", wireType)
+			}
+			var byteLen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowKeys
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				byteLen |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if byteLen < 0 {
+				return ErrInvalidLengthKeys
+			}
+			postIndex := iNdEx + byteLen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			m.Signature = append(m.Signature[:0], dAtA[iNdEx:postIndex]...)
+			if m.Signature == nil {
+				m.Signature = []byte{}
+			}
+			iNdEx = postIndex
+		case 2:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field CurveType", wireType)
+			}
+			var stringLen uint64
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowKeys
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				stringLen |= (uint64(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			intStringLen := int(stringLen)
+			if intStringLen < 0 {
+				return ErrInvalidLengthKeys
+			}
+			postIndex := iNdEx + intStringLen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			m.CurveType = string(dAtA[iNdEx:postIndex])
+			iNdEx = postIndex
+		default:
+			iNdEx = preIndex
+			skippy, err := skipKeys(dAtA[iNdEx:])
+			if err != nil {
+				return err
+			}
+			if skippy < 0 {
+				return ErrInvalidLengthKeys
+			}
+			if (iNdEx + skippy) > l {
+				return io.ErrUnexpectedEOF
+			}
+			iNdEx += skippy
+		}
+	}
+
+	if iNdEx > l {
+		return io.ErrUnexpectedEOF
+	}
+	return nil
+}
+func (m *VerifyRequest) Unmarshal(dAtA []byte) error {
+	l := len(dAtA)
+	iNdEx := 0
+	for iNdEx < l {
+		preIndex := iNdEx
+		var wire uint64
+		for shift := uint(0); ; shift += 7 {
+			if shift >= 64 {
+				return ErrIntOverflowKeys
+			}
+			if iNdEx >= l {
+				return io.ErrUnexpectedEOF
+			}
+			b := dAtA[iNdEx]
+			iNdEx++
+			wire |= (uint64(b) & 0x7F) << shift
+			if b < 0x80 {
+				break
+			}
+		}
+		fieldNum := int32(wire >> 3)
+		wireType := int(wire & 0x7)
+		if wireType == 4 {
+			return fmt.Errorf("proto: VerifyRequest: wiretype end group for non-group")
+		}
+		if fieldNum <= 0 {
+			return fmt.Errorf("proto: VerifyRequest: illegal tag %d (wire type %d)", fieldNum, wire)
+		}
+		switch fieldNum {
+		case 1:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field CurveType", wireType)
+			}
+			var stringLen uint64
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowKeys
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				stringLen |= (uint64(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			intStringLen := int(stringLen)
+			if intStringLen < 0 {
+				return ErrInvalidLengthKeys
+			}
+			postIndex := iNdEx + intStringLen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			m.CurveType = string(dAtA[iNdEx:postIndex])
+			iNdEx = postIndex
+		case 2:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field PublicKey", wireType)
+			}
+			var byteLen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowKeys
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				byteLen |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if byteLen < 0 {
+				return ErrInvalidLengthKeys
+			}
+			postIndex := iNdEx + byteLen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			m.PublicKey = append(m.PublicKey[:0], dAtA[iNdEx:postIndex]...)
+			if m.PublicKey == nil {
+				m.PublicKey = []byte{}
+			}
+			iNdEx = postIndex
+		case 3:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Message", wireType)
+			}
+			var byteLen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowKeys
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				byteLen |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if byteLen < 0 {
+				return ErrInvalidLengthKeys
+			}
+			postIndex := iNdEx + byteLen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			m.Message = append(m.Message[:0], dAtA[iNdEx:postIndex]...)
+			if m.Message == nil {
+				m.Message = []byte{}
+			}
+			iNdEx = postIndex
+		case 4:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Signature", wireType)
+			}
+			var byteLen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowKeys
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				byteLen |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if byteLen < 0 {
+				return ErrInvalidLengthKeys
+			}
+			postIndex := iNdEx + byteLen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			m.Signature = append(m.Signature[:0], dAtA[iNdEx:postIndex]...)
+			if m.Signature == nil {
+				m.Signature = []byte{}
+			}
+			iNdEx = postIndex
+		default:
+			iNdEx = preIndex
+			skippy, err := skipKeys(dAtA[iNdEx:])
+			if err != nil {
+				return err
+			}
+			if skippy < 0 {
+				return ErrInvalidLengthKeys
+			}
+			if (iNdEx + skippy) > l {
+				return io.ErrUnexpectedEOF
+			}
+			iNdEx += skippy
+		}
+	}
+
+	if iNdEx > l {
+		return io.ErrUnexpectedEOF
+	}
+	return nil
+}
+func (m *HashRequest) Unmarshal(dAtA []byte) error {
+	l := len(dAtA)
+	iNdEx := 0
+	for iNdEx < l {
+		preIndex := iNdEx
+		var wire uint64
+		for shift := uint(0); ; shift += 7 {
+			if shift >= 64 {
+				return ErrIntOverflowKeys
+			}
+			if iNdEx >= l {
+				return io.ErrUnexpectedEOF
+			}
+			b := dAtA[iNdEx]
+			iNdEx++
+			wire |= (uint64(b) & 0x7F) << shift
+			if b < 0x80 {
+				break
+			}
+		}
+		fieldNum := int32(wire >> 3)
+		wireType := int(wire & 0x7)
+		if wireType == 4 {
+			return fmt.Errorf("proto: HashRequest: wiretype end group for non-group")
+		}
+		if fieldNum <= 0 {
+			return fmt.Errorf("proto: HashRequest: illegal tag %d (wire type %d)", fieldNum, wire)
+		}
+		switch fieldNum {
+		case 1:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Hashtype", wireType)
+			}
+			var stringLen uint64
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowKeys
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				stringLen |= (uint64(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			intStringLen := int(stringLen)
+			if intStringLen < 0 {
+				return ErrInvalidLengthKeys
+			}
+			postIndex := iNdEx + intStringLen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			m.Hashtype = string(dAtA[iNdEx:postIndex])
+			iNdEx = postIndex
+		case 2:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Message", wireType)
+			}
+			var byteLen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowKeys
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				byteLen |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if byteLen < 0 {
+				return ErrInvalidLengthKeys
+			}
+			postIndex := iNdEx + byteLen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			m.Message = append(m.Message[:0], dAtA[iNdEx:postIndex]...)
+			if m.Message == nil {
+				m.Message = []byte{}
+			}
+			iNdEx = postIndex
+		default:
+			iNdEx = preIndex
+			skippy, err := skipKeys(dAtA[iNdEx:])
+			if err != nil {
+				return err
+			}
+			if skippy < 0 {
+				return ErrInvalidLengthKeys
+			}
+			if (iNdEx + skippy) > l {
+				return io.ErrUnexpectedEOF
+			}
+			iNdEx += skippy
+		}
+	}
+
+	if iNdEx > l {
+		return io.ErrUnexpectedEOF
+	}
+	return nil
+}
+func (m *HashResponse) Unmarshal(dAtA []byte) error {
+	l := len(dAtA)
+	iNdEx := 0
+	for iNdEx < l {
+		preIndex := iNdEx
+		var wire uint64
+		for shift := uint(0); ; shift += 7 {
+			if shift >= 64 {
+				return ErrIntOverflowKeys
+			}
+			if iNdEx >= l {
+				return io.ErrUnexpectedEOF
+			}
+			b := dAtA[iNdEx]
+			iNdEx++
+			wire |= (uint64(b) & 0x7F) << shift
+			if b < 0x80 {
+				break
+			}
+		}
+		fieldNum := int32(wire >> 3)
+		wireType := int(wire & 0x7)
+		if wireType == 4 {
+			return fmt.Errorf("proto: HashResponse: wiretype end group for non-group")
+		}
+		if fieldNum <= 0 {
+			return fmt.Errorf("proto: HashResponse: illegal tag %d (wire type %d)", fieldNum, wire)
+		}
+		switch fieldNum {
+		case 1:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Hash", wireType)
+			}
+			var stringLen uint64
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowKeys
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				stringLen |= (uint64(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			intStringLen := int(stringLen)
+			if intStringLen < 0 {
+				return ErrInvalidLengthKeys
+			}
+			postIndex := iNdEx + intStringLen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			m.Hash = string(dAtA[iNdEx:postIndex])
+			iNdEx = postIndex
+		default:
+			iNdEx = preIndex
+			skippy, err := skipKeys(dAtA[iNdEx:])
+			if err != nil {
+				return err
+			}
+			if skippy < 0 {
+				return ErrInvalidLengthKeys
+			}
+			if (iNdEx + skippy) > l {
+				return io.ErrUnexpectedEOF
+			}
+			iNdEx += skippy
+		}
+	}
+
+	if iNdEx > l {
+		return io.ErrUnexpectedEOF
+	}
+	return nil
+}
+func (m *KeyID) Unmarshal(dAtA []byte) error {
+	l := len(dAtA)
+	iNdEx := 0
+	for iNdEx < l {
+		preIndex := iNdEx
+		var wire uint64
+		for shift := uint(0); ; shift += 7 {
+			if shift >= 64 {
+				return ErrIntOverflowKeys
+			}
+			if iNdEx >= l {
+				return io.ErrUnexpectedEOF
+			}
+			b := dAtA[iNdEx]
+			iNdEx++
+			wire |= (uint64(b) & 0x7F) << shift
+			if b < 0x80 {
+				break
+			}
+		}
+		fieldNum := int32(wire >> 3)
+		wireType := int(wire & 0x7)
+		if wireType == 4 {
+			return fmt.Errorf("proto: KeyID: wiretype end group for non-group")
+		}
+		if fieldNum <= 0 {
+			return fmt.Errorf("proto: KeyID: illegal tag %d (wire type %d)", fieldNum, wire)
+		}
+		switch fieldNum {
+		case 1:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Address", wireType)
+			}
+			var stringLen uint64
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowKeys
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				stringLen |= (uint64(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			intStringLen := int(stringLen)
+			if intStringLen < 0 {
+				return ErrInvalidLengthKeys
+			}
+			postIndex := iNdEx + intStringLen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			m.Address = string(dAtA[iNdEx:postIndex])
+			iNdEx = postIndex
+		case 2:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field KeyName", wireType)
+			}
+			var stringLen uint64
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowKeys
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				stringLen |= (uint64(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			intStringLen := int(stringLen)
+			if intStringLen < 0 {
+				return ErrInvalidLengthKeys
+			}
+			postIndex := iNdEx + intStringLen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			m.KeyName = string(dAtA[iNdEx:postIndex])
+			iNdEx = postIndex
+		default:
+			iNdEx = preIndex
+			skippy, err := skipKeys(dAtA[iNdEx:])
+			if err != nil {
+				return err
+			}
+			if skippy < 0 {
+				return ErrInvalidLengthKeys
+			}
+			if (iNdEx + skippy) > l {
+				return io.ErrUnexpectedEOF
+			}
+			iNdEx += skippy
+		}
+	}
+
+	if iNdEx > l {
+		return io.ErrUnexpectedEOF
+	}
+	return nil
+}
+func (m *ListResponse) Unmarshal(dAtA []byte) error {
+	l := len(dAtA)
+	iNdEx := 0
+	for iNdEx < l {
+		preIndex := iNdEx
+		var wire uint64
+		for shift := uint(0); ; shift += 7 {
+			if shift >= 64 {
+				return ErrIntOverflowKeys
+			}
+			if iNdEx >= l {
+				return io.ErrUnexpectedEOF
+			}
+			b := dAtA[iNdEx]
+			iNdEx++
+			wire |= (uint64(b) & 0x7F) << shift
+			if b < 0x80 {
+				break
+			}
+		}
+		fieldNum := int32(wire >> 3)
+		wireType := int(wire & 0x7)
+		if wireType == 4 {
+			return fmt.Errorf("proto: ListResponse: wiretype end group for non-group")
+		}
+		if fieldNum <= 0 {
+			return fmt.Errorf("proto: ListResponse: illegal tag %d (wire type %d)", fieldNum, wire)
+		}
+		switch fieldNum {
+		case 1:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Key", wireType)
+			}
+			var msglen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowKeys
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				msglen |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if msglen < 0 {
+				return ErrInvalidLengthKeys
+			}
+			postIndex := iNdEx + msglen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			m.Key = append(m.Key, &KeyID{})
+			if err := m.Key[len(m.Key)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+				return err
+			}
+			iNdEx = postIndex
+		default:
+			iNdEx = preIndex
+			skippy, err := skipKeys(dAtA[iNdEx:])
+			if err != nil {
+				return err
+			}
+			if skippy < 0 {
+				return ErrInvalidLengthKeys
+			}
+			if (iNdEx + skippy) > l {
+				return io.ErrUnexpectedEOF
+			}
+			iNdEx += skippy
+		}
+	}
+
+	if iNdEx > l {
+		return io.ErrUnexpectedEOF
+	}
+	return nil
+}
+func (m *AddNameRequest) Unmarshal(dAtA []byte) error {
+	l := len(dAtA)
+	iNdEx := 0
+	for iNdEx < l {
+		preIndex := iNdEx
+		var wire uint64
+		for shift := uint(0); ; shift += 7 {
+			if shift >= 64 {
+				return ErrIntOverflowKeys
+			}
+			if iNdEx >= l {
+				return io.ErrUnexpectedEOF
+			}
+			b := dAtA[iNdEx]
+			iNdEx++
+			wire |= (uint64(b) & 0x7F) << shift
+			if b < 0x80 {
+				break
+			}
+		}
+		fieldNum := int32(wire >> 3)
+		wireType := int(wire & 0x7)
+		if wireType == 4 {
+			return fmt.Errorf("proto: AddNameRequest: wiretype end group for non-group")
+		}
+		if fieldNum <= 0 {
+			return fmt.Errorf("proto: AddNameRequest: illegal tag %d (wire type %d)", fieldNum, wire)
+		}
+		switch fieldNum {
+		case 1:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Keyname", wireType)
+			}
+			var stringLen uint64
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowKeys
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				stringLen |= (uint64(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			intStringLen := int(stringLen)
+			if intStringLen < 0 {
+				return ErrInvalidLengthKeys
+			}
+			postIndex := iNdEx + intStringLen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			m.Keyname = string(dAtA[iNdEx:postIndex])
+			iNdEx = postIndex
+		case 2:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Address", wireType)
+			}
+			var stringLen uint64
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowKeys
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				stringLen |= (uint64(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			intStringLen := int(stringLen)
+			if intStringLen < 0 {
+				return ErrInvalidLengthKeys
+			}
+			postIndex := iNdEx + intStringLen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			m.Address = string(dAtA[iNdEx:postIndex])
+			iNdEx = postIndex
+		default:
+			iNdEx = preIndex
+			skippy, err := skipKeys(dAtA[iNdEx:])
+			if err != nil {
+				return err
+			}
+			if skippy < 0 {
+				return ErrInvalidLengthKeys
+			}
+			if (iNdEx + skippy) > l {
+				return io.ErrUnexpectedEOF
+			}
+			iNdEx += skippy
+		}
+	}
+
+	if iNdEx > l {
+		return io.ErrUnexpectedEOF
+	}
+	return nil
+}
+func skipKeys(dAtA []byte) (n int, err error) {
+	l := len(dAtA)
+	iNdEx := 0
+	for iNdEx < l {
+		var wire uint64
+		for shift := uint(0); ; shift += 7 {
+			if shift >= 64 {
+				return 0, ErrIntOverflowKeys
+			}
+			if iNdEx >= l {
+				return 0, io.ErrUnexpectedEOF
+			}
+			b := dAtA[iNdEx]
+			iNdEx++
+			wire |= (uint64(b) & 0x7F) << shift
+			if b < 0x80 {
+				break
+			}
+		}
+		wireType := int(wire & 0x7)
+		switch wireType {
+		case 0:
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return 0, ErrIntOverflowKeys
+				}
+				if iNdEx >= l {
+					return 0, io.ErrUnexpectedEOF
+				}
+				iNdEx++
+				if dAtA[iNdEx-1] < 0x80 {
+					break
+				}
+			}
+			return iNdEx, nil
+		case 1:
+			iNdEx += 8
+			return iNdEx, nil
+		case 2:
+			var length int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return 0, ErrIntOverflowKeys
+				}
+				if iNdEx >= l {
+					return 0, io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				length |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			iNdEx += length
+			if length < 0 {
+				return 0, ErrInvalidLengthKeys
+			}
+			return iNdEx, nil
+		case 3:
+			for {
+				var innerWire uint64
+				var start int = iNdEx
+				for shift := uint(0); ; shift += 7 {
+					if shift >= 64 {
+						return 0, ErrIntOverflowKeys
+					}
+					if iNdEx >= l {
+						return 0, io.ErrUnexpectedEOF
+					}
+					b := dAtA[iNdEx]
+					iNdEx++
+					innerWire |= (uint64(b) & 0x7F) << shift
+					if b < 0x80 {
+						break
+					}
+				}
+				innerWireType := int(innerWire & 0x7)
+				if innerWireType == 4 {
+					break
+				}
+				next, err := skipKeys(dAtA[start:])
+				if err != nil {
+					return 0, err
+				}
+				iNdEx = start + next
+			}
+			return iNdEx, nil
+		case 4:
+			return iNdEx, nil
+		case 5:
+			iNdEx += 4
+			return iNdEx, nil
+		default:
+			return 0, fmt.Errorf("proto: illegal wireType %d", wireType)
+		}
+	}
+	panic("unreachable")
+}
+
+var (
+	ErrInvalidLengthKeys = fmt.Errorf("proto: negative length found during unmarshaling")
+	ErrIntOverflowKeys   = fmt.Errorf("proto: integer overflow")
+)
+
+func init() { proto.RegisterFile("keys.proto", fileDescriptorKeys) }
+func init() { golang_proto.RegisterFile("keys.proto", fileDescriptorKeys) }
+
+var fileDescriptorKeys = []byte{
+	// 759 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x56, 0x4d, 0x6f, 0xd3, 0x4c,
+	0x10, 0x96, 0x63, 0xbf, 0x7d, 0xdb, 0x71, 0x92, 0xb7, 0xf1, 0x5b, 0x44, 0x64, 0x95, 0x08, 0xed,
+	0x85, 0x0a, 0x29, 0x0d, 0x6a, 0x25, 0x84, 0xe8, 0x01, 0xf5, 0x03, 0x95, 0x36, 0x50, 0xaa, 0x14,
+	0x71, 0x40, 0xe2, 0xe0, 0x34, 0xd3, 0x24, 0x6a, 0x13, 0x87, 0x5d, 0xbb, 0xe0, 0x03, 0x27, 0x24,
+	0x7e, 0x17, 0xc7, 0x9e, 0x10, 0x3f, 0x01, 0xb5, 0x7f, 0x04, 0xed, 0xae, 0x37, 0xde, 0xdd, 0x96,
+	0x12, 0x89, 0xdb, 0xce, 0xec, 0xcc, 0x3e, 0xf3, 0xf1, 0xe4, 0x71, 0x00, 0x4e, 0x31, 0x63, 0xab,
+	0x13, 0x1a, 0x27, 0x71, 0xe0, 0xf1, 0x73, 0xd8, 0xec, 0x0f, 0x93, 0x41, 0xda, 0x5d, 0x3d, 0x8e,
+	0x47, 0xad, 0x7e, 0xdc, 0x8f, 0x5b, 0xe2, 0xb2, 0x9b, 0x9e, 0x08, 0x4b, 0x18, 0xe2, 0x24, 0x93,
+	0x48, 0x05, 0xfc, 0x97, 0x43, 0x96, 0x74, 0xf0, 0x43, 0x8a, 0x2c, 0x21, 0x8b, 0x50, 0x7d, 0x8b,
+	0x74, 0x78, 0x92, 0x75, 0x90, 0x4d, 0xe2, 0x31, 0x43, 0xb2, 0x04, 0x41, 0x07, 0x47, 0xf1, 0x39,
+	0x1e, 0x44, 0x23, 0x9c, 0x7a, 0x6b, 0xf0, 0xdf, 0x66, 0xaf, 0x67, 0xb8, 0x9a, 0x50, 0xd3, 0x03,
+	0xc5, 0x7b, 0x41, 0x1d, 0xfe, 0x6d, 0x63, 0xc6, 0x3d, 0x75, 0xe7, 0xbe, 0xb3, 0xb2, 0xd0, 0x51,
+	0x26, 0xe9, 0x01, 0xec, 0xe2, 0x58, 0xc5, 0x35, 0x00, 0x0e, 0x23, 0xc6, 0x26, 0x03, 0x1a, 0x31,
+	0x15, 0xaa, 0x79, 0x82, 0x65, 0x58, 0xd8, 0x4e, 0xe9, 0x39, 0xbe, 0xc9, 0x26, 0x58, 0x2f, 0x89,
+	0xeb, 0xc2, 0xa1, 0xa3, 0xb8, 0x26, 0xca, 0x03, 0xf0, 0x05, 0x8a, 0xac, 0x91, 0x07, 0x6e, 0xf6,
+	0x7a, 0x14, 0x19, 0x53, 0xe5, 0xe4, 0x26, 0x79, 0x0a, 0x70, 0x98, 0x76, 0xb5, 0xb2, 0x6f, 0x8e,
+	0x0b, 0x02, 0xf0, 0x04, 0x8e, 0xac, 0x41, 0x9c, 0xc9, 0x1e, 0xf8, 0x22, 0x37, 0x07, 0x59, 0x86,
+	0x85, 0xc3, 0xb4, 0x7b, 0x36, 0x3c, 0x6e, 0x63, 0x26, 0xd2, 0xcb, 0x9d, 0xc2, 0x71, 0x7b, 0x27,
+	0x64, 0x17, 0x6a, 0x7b, 0xa3, 0x49, 0x4c, 0x93, 0xfd, 0xa3, 0xd7, 0x07, 0xb3, 0x0e, 0x27, 0x00,
+	0x8f, 0x87, 0xab, 0x9a, 0xf8, 0x99, 0x3c, 0x84, 0xaa, 0x7c, 0x68, 0x86, 0xde, 0x3f, 0x43, 0x45,
+	0xc5, 0xce, 0x0c, 0x68, 0x0f, 0xc1, 0xec, 0xcb, 0xb5, 0x37, 0x14, 0xc2, 0x7c, 0x1b, 0xb3, 0xad,
+	0x2c, 0x41, 0x56, 0xf7, 0xc4, 0x48, 0xa6, 0x36, 0x79, 0x0f, 0x95, 0xe7, 0x9f, 0xfe, 0x16, 0x5e,
+	0xeb, 0xce, 0x35, 0xbb, 0xfb, 0xea, 0x40, 0x55, 0xbd, 0x6f, 0x6f, 0xe8, 0xd4, 0xde, 0xd0, 0x29,
+	0x66, 0x02, 0x9e, 0x0e, 0xcf, 0xa3, 0x04, 0xf9, 0x75, 0x49, 0x5c, 0x6b, 0x1e, 0x1b, 0xaa, 0x5c,
+	0x90, 0xc3, 0x98, 0x81, 0x67, 0xef, 0x36, 0x05, 0xff, 0x68, 0xd8, 0x9f, 0x99, 0xf2, 0x1a, 0x4c,
+	0xe9, 0x66, 0x0e, 0xba, 0x66, 0xff, 0xaf, 0x90, 0xb1, 0xa8, 0x8f, 0xf9, 0x7c, 0x95, 0x49, 0xf6,
+	0xa1, 0x2c, 0x61, 0x8b, 0xe6, 0xb9, 0x1d, 0x25, 0x29, 0x45, 0xd5, 0xfc, 0xd4, 0xf1, 0x07, 0x7a,
+	0x7e, 0x71, 0xa0, 0xa2, 0xf4, 0x41, 0x76, 0x61, 0xc4, 0x3b, 0xf6, 0xda, 0x8d, 0x9f, 0x42, 0xc9,
+	0xfe, 0x29, 0x68, 0x35, 0xbb, 0x46, 0xcd, 0x66, 0x8d, 0x9e, 0x55, 0x23, 0xd9, 0x06, 0xff, 0x45,
+	0xc4, 0x06, 0xaa, 0x84, 0x10, 0xe6, 0xb9, 0x99, 0x14, 0x15, 0x4c, 0x6d, 0x1d, 0xa2, 0x64, 0x8e,
+	0x85, 0x40, 0x59, 0x3e, 0x92, 0x8f, 0x25, 0x00, 0x8f, 0xdb, 0xf9, 0x0b, 0xe2, 0x4c, 0x36, 0xe0,
+	0x9f, 0x36, 0x66, 0x7b, 0x3b, 0xb7, 0xe8, 0x81, 0x26, 0x3d, 0x25, 0x53, 0x7a, 0x9a, 0x50, 0x96,
+	0xca, 0x9a, 0x03, 0xdc, 0x03, 0x57, 0xd2, 0xcd, 0x5d, 0xf1, 0xd7, 0xfc, 0x55, 0x21, 0xdc, 0xe2,
+	0xf5, 0x0e, 0xf7, 0x93, 0x1d, 0xa8, 0x4e, 0x15, 0x55, 0xd7, 0xce, 0xb1, 0xa9, 0x9d, 0x63, 0x8b,
+	0xec, 0x26, 0x35, 0xd6, 0xbe, 0x7b, 0xe0, 0xb5, 0x31, 0x63, 0xc1, 0x9a, 0x10, 0x3e, 0xa4, 0x51,
+	0x82, 0x7c, 0xd4, 0x8b, 0x12, 0xaf, 0x50, 0xdc, 0xb0, 0xa6, 0x79, 0xf2, 0x0a, 0x1f, 0x69, 0xdb,
+	0x52, 0x19, 0x85, 0x28, 0xaa, 0x0c, 0x5d, 0xea, 0x9a, 0xe0, 0xf1, 0xb5, 0x04, 0xf9, 0x95, 0x46,
+	0xef, 0x30, 0xd0, 0x5d, 0x79, 0xf8, 0x3a, 0xcc, 0x49, 0xf6, 0x04, 0xff, 0xcb, 0x5b, 0x83, 0x4b,
+	0xe1, 0x92, 0xe9, 0x2c, 0x92, 0xa4, 0x3a, 0xa9, 0x24, 0x43, 0xab, 0x54, 0x92, 0x25, 0x76, 0x1b,
+	0x00, 0x85, 0x8e, 0x06, 0x77, 0xf5, 0x18, 0x4d, 0x59, 0x7f, 0x93, 0xbc, 0x0e, 0x73, 0x52, 0x30,
+	0x14, 0xa2, 0x21, 0x4f, 0x2a, 0xc9, 0xd2, 0x94, 0xa6, 0xe4, 0x8f, 0x1a, 0x85, 0x46, 0x50, 0x35,
+	0x0a, 0x83, 0x6e, 0xcf, 0x00, 0x8a, 0xaf, 0xa5, 0x2a, 0xf0, 0xda, 0xf7, 0x33, 0xac, 0x5f, 0xbf,
+	0x28, 0xf0, 0x38, 0xbd, 0x14, 0x9e, 0xf6, 0x11, 0x57, 0x78, 0x06, 0xfb, 0x1e, 0x0b, 0xca, 0x08,
+	0xb0, 0xbc, 0x7e, 0x93, 0x6d, 0xe1, 0x1d, 0xcb, 0x2b, 0xf3, 0xb6, 0x9e, 0x5c, 0x5c, 0x36, 0x9c,
+	0x1f, 0x97, 0x0d, 0xe7, 0xe7, 0x65, 0xc3, 0xf9, 0x76, 0xd5, 0x70, 0x2e, 0xae, 0x1a, 0xce, 0x3b,
+	0xa2, 0xfd, 0xc9, 0x18, 0x64, 0x13, 0xa4, 0x67, 0xd8, 0xeb, 0x23, 0x6d, 0x75, 0x53, 0x4a, 0xe3,
+	0x8f, 0x2d, 0xfe, 0x52, 0x77, 0x4e, 0xfc, 0xc1, 0x58, 0xff, 0x15, 0x00, 0x00, 0xff, 0xff, 0xa9,
+	0x48, 0xf7, 0x08, 0xa3, 0x08, 0x00, 0x00,
+}
diff --git a/keys/mock/key.go b/keys/mock/key.go
index 83a7f0010aedd4c4646956b3bd5c6d1060425b73..c3e0ca683a2bcfbe219170596f8b244e638b5aff 100644
--- a/keys/mock/key.go
+++ b/keys/mock/key.go
@@ -5,7 +5,7 @@ import (
 	"encoding/json"
 	"fmt"
 
-	acm "github.com/hyperledger/burrow/account"
+	"github.com/hyperledger/burrow/acm"
 	"github.com/hyperledger/burrow/crypto"
 
 	"github.com/pkg/errors"
@@ -55,7 +55,7 @@ func newKey(name string) (*Key, error) {
 	return key, nil
 }
 
-func mockKeyFromPrivateAccount(privateAccount acm.PrivateAccount) *Key {
+func mockKeyFromPrivateAccount(privateAccount *acm.PrivateAccount) *Key {
 	if privateAccount.PrivateKey().CurveType != crypto.CurveTypeEd25519 {
 		panic(fmt.Errorf("mock key client only supports ed25519 private keys at present"))
 	}
diff --git a/keys/mock/key_client.go b/keys/mock/key_client.go
index a9c646704cc466b027e0ec344a0962117ec7a410..de5527ef95c1fcde22d9b97008603a7ded65331e 100644
--- a/keys/mock/key_client.go
+++ b/keys/mock/key_client.go
@@ -17,7 +17,7 @@ package mock
 import (
 	"fmt"
 
-	acm "github.com/hyperledger/burrow/account"
+	"github.com/hyperledger/burrow/acm"
 	"github.com/hyperledger/burrow/crypto"
 	"github.com/hyperledger/burrow/keys"
 )
@@ -32,7 +32,7 @@ type KeyClient struct {
 	knownKeys map[crypto.Address]*Key
 }
 
-func NewKeyClient(privateAccounts ...acm.PrivateAccount) *KeyClient {
+func NewKeyClient(privateAccounts ...*acm.PrivateAccount) *KeyClient {
 	client := &KeyClient{
 		knownKeys: make(map[crypto.Address]*Key),
 	}
diff --git a/keys/pbkeys/keys.pb.go b/keys/pbkeys/keys.pb.go
deleted file mode 100644
index 320ab041965a12c94c3e0757f810c9602b2f228c..0000000000000000000000000000000000000000
--- a/keys/pbkeys/keys.pb.go
+++ /dev/null
@@ -1,1492 +0,0 @@
-// Code generated by protoc-gen-go. DO NOT EDIT.
-// source: github.com/hyperledger/burrow/keys/pbkeys/keys.proto
-
-package pbkeys
-
-import proto "github.com/golang/protobuf/proto"
-import fmt "fmt"
-import math "math"
-
-import (
-	context "golang.org/x/net/context"
-	grpc "google.golang.org/grpc"
-)
-
-// Reference imports to suppress errors if they are not otherwise used.
-var _ = proto.Marshal
-var _ = fmt.Errorf
-var _ = math.Inf
-
-// This is a compile-time assertion to ensure that this generated file
-// is compatible with the proto package it is being compiled against.
-// A compilation error at this line likely means your copy of the
-// proto package needs to be updated.
-const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
-
-type ListRequest struct {
-	XXX_NoUnkeyedLiteral struct{} `json:"-"`
-	XXX_unrecognized     []byte   `json:"-"`
-	XXX_sizecache        int32    `json:"-"`
-}
-
-func (m *ListRequest) Reset()         { *m = ListRequest{} }
-func (m *ListRequest) String() string { return proto.CompactTextString(m) }
-func (*ListRequest) ProtoMessage()    {}
-func (*ListRequest) Descriptor() ([]byte, []int) {
-	return fileDescriptor_keys_ff2cb7ec9ea3671c, []int{0}
-}
-func (m *ListRequest) XXX_Unmarshal(b []byte) error {
-	return xxx_messageInfo_ListRequest.Unmarshal(m, b)
-}
-func (m *ListRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
-	return xxx_messageInfo_ListRequest.Marshal(b, m, deterministic)
-}
-func (dst *ListRequest) XXX_Merge(src proto.Message) {
-	xxx_messageInfo_ListRequest.Merge(dst, src)
-}
-func (m *ListRequest) XXX_Size() int {
-	return xxx_messageInfo_ListRequest.Size(m)
-}
-func (m *ListRequest) XXX_DiscardUnknown() {
-	xxx_messageInfo_ListRequest.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_ListRequest proto.InternalMessageInfo
-
-type VerifyResponse struct {
-	XXX_NoUnkeyedLiteral struct{} `json:"-"`
-	XXX_unrecognized     []byte   `json:"-"`
-	XXX_sizecache        int32    `json:"-"`
-}
-
-func (m *VerifyResponse) Reset()         { *m = VerifyResponse{} }
-func (m *VerifyResponse) String() string { return proto.CompactTextString(m) }
-func (*VerifyResponse) ProtoMessage()    {}
-func (*VerifyResponse) Descriptor() ([]byte, []int) {
-	return fileDescriptor_keys_ff2cb7ec9ea3671c, []int{1}
-}
-func (m *VerifyResponse) XXX_Unmarshal(b []byte) error {
-	return xxx_messageInfo_VerifyResponse.Unmarshal(m, b)
-}
-func (m *VerifyResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
-	return xxx_messageInfo_VerifyResponse.Marshal(b, m, deterministic)
-}
-func (dst *VerifyResponse) XXX_Merge(src proto.Message) {
-	xxx_messageInfo_VerifyResponse.Merge(dst, src)
-}
-func (m *VerifyResponse) XXX_Size() int {
-	return xxx_messageInfo_VerifyResponse.Size(m)
-}
-func (m *VerifyResponse) XXX_DiscardUnknown() {
-	xxx_messageInfo_VerifyResponse.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_VerifyResponse proto.InternalMessageInfo
-
-type RemoveNameResponse struct {
-	XXX_NoUnkeyedLiteral struct{} `json:"-"`
-	XXX_unrecognized     []byte   `json:"-"`
-	XXX_sizecache        int32    `json:"-"`
-}
-
-func (m *RemoveNameResponse) Reset()         { *m = RemoveNameResponse{} }
-func (m *RemoveNameResponse) String() string { return proto.CompactTextString(m) }
-func (*RemoveNameResponse) ProtoMessage()    {}
-func (*RemoveNameResponse) Descriptor() ([]byte, []int) {
-	return fileDescriptor_keys_ff2cb7ec9ea3671c, []int{2}
-}
-func (m *RemoveNameResponse) XXX_Unmarshal(b []byte) error {
-	return xxx_messageInfo_RemoveNameResponse.Unmarshal(m, b)
-}
-func (m *RemoveNameResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
-	return xxx_messageInfo_RemoveNameResponse.Marshal(b, m, deterministic)
-}
-func (dst *RemoveNameResponse) XXX_Merge(src proto.Message) {
-	xxx_messageInfo_RemoveNameResponse.Merge(dst, src)
-}
-func (m *RemoveNameResponse) XXX_Size() int {
-	return xxx_messageInfo_RemoveNameResponse.Size(m)
-}
-func (m *RemoveNameResponse) XXX_DiscardUnknown() {
-	xxx_messageInfo_RemoveNameResponse.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_RemoveNameResponse proto.InternalMessageInfo
-
-type AddNameResponse struct {
-	XXX_NoUnkeyedLiteral struct{} `json:"-"`
-	XXX_unrecognized     []byte   `json:"-"`
-	XXX_sizecache        int32    `json:"-"`
-}
-
-func (m *AddNameResponse) Reset()         { *m = AddNameResponse{} }
-func (m *AddNameResponse) String() string { return proto.CompactTextString(m) }
-func (*AddNameResponse) ProtoMessage()    {}
-func (*AddNameResponse) Descriptor() ([]byte, []int) {
-	return fileDescriptor_keys_ff2cb7ec9ea3671c, []int{3}
-}
-func (m *AddNameResponse) XXX_Unmarshal(b []byte) error {
-	return xxx_messageInfo_AddNameResponse.Unmarshal(m, b)
-}
-func (m *AddNameResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
-	return xxx_messageInfo_AddNameResponse.Marshal(b, m, deterministic)
-}
-func (dst *AddNameResponse) XXX_Merge(src proto.Message) {
-	xxx_messageInfo_AddNameResponse.Merge(dst, src)
-}
-func (m *AddNameResponse) XXX_Size() int {
-	return xxx_messageInfo_AddNameResponse.Size(m)
-}
-func (m *AddNameResponse) XXX_DiscardUnknown() {
-	xxx_messageInfo_AddNameResponse.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_AddNameResponse proto.InternalMessageInfo
-
-type RemoveNameRequest struct {
-	Keyname              string   `protobuf:"bytes,1,opt,name=keyname,proto3" json:"keyname,omitempty"`
-	XXX_NoUnkeyedLiteral struct{} `json:"-"`
-	XXX_unrecognized     []byte   `json:"-"`
-	XXX_sizecache        int32    `json:"-"`
-}
-
-func (m *RemoveNameRequest) Reset()         { *m = RemoveNameRequest{} }
-func (m *RemoveNameRequest) String() string { return proto.CompactTextString(m) }
-func (*RemoveNameRequest) ProtoMessage()    {}
-func (*RemoveNameRequest) Descriptor() ([]byte, []int) {
-	return fileDescriptor_keys_ff2cb7ec9ea3671c, []int{4}
-}
-func (m *RemoveNameRequest) XXX_Unmarshal(b []byte) error {
-	return xxx_messageInfo_RemoveNameRequest.Unmarshal(m, b)
-}
-func (m *RemoveNameRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
-	return xxx_messageInfo_RemoveNameRequest.Marshal(b, m, deterministic)
-}
-func (dst *RemoveNameRequest) XXX_Merge(src proto.Message) {
-	xxx_messageInfo_RemoveNameRequest.Merge(dst, src)
-}
-func (m *RemoveNameRequest) XXX_Size() int {
-	return xxx_messageInfo_RemoveNameRequest.Size(m)
-}
-func (m *RemoveNameRequest) XXX_DiscardUnknown() {
-	xxx_messageInfo_RemoveNameRequest.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_RemoveNameRequest proto.InternalMessageInfo
-
-func (m *RemoveNameRequest) GetKeyname() string {
-	if m != nil {
-		return m.Keyname
-	}
-	return ""
-}
-
-type GenRequest struct {
-	Passphrase           string   `protobuf:"bytes,1,opt,name=passphrase,proto3" json:"passphrase,omitempty"`
-	Curvetype            string   `protobuf:"bytes,2,opt,name=curvetype,proto3" json:"curvetype,omitempty"`
-	Keyname              string   `protobuf:"bytes,3,opt,name=keyname,proto3" json:"keyname,omitempty"`
-	XXX_NoUnkeyedLiteral struct{} `json:"-"`
-	XXX_unrecognized     []byte   `json:"-"`
-	XXX_sizecache        int32    `json:"-"`
-}
-
-func (m *GenRequest) Reset()         { *m = GenRequest{} }
-func (m *GenRequest) String() string { return proto.CompactTextString(m) }
-func (*GenRequest) ProtoMessage()    {}
-func (*GenRequest) Descriptor() ([]byte, []int) {
-	return fileDescriptor_keys_ff2cb7ec9ea3671c, []int{5}
-}
-func (m *GenRequest) XXX_Unmarshal(b []byte) error {
-	return xxx_messageInfo_GenRequest.Unmarshal(m, b)
-}
-func (m *GenRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
-	return xxx_messageInfo_GenRequest.Marshal(b, m, deterministic)
-}
-func (dst *GenRequest) XXX_Merge(src proto.Message) {
-	xxx_messageInfo_GenRequest.Merge(dst, src)
-}
-func (m *GenRequest) XXX_Size() int {
-	return xxx_messageInfo_GenRequest.Size(m)
-}
-func (m *GenRequest) XXX_DiscardUnknown() {
-	xxx_messageInfo_GenRequest.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_GenRequest proto.InternalMessageInfo
-
-func (m *GenRequest) GetPassphrase() string {
-	if m != nil {
-		return m.Passphrase
-	}
-	return ""
-}
-
-func (m *GenRequest) GetCurvetype() string {
-	if m != nil {
-		return m.Curvetype
-	}
-	return ""
-}
-
-func (m *GenRequest) GetKeyname() string {
-	if m != nil {
-		return m.Keyname
-	}
-	return ""
-}
-
-type GenResponse struct {
-	Address              string   `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"`
-	XXX_NoUnkeyedLiteral struct{} `json:"-"`
-	XXX_unrecognized     []byte   `json:"-"`
-	XXX_sizecache        int32    `json:"-"`
-}
-
-func (m *GenResponse) Reset()         { *m = GenResponse{} }
-func (m *GenResponse) String() string { return proto.CompactTextString(m) }
-func (*GenResponse) ProtoMessage()    {}
-func (*GenResponse) Descriptor() ([]byte, []int) {
-	return fileDescriptor_keys_ff2cb7ec9ea3671c, []int{6}
-}
-func (m *GenResponse) XXX_Unmarshal(b []byte) error {
-	return xxx_messageInfo_GenResponse.Unmarshal(m, b)
-}
-func (m *GenResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
-	return xxx_messageInfo_GenResponse.Marshal(b, m, deterministic)
-}
-func (dst *GenResponse) XXX_Merge(src proto.Message) {
-	xxx_messageInfo_GenResponse.Merge(dst, src)
-}
-func (m *GenResponse) XXX_Size() int {
-	return xxx_messageInfo_GenResponse.Size(m)
-}
-func (m *GenResponse) XXX_DiscardUnknown() {
-	xxx_messageInfo_GenResponse.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_GenResponse proto.InternalMessageInfo
-
-func (m *GenResponse) GetAddress() string {
-	if m != nil {
-		return m.Address
-	}
-	return ""
-}
-
-type PubRequest struct {
-	Address              string   `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"`
-	Name                 string   `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
-	XXX_NoUnkeyedLiteral struct{} `json:"-"`
-	XXX_unrecognized     []byte   `json:"-"`
-	XXX_sizecache        int32    `json:"-"`
-}
-
-func (m *PubRequest) Reset()         { *m = PubRequest{} }
-func (m *PubRequest) String() string { return proto.CompactTextString(m) }
-func (*PubRequest) ProtoMessage()    {}
-func (*PubRequest) Descriptor() ([]byte, []int) {
-	return fileDescriptor_keys_ff2cb7ec9ea3671c, []int{7}
-}
-func (m *PubRequest) XXX_Unmarshal(b []byte) error {
-	return xxx_messageInfo_PubRequest.Unmarshal(m, b)
-}
-func (m *PubRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
-	return xxx_messageInfo_PubRequest.Marshal(b, m, deterministic)
-}
-func (dst *PubRequest) XXX_Merge(src proto.Message) {
-	xxx_messageInfo_PubRequest.Merge(dst, src)
-}
-func (m *PubRequest) XXX_Size() int {
-	return xxx_messageInfo_PubRequest.Size(m)
-}
-func (m *PubRequest) XXX_DiscardUnknown() {
-	xxx_messageInfo_PubRequest.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_PubRequest proto.InternalMessageInfo
-
-func (m *PubRequest) GetAddress() string {
-	if m != nil {
-		return m.Address
-	}
-	return ""
-}
-
-func (m *PubRequest) GetName() string {
-	if m != nil {
-		return m.Name
-	}
-	return ""
-}
-
-type PubResponse struct {
-	Pub                  []byte   `protobuf:"bytes,1,opt,name=pub,proto3" json:"pub,omitempty"`
-	Curvetype            string   `protobuf:"bytes,2,opt,name=curvetype,proto3" json:"curvetype,omitempty"`
-	XXX_NoUnkeyedLiteral struct{} `json:"-"`
-	XXX_unrecognized     []byte   `json:"-"`
-	XXX_sizecache        int32    `json:"-"`
-}
-
-func (m *PubResponse) Reset()         { *m = PubResponse{} }
-func (m *PubResponse) String() string { return proto.CompactTextString(m) }
-func (*PubResponse) ProtoMessage()    {}
-func (*PubResponse) Descriptor() ([]byte, []int) {
-	return fileDescriptor_keys_ff2cb7ec9ea3671c, []int{8}
-}
-func (m *PubResponse) XXX_Unmarshal(b []byte) error {
-	return xxx_messageInfo_PubResponse.Unmarshal(m, b)
-}
-func (m *PubResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
-	return xxx_messageInfo_PubResponse.Marshal(b, m, deterministic)
-}
-func (dst *PubResponse) XXX_Merge(src proto.Message) {
-	xxx_messageInfo_PubResponse.Merge(dst, src)
-}
-func (m *PubResponse) XXX_Size() int {
-	return xxx_messageInfo_PubResponse.Size(m)
-}
-func (m *PubResponse) XXX_DiscardUnknown() {
-	xxx_messageInfo_PubResponse.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_PubResponse proto.InternalMessageInfo
-
-func (m *PubResponse) GetPub() []byte {
-	if m != nil {
-		return m.Pub
-	}
-	return nil
-}
-
-func (m *PubResponse) GetCurvetype() string {
-	if m != nil {
-		return m.Curvetype
-	}
-	return ""
-}
-
-type ImportJSONRequest struct {
-	Passphrase           string   `protobuf:"bytes,1,opt,name=passphrase,proto3" json:"passphrase,omitempty"`
-	JSON                 string   `protobuf:"bytes,2,opt,name=JSON,proto3" json:"JSON,omitempty"`
-	XXX_NoUnkeyedLiteral struct{} `json:"-"`
-	XXX_unrecognized     []byte   `json:"-"`
-	XXX_sizecache        int32    `json:"-"`
-}
-
-func (m *ImportJSONRequest) Reset()         { *m = ImportJSONRequest{} }
-func (m *ImportJSONRequest) String() string { return proto.CompactTextString(m) }
-func (*ImportJSONRequest) ProtoMessage()    {}
-func (*ImportJSONRequest) Descriptor() ([]byte, []int) {
-	return fileDescriptor_keys_ff2cb7ec9ea3671c, []int{9}
-}
-func (m *ImportJSONRequest) XXX_Unmarshal(b []byte) error {
-	return xxx_messageInfo_ImportJSONRequest.Unmarshal(m, b)
-}
-func (m *ImportJSONRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
-	return xxx_messageInfo_ImportJSONRequest.Marshal(b, m, deterministic)
-}
-func (dst *ImportJSONRequest) XXX_Merge(src proto.Message) {
-	xxx_messageInfo_ImportJSONRequest.Merge(dst, src)
-}
-func (m *ImportJSONRequest) XXX_Size() int {
-	return xxx_messageInfo_ImportJSONRequest.Size(m)
-}
-func (m *ImportJSONRequest) XXX_DiscardUnknown() {
-	xxx_messageInfo_ImportJSONRequest.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_ImportJSONRequest proto.InternalMessageInfo
-
-func (m *ImportJSONRequest) GetPassphrase() string {
-	if m != nil {
-		return m.Passphrase
-	}
-	return ""
-}
-
-func (m *ImportJSONRequest) GetJSON() string {
-	if m != nil {
-		return m.JSON
-	}
-	return ""
-}
-
-type ImportResponse struct {
-	Address              string   `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"`
-	XXX_NoUnkeyedLiteral struct{} `json:"-"`
-	XXX_unrecognized     []byte   `json:"-"`
-	XXX_sizecache        int32    `json:"-"`
-}
-
-func (m *ImportResponse) Reset()         { *m = ImportResponse{} }
-func (m *ImportResponse) String() string { return proto.CompactTextString(m) }
-func (*ImportResponse) ProtoMessage()    {}
-func (*ImportResponse) Descriptor() ([]byte, []int) {
-	return fileDescriptor_keys_ff2cb7ec9ea3671c, []int{10}
-}
-func (m *ImportResponse) XXX_Unmarshal(b []byte) error {
-	return xxx_messageInfo_ImportResponse.Unmarshal(m, b)
-}
-func (m *ImportResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
-	return xxx_messageInfo_ImportResponse.Marshal(b, m, deterministic)
-}
-func (dst *ImportResponse) XXX_Merge(src proto.Message) {
-	xxx_messageInfo_ImportResponse.Merge(dst, src)
-}
-func (m *ImportResponse) XXX_Size() int {
-	return xxx_messageInfo_ImportResponse.Size(m)
-}
-func (m *ImportResponse) XXX_DiscardUnknown() {
-	xxx_messageInfo_ImportResponse.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_ImportResponse proto.InternalMessageInfo
-
-func (m *ImportResponse) GetAddress() string {
-	if m != nil {
-		return m.Address
-	}
-	return ""
-}
-
-type ImportRequest struct {
-	Passphrase           string   `protobuf:"bytes,1,opt,name=passphrase,proto3" json:"passphrase,omitempty"`
-	Name                 string   `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
-	Curvetype            string   `protobuf:"bytes,3,opt,name=curvetype,proto3" json:"curvetype,omitempty"`
-	Keybytes             []byte   `protobuf:"bytes,4,opt,name=keybytes,proto3" json:"keybytes,omitempty"`
-	XXX_NoUnkeyedLiteral struct{} `json:"-"`
-	XXX_unrecognized     []byte   `json:"-"`
-	XXX_sizecache        int32    `json:"-"`
-}
-
-func (m *ImportRequest) Reset()         { *m = ImportRequest{} }
-func (m *ImportRequest) String() string { return proto.CompactTextString(m) }
-func (*ImportRequest) ProtoMessage()    {}
-func (*ImportRequest) Descriptor() ([]byte, []int) {
-	return fileDescriptor_keys_ff2cb7ec9ea3671c, []int{11}
-}
-func (m *ImportRequest) XXX_Unmarshal(b []byte) error {
-	return xxx_messageInfo_ImportRequest.Unmarshal(m, b)
-}
-func (m *ImportRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
-	return xxx_messageInfo_ImportRequest.Marshal(b, m, deterministic)
-}
-func (dst *ImportRequest) XXX_Merge(src proto.Message) {
-	xxx_messageInfo_ImportRequest.Merge(dst, src)
-}
-func (m *ImportRequest) XXX_Size() int {
-	return xxx_messageInfo_ImportRequest.Size(m)
-}
-func (m *ImportRequest) XXX_DiscardUnknown() {
-	xxx_messageInfo_ImportRequest.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_ImportRequest proto.InternalMessageInfo
-
-func (m *ImportRequest) GetPassphrase() string {
-	if m != nil {
-		return m.Passphrase
-	}
-	return ""
-}
-
-func (m *ImportRequest) GetName() string {
-	if m != nil {
-		return m.Name
-	}
-	return ""
-}
-
-func (m *ImportRequest) GetCurvetype() string {
-	if m != nil {
-		return m.Curvetype
-	}
-	return ""
-}
-
-func (m *ImportRequest) GetKeybytes() []byte {
-	if m != nil {
-		return m.Keybytes
-	}
-	return nil
-}
-
-type ExportRequest struct {
-	Passphrase           string   `protobuf:"bytes,1,opt,name=passphrase,proto3" json:"passphrase,omitempty"`
-	Name                 string   `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
-	Address              string   `protobuf:"bytes,3,opt,name=address,proto3" json:"address,omitempty"`
-	XXX_NoUnkeyedLiteral struct{} `json:"-"`
-	XXX_unrecognized     []byte   `json:"-"`
-	XXX_sizecache        int32    `json:"-"`
-}
-
-func (m *ExportRequest) Reset()         { *m = ExportRequest{} }
-func (m *ExportRequest) String() string { return proto.CompactTextString(m) }
-func (*ExportRequest) ProtoMessage()    {}
-func (*ExportRequest) Descriptor() ([]byte, []int) {
-	return fileDescriptor_keys_ff2cb7ec9ea3671c, []int{12}
-}
-func (m *ExportRequest) XXX_Unmarshal(b []byte) error {
-	return xxx_messageInfo_ExportRequest.Unmarshal(m, b)
-}
-func (m *ExportRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
-	return xxx_messageInfo_ExportRequest.Marshal(b, m, deterministic)
-}
-func (dst *ExportRequest) XXX_Merge(src proto.Message) {
-	xxx_messageInfo_ExportRequest.Merge(dst, src)
-}
-func (m *ExportRequest) XXX_Size() int {
-	return xxx_messageInfo_ExportRequest.Size(m)
-}
-func (m *ExportRequest) XXX_DiscardUnknown() {
-	xxx_messageInfo_ExportRequest.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_ExportRequest proto.InternalMessageInfo
-
-func (m *ExportRequest) GetPassphrase() string {
-	if m != nil {
-		return m.Passphrase
-	}
-	return ""
-}
-
-func (m *ExportRequest) GetName() string {
-	if m != nil {
-		return m.Name
-	}
-	return ""
-}
-
-func (m *ExportRequest) GetAddress() string {
-	if m != nil {
-		return m.Address
-	}
-	return ""
-}
-
-type ExportResponse struct {
-	Publickey            []byte   `protobuf:"bytes,1,opt,name=publickey,proto3" json:"publickey,omitempty"`
-	Privatekey           []byte   `protobuf:"bytes,2,opt,name=privatekey,proto3" json:"privatekey,omitempty"`
-	Address              []byte   `protobuf:"bytes,3,opt,name=address,proto3" json:"address,omitempty"`
-	Curvetype            string   `protobuf:"bytes,4,opt,name=curvetype,proto3" json:"curvetype,omitempty"`
-	XXX_NoUnkeyedLiteral struct{} `json:"-"`
-	XXX_unrecognized     []byte   `json:"-"`
-	XXX_sizecache        int32    `json:"-"`
-}
-
-func (m *ExportResponse) Reset()         { *m = ExportResponse{} }
-func (m *ExportResponse) String() string { return proto.CompactTextString(m) }
-func (*ExportResponse) ProtoMessage()    {}
-func (*ExportResponse) Descriptor() ([]byte, []int) {
-	return fileDescriptor_keys_ff2cb7ec9ea3671c, []int{13}
-}
-func (m *ExportResponse) XXX_Unmarshal(b []byte) error {
-	return xxx_messageInfo_ExportResponse.Unmarshal(m, b)
-}
-func (m *ExportResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
-	return xxx_messageInfo_ExportResponse.Marshal(b, m, deterministic)
-}
-func (dst *ExportResponse) XXX_Merge(src proto.Message) {
-	xxx_messageInfo_ExportResponse.Merge(dst, src)
-}
-func (m *ExportResponse) XXX_Size() int {
-	return xxx_messageInfo_ExportResponse.Size(m)
-}
-func (m *ExportResponse) XXX_DiscardUnknown() {
-	xxx_messageInfo_ExportResponse.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_ExportResponse proto.InternalMessageInfo
-
-func (m *ExportResponse) GetPublickey() []byte {
-	if m != nil {
-		return m.Publickey
-	}
-	return nil
-}
-
-func (m *ExportResponse) GetPrivatekey() []byte {
-	if m != nil {
-		return m.Privatekey
-	}
-	return nil
-}
-
-func (m *ExportResponse) GetAddress() []byte {
-	if m != nil {
-		return m.Address
-	}
-	return nil
-}
-
-func (m *ExportResponse) GetCurvetype() string {
-	if m != nil {
-		return m.Curvetype
-	}
-	return ""
-}
-
-type SignRequest struct {
-	Passphrase           string   `protobuf:"bytes,1,opt,name=passphrase,proto3" json:"passphrase,omitempty"`
-	Address              string   `protobuf:"bytes,2,opt,name=address,proto3" json:"address,omitempty"`
-	Name                 string   `protobuf:"bytes,3,opt,name=name,proto3" json:"name,omitempty"`
-	Message              []byte   `protobuf:"bytes,4,opt,name=message,proto3" json:"message,omitempty"`
-	XXX_NoUnkeyedLiteral struct{} `json:"-"`
-	XXX_unrecognized     []byte   `json:"-"`
-	XXX_sizecache        int32    `json:"-"`
-}
-
-func (m *SignRequest) Reset()         { *m = SignRequest{} }
-func (m *SignRequest) String() string { return proto.CompactTextString(m) }
-func (*SignRequest) ProtoMessage()    {}
-func (*SignRequest) Descriptor() ([]byte, []int) {
-	return fileDescriptor_keys_ff2cb7ec9ea3671c, []int{14}
-}
-func (m *SignRequest) XXX_Unmarshal(b []byte) error {
-	return xxx_messageInfo_SignRequest.Unmarshal(m, b)
-}
-func (m *SignRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
-	return xxx_messageInfo_SignRequest.Marshal(b, m, deterministic)
-}
-func (dst *SignRequest) XXX_Merge(src proto.Message) {
-	xxx_messageInfo_SignRequest.Merge(dst, src)
-}
-func (m *SignRequest) XXX_Size() int {
-	return xxx_messageInfo_SignRequest.Size(m)
-}
-func (m *SignRequest) XXX_DiscardUnknown() {
-	xxx_messageInfo_SignRequest.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_SignRequest proto.InternalMessageInfo
-
-func (m *SignRequest) GetPassphrase() string {
-	if m != nil {
-		return m.Passphrase
-	}
-	return ""
-}
-
-func (m *SignRequest) GetAddress() string {
-	if m != nil {
-		return m.Address
-	}
-	return ""
-}
-
-func (m *SignRequest) GetName() string {
-	if m != nil {
-		return m.Name
-	}
-	return ""
-}
-
-func (m *SignRequest) GetMessage() []byte {
-	if m != nil {
-		return m.Message
-	}
-	return nil
-}
-
-type SignResponse struct {
-	Signature            []byte   `protobuf:"bytes,1,opt,name=signature,proto3" json:"signature,omitempty"`
-	Curvetype            string   `protobuf:"bytes,2,opt,name=curvetype,proto3" json:"curvetype,omitempty"`
-	XXX_NoUnkeyedLiteral struct{} `json:"-"`
-	XXX_unrecognized     []byte   `json:"-"`
-	XXX_sizecache        int32    `json:"-"`
-}
-
-func (m *SignResponse) Reset()         { *m = SignResponse{} }
-func (m *SignResponse) String() string { return proto.CompactTextString(m) }
-func (*SignResponse) ProtoMessage()    {}
-func (*SignResponse) Descriptor() ([]byte, []int) {
-	return fileDescriptor_keys_ff2cb7ec9ea3671c, []int{15}
-}
-func (m *SignResponse) XXX_Unmarshal(b []byte) error {
-	return xxx_messageInfo_SignResponse.Unmarshal(m, b)
-}
-func (m *SignResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
-	return xxx_messageInfo_SignResponse.Marshal(b, m, deterministic)
-}
-func (dst *SignResponse) XXX_Merge(src proto.Message) {
-	xxx_messageInfo_SignResponse.Merge(dst, src)
-}
-func (m *SignResponse) XXX_Size() int {
-	return xxx_messageInfo_SignResponse.Size(m)
-}
-func (m *SignResponse) XXX_DiscardUnknown() {
-	xxx_messageInfo_SignResponse.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_SignResponse proto.InternalMessageInfo
-
-func (m *SignResponse) GetSignature() []byte {
-	if m != nil {
-		return m.Signature
-	}
-	return nil
-}
-
-func (m *SignResponse) GetCurvetype() string {
-	if m != nil {
-		return m.Curvetype
-	}
-	return ""
-}
-
-type VerifyRequest struct {
-	Curvetype            string   `protobuf:"bytes,1,opt,name=curvetype,proto3" json:"curvetype,omitempty"`
-	Pub                  []byte   `protobuf:"bytes,2,opt,name=pub,proto3" json:"pub,omitempty"`
-	Message              []byte   `protobuf:"bytes,3,opt,name=message,proto3" json:"message,omitempty"`
-	Signature            []byte   `protobuf:"bytes,4,opt,name=signature,proto3" json:"signature,omitempty"`
-	XXX_NoUnkeyedLiteral struct{} `json:"-"`
-	XXX_unrecognized     []byte   `json:"-"`
-	XXX_sizecache        int32    `json:"-"`
-}
-
-func (m *VerifyRequest) Reset()         { *m = VerifyRequest{} }
-func (m *VerifyRequest) String() string { return proto.CompactTextString(m) }
-func (*VerifyRequest) ProtoMessage()    {}
-func (*VerifyRequest) Descriptor() ([]byte, []int) {
-	return fileDescriptor_keys_ff2cb7ec9ea3671c, []int{16}
-}
-func (m *VerifyRequest) XXX_Unmarshal(b []byte) error {
-	return xxx_messageInfo_VerifyRequest.Unmarshal(m, b)
-}
-func (m *VerifyRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
-	return xxx_messageInfo_VerifyRequest.Marshal(b, m, deterministic)
-}
-func (dst *VerifyRequest) XXX_Merge(src proto.Message) {
-	xxx_messageInfo_VerifyRequest.Merge(dst, src)
-}
-func (m *VerifyRequest) XXX_Size() int {
-	return xxx_messageInfo_VerifyRequest.Size(m)
-}
-func (m *VerifyRequest) XXX_DiscardUnknown() {
-	xxx_messageInfo_VerifyRequest.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_VerifyRequest proto.InternalMessageInfo
-
-func (m *VerifyRequest) GetCurvetype() string {
-	if m != nil {
-		return m.Curvetype
-	}
-	return ""
-}
-
-func (m *VerifyRequest) GetPub() []byte {
-	if m != nil {
-		return m.Pub
-	}
-	return nil
-}
-
-func (m *VerifyRequest) GetMessage() []byte {
-	if m != nil {
-		return m.Message
-	}
-	return nil
-}
-
-func (m *VerifyRequest) GetSignature() []byte {
-	if m != nil {
-		return m.Signature
-	}
-	return nil
-}
-
-type HashRequest struct {
-	Hashtype             string   `protobuf:"bytes,1,opt,name=hashtype,proto3" json:"hashtype,omitempty"`
-	Message              []byte   `protobuf:"bytes,2,opt,name=message,proto3" json:"message,omitempty"`
-	XXX_NoUnkeyedLiteral struct{} `json:"-"`
-	XXX_unrecognized     []byte   `json:"-"`
-	XXX_sizecache        int32    `json:"-"`
-}
-
-func (m *HashRequest) Reset()         { *m = HashRequest{} }
-func (m *HashRequest) String() string { return proto.CompactTextString(m) }
-func (*HashRequest) ProtoMessage()    {}
-func (*HashRequest) Descriptor() ([]byte, []int) {
-	return fileDescriptor_keys_ff2cb7ec9ea3671c, []int{17}
-}
-func (m *HashRequest) XXX_Unmarshal(b []byte) error {
-	return xxx_messageInfo_HashRequest.Unmarshal(m, b)
-}
-func (m *HashRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
-	return xxx_messageInfo_HashRequest.Marshal(b, m, deterministic)
-}
-func (dst *HashRequest) XXX_Merge(src proto.Message) {
-	xxx_messageInfo_HashRequest.Merge(dst, src)
-}
-func (m *HashRequest) XXX_Size() int {
-	return xxx_messageInfo_HashRequest.Size(m)
-}
-func (m *HashRequest) XXX_DiscardUnknown() {
-	xxx_messageInfo_HashRequest.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_HashRequest proto.InternalMessageInfo
-
-func (m *HashRequest) GetHashtype() string {
-	if m != nil {
-		return m.Hashtype
-	}
-	return ""
-}
-
-func (m *HashRequest) GetMessage() []byte {
-	if m != nil {
-		return m.Message
-	}
-	return nil
-}
-
-type HashResponse struct {
-	Hash                 string   `protobuf:"bytes,1,opt,name=hash,proto3" json:"hash,omitempty"`
-	XXX_NoUnkeyedLiteral struct{} `json:"-"`
-	XXX_unrecognized     []byte   `json:"-"`
-	XXX_sizecache        int32    `json:"-"`
-}
-
-func (m *HashResponse) Reset()         { *m = HashResponse{} }
-func (m *HashResponse) String() string { return proto.CompactTextString(m) }
-func (*HashResponse) ProtoMessage()    {}
-func (*HashResponse) Descriptor() ([]byte, []int) {
-	return fileDescriptor_keys_ff2cb7ec9ea3671c, []int{18}
-}
-func (m *HashResponse) XXX_Unmarshal(b []byte) error {
-	return xxx_messageInfo_HashResponse.Unmarshal(m, b)
-}
-func (m *HashResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
-	return xxx_messageInfo_HashResponse.Marshal(b, m, deterministic)
-}
-func (dst *HashResponse) XXX_Merge(src proto.Message) {
-	xxx_messageInfo_HashResponse.Merge(dst, src)
-}
-func (m *HashResponse) XXX_Size() int {
-	return xxx_messageInfo_HashResponse.Size(m)
-}
-func (m *HashResponse) XXX_DiscardUnknown() {
-	xxx_messageInfo_HashResponse.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_HashResponse proto.InternalMessageInfo
-
-func (m *HashResponse) GetHash() string {
-	if m != nil {
-		return m.Hash
-	}
-	return ""
-}
-
-type Key struct {
-	Address              string   `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"`
-	Keyname              string   `protobuf:"bytes,2,opt,name=keyname,proto3" json:"keyname,omitempty"`
-	XXX_NoUnkeyedLiteral struct{} `json:"-"`
-	XXX_unrecognized     []byte   `json:"-"`
-	XXX_sizecache        int32    `json:"-"`
-}
-
-func (m *Key) Reset()         { *m = Key{} }
-func (m *Key) String() string { return proto.CompactTextString(m) }
-func (*Key) ProtoMessage()    {}
-func (*Key) Descriptor() ([]byte, []int) {
-	return fileDescriptor_keys_ff2cb7ec9ea3671c, []int{19}
-}
-func (m *Key) XXX_Unmarshal(b []byte) error {
-	return xxx_messageInfo_Key.Unmarshal(m, b)
-}
-func (m *Key) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
-	return xxx_messageInfo_Key.Marshal(b, m, deterministic)
-}
-func (dst *Key) XXX_Merge(src proto.Message) {
-	xxx_messageInfo_Key.Merge(dst, src)
-}
-func (m *Key) XXX_Size() int {
-	return xxx_messageInfo_Key.Size(m)
-}
-func (m *Key) XXX_DiscardUnknown() {
-	xxx_messageInfo_Key.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_Key proto.InternalMessageInfo
-
-func (m *Key) GetAddress() string {
-	if m != nil {
-		return m.Address
-	}
-	return ""
-}
-
-func (m *Key) GetKeyname() string {
-	if m != nil {
-		return m.Keyname
-	}
-	return ""
-}
-
-type ListResponse struct {
-	Key                  []*Key   `protobuf:"bytes,1,rep,name=key,proto3" json:"key,omitempty"`
-	XXX_NoUnkeyedLiteral struct{} `json:"-"`
-	XXX_unrecognized     []byte   `json:"-"`
-	XXX_sizecache        int32    `json:"-"`
-}
-
-func (m *ListResponse) Reset()         { *m = ListResponse{} }
-func (m *ListResponse) String() string { return proto.CompactTextString(m) }
-func (*ListResponse) ProtoMessage()    {}
-func (*ListResponse) Descriptor() ([]byte, []int) {
-	return fileDescriptor_keys_ff2cb7ec9ea3671c, []int{20}
-}
-func (m *ListResponse) XXX_Unmarshal(b []byte) error {
-	return xxx_messageInfo_ListResponse.Unmarshal(m, b)
-}
-func (m *ListResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
-	return xxx_messageInfo_ListResponse.Marshal(b, m, deterministic)
-}
-func (dst *ListResponse) XXX_Merge(src proto.Message) {
-	xxx_messageInfo_ListResponse.Merge(dst, src)
-}
-func (m *ListResponse) XXX_Size() int {
-	return xxx_messageInfo_ListResponse.Size(m)
-}
-func (m *ListResponse) XXX_DiscardUnknown() {
-	xxx_messageInfo_ListResponse.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_ListResponse proto.InternalMessageInfo
-
-func (m *ListResponse) GetKey() []*Key {
-	if m != nil {
-		return m.Key
-	}
-	return nil
-}
-
-type AddNameRequest struct {
-	Keyname              string   `protobuf:"bytes,1,opt,name=keyname,proto3" json:"keyname,omitempty"`
-	Address              string   `protobuf:"bytes,2,opt,name=address,proto3" json:"address,omitempty"`
-	XXX_NoUnkeyedLiteral struct{} `json:"-"`
-	XXX_unrecognized     []byte   `json:"-"`
-	XXX_sizecache        int32    `json:"-"`
-}
-
-func (m *AddNameRequest) Reset()         { *m = AddNameRequest{} }
-func (m *AddNameRequest) String() string { return proto.CompactTextString(m) }
-func (*AddNameRequest) ProtoMessage()    {}
-func (*AddNameRequest) Descriptor() ([]byte, []int) {
-	return fileDescriptor_keys_ff2cb7ec9ea3671c, []int{21}
-}
-func (m *AddNameRequest) XXX_Unmarshal(b []byte) error {
-	return xxx_messageInfo_AddNameRequest.Unmarshal(m, b)
-}
-func (m *AddNameRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
-	return xxx_messageInfo_AddNameRequest.Marshal(b, m, deterministic)
-}
-func (dst *AddNameRequest) XXX_Merge(src proto.Message) {
-	xxx_messageInfo_AddNameRequest.Merge(dst, src)
-}
-func (m *AddNameRequest) XXX_Size() int {
-	return xxx_messageInfo_AddNameRequest.Size(m)
-}
-func (m *AddNameRequest) XXX_DiscardUnknown() {
-	xxx_messageInfo_AddNameRequest.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_AddNameRequest proto.InternalMessageInfo
-
-func (m *AddNameRequest) GetKeyname() string {
-	if m != nil {
-		return m.Keyname
-	}
-	return ""
-}
-
-func (m *AddNameRequest) GetAddress() string {
-	if m != nil {
-		return m.Address
-	}
-	return ""
-}
-
-func init() {
-	proto.RegisterType((*ListRequest)(nil), "pbkeys.ListRequest")
-	proto.RegisterType((*VerifyResponse)(nil), "pbkeys.VerifyResponse")
-	proto.RegisterType((*RemoveNameResponse)(nil), "pbkeys.RemoveNameResponse")
-	proto.RegisterType((*AddNameResponse)(nil), "pbkeys.AddNameResponse")
-	proto.RegisterType((*RemoveNameRequest)(nil), "pbkeys.RemoveNameRequest")
-	proto.RegisterType((*GenRequest)(nil), "pbkeys.GenRequest")
-	proto.RegisterType((*GenResponse)(nil), "pbkeys.GenResponse")
-	proto.RegisterType((*PubRequest)(nil), "pbkeys.PubRequest")
-	proto.RegisterType((*PubResponse)(nil), "pbkeys.PubResponse")
-	proto.RegisterType((*ImportJSONRequest)(nil), "pbkeys.ImportJSONRequest")
-	proto.RegisterType((*ImportResponse)(nil), "pbkeys.ImportResponse")
-	proto.RegisterType((*ImportRequest)(nil), "pbkeys.ImportRequest")
-	proto.RegisterType((*ExportRequest)(nil), "pbkeys.ExportRequest")
-	proto.RegisterType((*ExportResponse)(nil), "pbkeys.ExportResponse")
-	proto.RegisterType((*SignRequest)(nil), "pbkeys.SignRequest")
-	proto.RegisterType((*SignResponse)(nil), "pbkeys.SignResponse")
-	proto.RegisterType((*VerifyRequest)(nil), "pbkeys.VerifyRequest")
-	proto.RegisterType((*HashRequest)(nil), "pbkeys.HashRequest")
-	proto.RegisterType((*HashResponse)(nil), "pbkeys.HashResponse")
-	proto.RegisterType((*Key)(nil), "pbkeys.Key")
-	proto.RegisterType((*ListResponse)(nil), "pbkeys.ListResponse")
-	proto.RegisterType((*AddNameRequest)(nil), "pbkeys.AddNameRequest")
-}
-
-// Reference imports to suppress errors if they are not otherwise used.
-var _ context.Context
-var _ grpc.ClientConn
-
-// This is a compile-time assertion to ensure that this generated file
-// is compatible with the grpc package it is being compiled against.
-const _ = grpc.SupportPackageIsVersion4
-
-// KeysClient is the client API for Keys service.
-//
-// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
-type KeysClient interface {
-	GenerateKey(ctx context.Context, in *GenRequest, opts ...grpc.CallOption) (*GenResponse, error)
-	PublicKey(ctx context.Context, in *PubRequest, opts ...grpc.CallOption) (*PubResponse, error)
-	Sign(ctx context.Context, in *SignRequest, opts ...grpc.CallOption) (*SignResponse, error)
-	Verify(ctx context.Context, in *VerifyRequest, opts ...grpc.CallOption) (*VerifyResponse, error)
-	Import(ctx context.Context, in *ImportRequest, opts ...grpc.CallOption) (*ImportResponse, error)
-	ImportJSON(ctx context.Context, in *ImportJSONRequest, opts ...grpc.CallOption) (*ImportResponse, error)
-	Export(ctx context.Context, in *ExportRequest, opts ...grpc.CallOption) (*ExportResponse, error)
-	Hash(ctx context.Context, in *HashRequest, opts ...grpc.CallOption) (*HashResponse, error)
-	RemoveName(ctx context.Context, in *RemoveNameRequest, opts ...grpc.CallOption) (*RemoveNameResponse, error)
-	List(ctx context.Context, in *ListRequest, opts ...grpc.CallOption) (*ListResponse, error)
-	AddName(ctx context.Context, in *AddNameRequest, opts ...grpc.CallOption) (*AddNameResponse, error)
-}
-
-type keysClient struct {
-	cc *grpc.ClientConn
-}
-
-func NewKeysClient(cc *grpc.ClientConn) KeysClient {
-	return &keysClient{cc}
-}
-
-func (c *keysClient) GenerateKey(ctx context.Context, in *GenRequest, opts ...grpc.CallOption) (*GenResponse, error) {
-	out := new(GenResponse)
-	err := c.cc.Invoke(ctx, "/pbkeys.Keys/GenerateKey", in, out, opts...)
-	if err != nil {
-		return nil, err
-	}
-	return out, nil
-}
-
-func (c *keysClient) PublicKey(ctx context.Context, in *PubRequest, opts ...grpc.CallOption) (*PubResponse, error) {
-	out := new(PubResponse)
-	err := c.cc.Invoke(ctx, "/pbkeys.Keys/PublicKey", in, out, opts...)
-	if err != nil {
-		return nil, err
-	}
-	return out, nil
-}
-
-func (c *keysClient) Sign(ctx context.Context, in *SignRequest, opts ...grpc.CallOption) (*SignResponse, error) {
-	out := new(SignResponse)
-	err := c.cc.Invoke(ctx, "/pbkeys.Keys/Sign", in, out, opts...)
-	if err != nil {
-		return nil, err
-	}
-	return out, nil
-}
-
-func (c *keysClient) Verify(ctx context.Context, in *VerifyRequest, opts ...grpc.CallOption) (*VerifyResponse, error) {
-	out := new(VerifyResponse)
-	err := c.cc.Invoke(ctx, "/pbkeys.Keys/Verify", in, out, opts...)
-	if err != nil {
-		return nil, err
-	}
-	return out, nil
-}
-
-func (c *keysClient) Import(ctx context.Context, in *ImportRequest, opts ...grpc.CallOption) (*ImportResponse, error) {
-	out := new(ImportResponse)
-	err := c.cc.Invoke(ctx, "/pbkeys.Keys/Import", in, out, opts...)
-	if err != nil {
-		return nil, err
-	}
-	return out, nil
-}
-
-func (c *keysClient) ImportJSON(ctx context.Context, in *ImportJSONRequest, opts ...grpc.CallOption) (*ImportResponse, error) {
-	out := new(ImportResponse)
-	err := c.cc.Invoke(ctx, "/pbkeys.Keys/ImportJSON", in, out, opts...)
-	if err != nil {
-		return nil, err
-	}
-	return out, nil
-}
-
-func (c *keysClient) Export(ctx context.Context, in *ExportRequest, opts ...grpc.CallOption) (*ExportResponse, error) {
-	out := new(ExportResponse)
-	err := c.cc.Invoke(ctx, "/pbkeys.Keys/Export", in, out, opts...)
-	if err != nil {
-		return nil, err
-	}
-	return out, nil
-}
-
-func (c *keysClient) Hash(ctx context.Context, in *HashRequest, opts ...grpc.CallOption) (*HashResponse, error) {
-	out := new(HashResponse)
-	err := c.cc.Invoke(ctx, "/pbkeys.Keys/Hash", in, out, opts...)
-	if err != nil {
-		return nil, err
-	}
-	return out, nil
-}
-
-func (c *keysClient) RemoveName(ctx context.Context, in *RemoveNameRequest, opts ...grpc.CallOption) (*RemoveNameResponse, error) {
-	out := new(RemoveNameResponse)
-	err := c.cc.Invoke(ctx, "/pbkeys.Keys/RemoveName", in, out, opts...)
-	if err != nil {
-		return nil, err
-	}
-	return out, nil
-}
-
-func (c *keysClient) List(ctx context.Context, in *ListRequest, opts ...grpc.CallOption) (*ListResponse, error) {
-	out := new(ListResponse)
-	err := c.cc.Invoke(ctx, "/pbkeys.Keys/List", in, out, opts...)
-	if err != nil {
-		return nil, err
-	}
-	return out, nil
-}
-
-func (c *keysClient) AddName(ctx context.Context, in *AddNameRequest, opts ...grpc.CallOption) (*AddNameResponse, error) {
-	out := new(AddNameResponse)
-	err := c.cc.Invoke(ctx, "/pbkeys.Keys/AddName", in, out, opts...)
-	if err != nil {
-		return nil, err
-	}
-	return out, nil
-}
-
-// KeysServer is the server API for Keys service.
-type KeysServer interface {
-	GenerateKey(context.Context, *GenRequest) (*GenResponse, error)
-	PublicKey(context.Context, *PubRequest) (*PubResponse, error)
-	Sign(context.Context, *SignRequest) (*SignResponse, error)
-	Verify(context.Context, *VerifyRequest) (*VerifyResponse, error)
-	Import(context.Context, *ImportRequest) (*ImportResponse, error)
-	ImportJSON(context.Context, *ImportJSONRequest) (*ImportResponse, error)
-	Export(context.Context, *ExportRequest) (*ExportResponse, error)
-	Hash(context.Context, *HashRequest) (*HashResponse, error)
-	RemoveName(context.Context, *RemoveNameRequest) (*RemoveNameResponse, error)
-	List(context.Context, *ListRequest) (*ListResponse, error)
-	AddName(context.Context, *AddNameRequest) (*AddNameResponse, error)
-}
-
-func RegisterKeysServer(s *grpc.Server, srv KeysServer) {
-	s.RegisterService(&_Keys_serviceDesc, srv)
-}
-
-func _Keys_GenerateKey_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
-	in := new(GenRequest)
-	if err := dec(in); err != nil {
-		return nil, err
-	}
-	if interceptor == nil {
-		return srv.(KeysServer).GenerateKey(ctx, in)
-	}
-	info := &grpc.UnaryServerInfo{
-		Server:     srv,
-		FullMethod: "/pbkeys.Keys/GenerateKey",
-	}
-	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
-		return srv.(KeysServer).GenerateKey(ctx, req.(*GenRequest))
-	}
-	return interceptor(ctx, in, info, handler)
-}
-
-func _Keys_PublicKey_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
-	in := new(PubRequest)
-	if err := dec(in); err != nil {
-		return nil, err
-	}
-	if interceptor == nil {
-		return srv.(KeysServer).PublicKey(ctx, in)
-	}
-	info := &grpc.UnaryServerInfo{
-		Server:     srv,
-		FullMethod: "/pbkeys.Keys/PublicKey",
-	}
-	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
-		return srv.(KeysServer).PublicKey(ctx, req.(*PubRequest))
-	}
-	return interceptor(ctx, in, info, handler)
-}
-
-func _Keys_Sign_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
-	in := new(SignRequest)
-	if err := dec(in); err != nil {
-		return nil, err
-	}
-	if interceptor == nil {
-		return srv.(KeysServer).Sign(ctx, in)
-	}
-	info := &grpc.UnaryServerInfo{
-		Server:     srv,
-		FullMethod: "/pbkeys.Keys/Sign",
-	}
-	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
-		return srv.(KeysServer).Sign(ctx, req.(*SignRequest))
-	}
-	return interceptor(ctx, in, info, handler)
-}
-
-func _Keys_Verify_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
-	in := new(VerifyRequest)
-	if err := dec(in); err != nil {
-		return nil, err
-	}
-	if interceptor == nil {
-		return srv.(KeysServer).Verify(ctx, in)
-	}
-	info := &grpc.UnaryServerInfo{
-		Server:     srv,
-		FullMethod: "/pbkeys.Keys/Verify",
-	}
-	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
-		return srv.(KeysServer).Verify(ctx, req.(*VerifyRequest))
-	}
-	return interceptor(ctx, in, info, handler)
-}
-
-func _Keys_Import_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
-	in := new(ImportRequest)
-	if err := dec(in); err != nil {
-		return nil, err
-	}
-	if interceptor == nil {
-		return srv.(KeysServer).Import(ctx, in)
-	}
-	info := &grpc.UnaryServerInfo{
-		Server:     srv,
-		FullMethod: "/pbkeys.Keys/Import",
-	}
-	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
-		return srv.(KeysServer).Import(ctx, req.(*ImportRequest))
-	}
-	return interceptor(ctx, in, info, handler)
-}
-
-func _Keys_ImportJSON_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
-	in := new(ImportJSONRequest)
-	if err := dec(in); err != nil {
-		return nil, err
-	}
-	if interceptor == nil {
-		return srv.(KeysServer).ImportJSON(ctx, in)
-	}
-	info := &grpc.UnaryServerInfo{
-		Server:     srv,
-		FullMethod: "/pbkeys.Keys/ImportJSON",
-	}
-	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
-		return srv.(KeysServer).ImportJSON(ctx, req.(*ImportJSONRequest))
-	}
-	return interceptor(ctx, in, info, handler)
-}
-
-func _Keys_Export_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
-	in := new(ExportRequest)
-	if err := dec(in); err != nil {
-		return nil, err
-	}
-	if interceptor == nil {
-		return srv.(KeysServer).Export(ctx, in)
-	}
-	info := &grpc.UnaryServerInfo{
-		Server:     srv,
-		FullMethod: "/pbkeys.Keys/Export",
-	}
-	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
-		return srv.(KeysServer).Export(ctx, req.(*ExportRequest))
-	}
-	return interceptor(ctx, in, info, handler)
-}
-
-func _Keys_Hash_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
-	in := new(HashRequest)
-	if err := dec(in); err != nil {
-		return nil, err
-	}
-	if interceptor == nil {
-		return srv.(KeysServer).Hash(ctx, in)
-	}
-	info := &grpc.UnaryServerInfo{
-		Server:     srv,
-		FullMethod: "/pbkeys.Keys/Hash",
-	}
-	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
-		return srv.(KeysServer).Hash(ctx, req.(*HashRequest))
-	}
-	return interceptor(ctx, in, info, handler)
-}
-
-func _Keys_RemoveName_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
-	in := new(RemoveNameRequest)
-	if err := dec(in); err != nil {
-		return nil, err
-	}
-	if interceptor == nil {
-		return srv.(KeysServer).RemoveName(ctx, in)
-	}
-	info := &grpc.UnaryServerInfo{
-		Server:     srv,
-		FullMethod: "/pbkeys.Keys/RemoveName",
-	}
-	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
-		return srv.(KeysServer).RemoveName(ctx, req.(*RemoveNameRequest))
-	}
-	return interceptor(ctx, in, info, handler)
-}
-
-func _Keys_List_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
-	in := new(ListRequest)
-	if err := dec(in); err != nil {
-		return nil, err
-	}
-	if interceptor == nil {
-		return srv.(KeysServer).List(ctx, in)
-	}
-	info := &grpc.UnaryServerInfo{
-		Server:     srv,
-		FullMethod: "/pbkeys.Keys/List",
-	}
-	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
-		return srv.(KeysServer).List(ctx, req.(*ListRequest))
-	}
-	return interceptor(ctx, in, info, handler)
-}
-
-func _Keys_AddName_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
-	in := new(AddNameRequest)
-	if err := dec(in); err != nil {
-		return nil, err
-	}
-	if interceptor == nil {
-		return srv.(KeysServer).AddName(ctx, in)
-	}
-	info := &grpc.UnaryServerInfo{
-		Server:     srv,
-		FullMethod: "/pbkeys.Keys/AddName",
-	}
-	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
-		return srv.(KeysServer).AddName(ctx, req.(*AddNameRequest))
-	}
-	return interceptor(ctx, in, info, handler)
-}
-
-var _Keys_serviceDesc = grpc.ServiceDesc{
-	ServiceName: "pbkeys.Keys",
-	HandlerType: (*KeysServer)(nil),
-	Methods: []grpc.MethodDesc{
-		{
-			MethodName: "GenerateKey",
-			Handler:    _Keys_GenerateKey_Handler,
-		},
-		{
-			MethodName: "PublicKey",
-			Handler:    _Keys_PublicKey_Handler,
-		},
-		{
-			MethodName: "Sign",
-			Handler:    _Keys_Sign_Handler,
-		},
-		{
-			MethodName: "Verify",
-			Handler:    _Keys_Verify_Handler,
-		},
-		{
-			MethodName: "Import",
-			Handler:    _Keys_Import_Handler,
-		},
-		{
-			MethodName: "ImportJSON",
-			Handler:    _Keys_ImportJSON_Handler,
-		},
-		{
-			MethodName: "Export",
-			Handler:    _Keys_Export_Handler,
-		},
-		{
-			MethodName: "Hash",
-			Handler:    _Keys_Hash_Handler,
-		},
-		{
-			MethodName: "RemoveName",
-			Handler:    _Keys_RemoveName_Handler,
-		},
-		{
-			MethodName: "List",
-			Handler:    _Keys_List_Handler,
-		},
-		{
-			MethodName: "AddName",
-			Handler:    _Keys_AddName_Handler,
-		},
-	},
-	Streams:  []grpc.StreamDesc{},
-	Metadata: "github.com/hyperledger/burrow/keys/pbkeys/keys.proto",
-}
-
-func init() {
-	proto.RegisterFile("github.com/hyperledger/burrow/keys/pbkeys/keys.proto", fileDescriptor_keys_ff2cb7ec9ea3671c)
-}
-
-var fileDescriptor_keys_ff2cb7ec9ea3671c = []byte{
-	// 716 bytes of a gzipped FileDescriptorProto
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x56, 0xd1, 0x6f, 0xd3, 0x3c,
-	0x10, 0x57, 0x9b, 0xa8, 0x5b, 0x2f, 0x6d, 0xbf, 0xcd, 0xdf, 0xbe, 0x8f, 0x12, 0x0d, 0x84, 0xfc,
-	0xc2, 0x84, 0xb4, 0x56, 0x1b, 0x13, 0x13, 0x93, 0x10, 0x42, 0x03, 0x0d, 0x36, 0x34, 0xa6, 0x4e,
-	0xe2, 0x8d, 0x87, 0x64, 0x3d, 0xda, 0xa8, 0x6b, 0x13, 0xec, 0x64, 0x23, 0x0f, 0xbc, 0xf2, 0x47,
-	0xf3, 0x84, 0x62, 0xc7, 0xb1, 0x9d, 0x6d, 0xac, 0x12, 0x2f, 0xad, 0x7d, 0xbe, 0xbb, 0xdf, 0xdd,
-	0xf9, 0xd7, 0x9f, 0x0b, 0x7b, 0x93, 0x28, 0x9d, 0x66, 0xe1, 0xe0, 0x22, 0x9e, 0x0f, 0xa7, 0x79,
-	0x82, 0xec, 0x12, 0xc7, 0x13, 0x64, 0xc3, 0x30, 0x63, 0x2c, 0xbe, 0x1e, 0xce, 0x30, 0xe7, 0xc3,
-	0x24, 0x14, 0x5f, 0xc5, 0xc7, 0x20, 0x61, 0x71, 0x1a, 0x93, 0x96, 0x34, 0xd1, 0x2e, 0x78, 0x1f,
-	0x23, 0x9e, 0x8e, 0xf0, 0x5b, 0x86, 0x3c, 0xa5, 0x6b, 0xd0, 0xfb, 0x8c, 0x2c, 0xfa, 0x9a, 0x8f,
-	0x90, 0x27, 0xf1, 0x82, 0x23, 0xdd, 0x00, 0x32, 0xc2, 0x79, 0x7c, 0x85, 0xa7, 0xc1, 0x1c, 0x2b,
-	0xeb, 0x3a, 0xfc, 0xf3, 0x66, 0x3c, 0xb6, 0x4c, 0xdb, 0xb0, 0x6e, 0x3a, 0x8a, 0x7c, 0xa4, 0x0f,
-	0x2b, 0x33, 0xcc, 0x17, 0xc1, 0x1c, 0xfb, 0x8d, 0x27, 0x8d, 0xad, 0xf6, 0x48, 0x6d, 0xe9, 0x18,
-	0xe0, 0x08, 0x17, 0xca, 0xef, 0x31, 0x40, 0x12, 0x70, 0x9e, 0x4c, 0x59, 0xc0, 0x95, 0xab, 0x61,
-	0x21, 0x9b, 0xd0, 0xbe, 0xc8, 0xd8, 0x15, 0xa6, 0x79, 0x82, 0xfd, 0xa6, 0x38, 0xd6, 0x06, 0x13,
-	0xc5, 0xb1, 0x51, 0x9e, 0x82, 0x27, 0x50, 0x64, 0x8d, 0x85, 0x63, 0x30, 0x1e, 0x33, 0xe4, 0x5c,
-	0x95, 0x53, 0x6e, 0xe9, 0x01, 0xc0, 0x59, 0x16, 0x1a, 0x65, 0xdf, 0xee, 0x47, 0x08, 0xb8, 0x02,
-	0x47, 0xd6, 0x20, 0xd6, 0xf4, 0x15, 0x78, 0x22, 0xb6, 0x04, 0x59, 0x03, 0x27, 0xc9, 0x42, 0x11,
-	0xd8, 0x19, 0x15, 0xcb, 0x3f, 0x57, 0x4f, 0x8f, 0x60, 0xfd, 0xc3, 0x3c, 0x89, 0x59, 0x7a, 0x7c,
-	0xfe, 0xe9, 0x74, 0xd9, 0x81, 0x10, 0x70, 0x0b, 0x77, 0x55, 0x47, 0xb1, 0xa6, 0xcf, 0xa0, 0x27,
-	0x13, 0x2d, 0xd1, 0xef, 0x0f, 0xe8, 0x2a, 0xdf, 0xa5, 0x01, 0xeb, 0x8d, 0xdb, 0x7d, 0x39, 0xf5,
-	0x5b, 0xf1, 0x61, 0x75, 0x86, 0x79, 0x98, 0xa7, 0xc8, 0xfb, 0xae, 0x18, 0x46, 0xb5, 0xa7, 0x5f,
-	0xa0, 0xfb, 0xee, 0xfb, 0xdf, 0xc2, 0x1b, 0xdd, 0x39, 0x76, 0x77, 0x3f, 0x1b, 0xd0, 0x53, 0xf9,
-	0xcb, 0x51, 0x6c, 0x42, 0x3b, 0xc9, 0xc2, 0xcb, 0xe8, 0x62, 0x86, 0x79, 0x79, 0x37, 0xda, 0x20,
-	0xe0, 0x59, 0x74, 0x15, 0xa4, 0x58, 0x1c, 0x37, 0xc5, 0xb1, 0x61, 0xa9, 0x43, 0x75, 0x34, 0x21,
-	0xac, 0x19, 0xb8, 0xf5, 0xbb, 0xcd, 0xc0, 0x3b, 0x8f, 0x26, 0x4b, 0xd3, 0xdc, 0x80, 0x69, 0xde,
-	0xce, 0x3b, 0xc7, 0xee, 0x7f, 0x8e, 0x9c, 0x07, 0x13, 0x2c, 0xe7, 0xab, 0xb6, 0xf4, 0x18, 0x3a,
-	0x12, 0x56, 0x37, 0xcf, 0xa3, 0xc9, 0x22, 0x48, 0x33, 0x86, 0xaa, 0xf9, 0xca, 0x70, 0x0f, 0x3d,
-	0xaf, 0xa1, 0xab, 0x24, 0x41, 0x36, 0x61, 0xb9, 0x37, 0xea, 0xb7, 0x5e, 0xb2, 0xbf, 0xa9, 0xd9,
-	0x6f, 0x94, 0xe9, 0x58, 0x65, 0xda, 0x65, 0xb9, 0xb5, 0xb2, 0xe8, 0x21, 0x78, 0xef, 0x03, 0x3e,
-	0x55, 0xb0, 0x3e, 0xac, 0x4e, 0x03, 0x3e, 0x35, 0x50, 0xab, 0xbd, 0x09, 0xd1, 0xb4, 0x27, 0x41,
-	0xa1, 0x23, 0x93, 0x94, 0x93, 0x20, 0xe0, 0x16, 0x51, 0x65, 0x06, 0xb1, 0xa6, 0x2f, 0xc1, 0x39,
-	0xb1, 0xef, 0xb8, 0xf6, 0xa3, 0x37, 0xf4, 0xa5, 0x69, 0xeb, 0xcb, 0x36, 0x74, 0xa4, 0x7c, 0x96,
-	0xe9, 0x1f, 0x81, 0x23, 0xf9, 0xe5, 0x6c, 0x79, 0xbb, 0xde, 0x40, 0x8a, 0xec, 0xe0, 0x04, 0xf3,
-	0x51, 0x61, 0xa7, 0x6f, 0xa1, 0x57, 0xc9, 0xe6, 0x3d, 0x02, 0x79, 0x37, 0x17, 0x76, 0x7f, 0xb9,
-	0xe0, 0x9e, 0x60, 0xce, 0xc9, 0x0b, 0xa1, 0x6e, 0xc8, 0x82, 0x14, 0x8b, 0x06, 0x88, 0xc2, 0xd3,
-	0xc2, 0xea, 0xff, 0x6b, 0xd9, 0xca, 0x2a, 0xf7, 0xa0, 0x7d, 0x26, 0xa8, 0x6f, 0x45, 0x69, 0xfd,
-	0xd3, 0x51, 0xa6, 0xae, 0xed, 0x80, 0x5b, 0x90, 0x8a, 0x54, 0x87, 0x06, 0xb3, 0xfd, 0x0d, 0xdb,
-	0x58, 0x86, 0xec, 0x43, 0x4b, 0x72, 0x87, 0xfc, 0xa7, 0xce, 0x2d, 0x2e, 0xf9, 0xff, 0xd7, 0xcd,
-	0x3a, 0x50, 0xca, 0x93, 0x0e, 0xb4, 0xe4, 0x4a, 0x07, 0xd6, 0x14, 0xef, 0x35, 0x80, 0x16, 0x53,
-	0xf2, 0xd0, 0xf6, 0x32, 0x04, 0xf6, 0xce, 0x04, 0xfb, 0xd0, 0x92, 0xca, 0xa1, 0x91, 0x2d, 0xa5,
-	0xd2, 0x81, 0x35, 0x81, 0xd9, 0x01, 0xb7, 0x60, 0x9a, 0x1e, 0x8f, 0x41, 0x5e, 0x3d, 0x1e, 0x8b,
-	0x8c, 0x87, 0x00, 0xfa, 0xc9, 0xd4, 0xc5, 0xde, 0x78, 0x46, 0x7d, 0xff, 0xb6, 0x23, 0x8d, 0x5b,
-	0x50, 0x50, 0xe3, 0x1a, 0xef, 0xb9, 0xc6, 0xb5, 0x58, 0x7a, 0x00, 0x2b, 0x25, 0x0d, 0x49, 0xd5,
-	0x8d, 0xcd, 0x4b, 0xff, 0xc1, 0x0d, 0xbb, 0x8c, 0x0d, 0x5b, 0xe2, 0xff, 0xc3, 0xf3, 0xdf, 0x01,
-	0x00, 0x00, 0xff, 0xff, 0x73, 0x20, 0x9f, 0xdf, 0x77, 0x08, 0x00, 0x00,
-}
diff --git a/keys/pbkeys/keys.proto b/keys/pbkeys/keys.proto
deleted file mode 100644
index b1ceeb4cd3e4c2daf5bd0d7340d7a25043bdb54f..0000000000000000000000000000000000000000
--- a/keys/pbkeys/keys.proto
+++ /dev/null
@@ -1,131 +0,0 @@
-syntax = "proto3";
-
-package pbkeys;
-
-service Keys {
-    rpc GenerateKey(GenRequest) returns (GenResponse);
-    rpc PublicKey(PubRequest) returns (PubResponse);
-    rpc Sign(SignRequest) returns (SignResponse);
-    rpc Verify(VerifyRequest) returns (VerifyResponse);
-    rpc Import(ImportRequest) returns (ImportResponse);
-    rpc ImportJSON(ImportJSONRequest) returns (ImportResponse);
-    rpc Export(ExportRequest) returns (ExportResponse);
-    rpc Hash(HashRequest) returns (HashResponse);
-    rpc RemoveName(RemoveNameRequest) returns (RemoveNameResponse);
-    rpc List(ListRequest) returns (ListResponse);
-    rpc AddName(AddNameRequest) returns (AddNameResponse);
-}
-
-// Some empty types we may define later
-
-message ListRequest {
-
-}
-
-message VerifyResponse {
-
-}
-
-message RemoveNameResponse {
-
-}
-
-message AddNameResponse {
-
-}
-
-message RemoveNameRequest {
-    string keyname = 1;
-}
-
-
-message GenRequest {
-    string passphrase = 1;
-    string curvetype = 2;
-    string keyname = 3;
-}
-
-message GenResponse {
-    string address = 1;
-}
-
-message PubRequest {
-    string address = 1;
-    string name = 2;
-} 
-
-message PubResponse {
-    bytes pub = 1;
-    string curvetype = 2;
-}
-
-message ImportJSONRequest {
-    string passphrase = 1;
-    string JSON = 2;
-}
-
-message ImportResponse {
-    string address = 1;
-}
-
-message ImportRequest {
-    string passphrase = 1;
-    string name = 2;
-    string curvetype = 3;
-    bytes keybytes = 4;
-}
-
-message ExportRequest {
-    string passphrase = 1;
-    string name = 2;
-    string address = 3;
-}
-
-message ExportResponse {
-    bytes publickey = 1;
-    bytes privatekey = 2;
-    bytes address = 3;
-    string curvetype = 4;
-}
-
-message SignRequest {
-    string passphrase = 1;
-    string address = 2;
-    string name = 3;
-    bytes message = 4;
-}
-
-message SignResponse {
-    bytes signature = 1;
-    string curvetype = 2;
-}
-
-message VerifyRequest {
-    string curvetype = 1;
-    bytes pub = 2;
-    bytes message = 3;
-    bytes signature = 4;
-}
-
-message HashRequest {
-    string hashtype = 1;
-    bytes message = 2;
-}
-
-message HashResponse {
-    string hash = 1;
-}
-
-message Key {
-    string address = 1;
-    string keyname = 2;
-}
-
-message ListResponse {
-    repeated Key key = 1;
-}
-
-message AddNameRequest {
-    string keyname = 1;
-    string address = 2;
-}
diff --git a/keys/server.go b/keys/server.go
index 576c819c656fdda11e9286d7bc562f511c825f2a..5613a7b529a90cea442250101c69dd0952eb147d 100644
--- a/keys/server.go
+++ b/keys/server.go
@@ -9,7 +9,6 @@ import (
 	"strings"
 
 	"github.com/hyperledger/burrow/crypto"
-	"github.com/hyperledger/burrow/keys/pbkeys"
 	"github.com/hyperledger/burrow/logging"
 	"github.com/tmthrgd/go-hex"
 	"golang.org/x/crypto/ripemd160"
@@ -26,15 +25,15 @@ func StartStandAloneServer(keysDir, host, port string, AllowBadFilePermissions b
 		return err
 	}
 	grpcServer := grpc.NewServer()
-	pbkeys.RegisterKeysServer(grpcServer, NewKeyStore(keysDir, AllowBadFilePermissions, logger))
+	RegisterKeysServer(grpcServer, NewKeyStore(keysDir, AllowBadFilePermissions, logger))
 	return grpcServer.Serve(listen)
 }
 
 //------------------------------------------------------------------------
 // handlers
 
-func (k *KeyStore) GenerateKey(ctx context.Context, in *pbkeys.GenRequest) (*pbkeys.GenResponse, error) {
-	curveT, err := crypto.CurveTypeFromString(in.Curvetype)
+func (k *KeyStore) GenerateKey(ctx context.Context, in *GenRequest) (*GenResponse, error) {
+	curveT, err := crypto.CurveTypeFromString(in.CurveType)
 	if err != nil {
 		return nil, err
 	}
@@ -45,17 +44,17 @@ func (k *KeyStore) GenerateKey(ctx context.Context, in *pbkeys.GenRequest) (*pbk
 	}
 
 	addrH := key.Address.String()
-	if in.Keyname != "" {
-		err = coreNameAdd(k.keysDirPath, in.Keyname, addrH)
+	if in.KeyName != "" {
+		err = coreNameAdd(k.keysDirPath, in.KeyName, addrH)
 		if err != nil {
 			return nil, err
 		}
 	}
 
-	return &pbkeys.GenResponse{Address: addrH}, nil
+	return &GenResponse{Address: addrH}, nil
 }
 
-func (k *KeyStore) Export(ctx context.Context, in *pbkeys.ExportRequest) (*pbkeys.ExportResponse, error) {
+func (k *KeyStore) Export(ctx context.Context, in *ExportRequest) (*ExportResponse, error) {
 	addr, err := getNameAddr(k.keysDirPath, in.GetName(), in.GetAddress())
 
 	if err != nil {
@@ -73,15 +72,15 @@ func (k *KeyStore) Export(ctx context.Context, in *pbkeys.ExportRequest) (*pbkey
 		return nil, err
 	}
 
-	return &pbkeys.ExportResponse{
+	return &ExportResponse{
 		Address:    addrB[:],
-		Curvetype:  key.CurveType.String(),
+		CurveType:  key.CurveType.String(),
 		Publickey:  key.PublicKey.PublicKey[:],
 		Privatekey: key.PrivateKey.PrivateKey[:],
 	}, nil
 }
 
-func (k *KeyStore) PublicKey(ctx context.Context, in *pbkeys.PubRequest) (*pbkeys.PubResponse, error) {
+func (k *KeyStore) PublicKey(ctx context.Context, in *PubRequest) (*PubResponse, error) {
 	addr, err := getNameAddr(k.keysDirPath, in.GetName(), in.GetAddress())
 	if err != nil {
 		return nil, err
@@ -98,10 +97,10 @@ func (k *KeyStore) PublicKey(ctx context.Context, in *pbkeys.PubRequest) (*pbkey
 		return nil, err
 	}
 
-	return &pbkeys.PubResponse{Curvetype: key.CurveType.String(), Pub: key.Pubkey()}, nil
+	return &PubResponse{CurveType: key.CurveType.String(), PublicKey: key.Pubkey()}, nil
 }
 
-func (k *KeyStore) Sign(ctx context.Context, in *pbkeys.SignRequest) (*pbkeys.SignResponse, error) {
+func (k *KeyStore) Sign(ctx context.Context, in *SignRequest) (*SignResponse, error) {
 	addr, err := getNameAddr(k.keysDirPath, in.GetName(), in.GetAddress())
 	if err != nil {
 		return nil, err
@@ -119,11 +118,11 @@ func (k *KeyStore) Sign(ctx context.Context, in *pbkeys.SignRequest) (*pbkeys.Si
 
 	sig, err := key.Sign(in.GetMessage())
 
-	return &pbkeys.SignResponse{Signature: sig, Curvetype: key.CurveType.String()}, nil
+	return &SignResponse{Signature: sig, CurveType: key.CurveType.String()}, nil
 }
 
-func (k *KeyStore) Verify(ctx context.Context, in *pbkeys.VerifyRequest) (*pbkeys.VerifyResponse, error) {
-	if in.GetPub() == nil {
+func (k *KeyStore) Verify(ctx context.Context, in *VerifyRequest) (*VerifyResponse, error) {
+	if in.GetPublicKey() == nil {
 		return nil, fmt.Errorf("must provide a pubkey")
 	}
 	if in.GetMessage() == nil {
@@ -133,7 +132,7 @@ func (k *KeyStore) Verify(ctx context.Context, in *pbkeys.VerifyRequest) (*pbkey
 		return nil, fmt.Errorf("must provide a signature")
 	}
 
-	curveT, err := crypto.CurveTypeFromString(in.GetCurvetype())
+	curveT, err := crypto.CurveTypeFromString(in.GetCurveType())
 	if err != nil {
 		return nil, err
 	}
@@ -141,7 +140,7 @@ func (k *KeyStore) Verify(ctx context.Context, in *pbkeys.VerifyRequest) (*pbkey
 	if err != nil {
 		return nil, err
 	}
-	pubkey, err := crypto.PublicKeyFromBytes(in.GetPub(), curveT)
+	pubkey, err := crypto.PublicKeyFromBytes(in.GetPublicKey(), curveT)
 	if err != nil {
 		return nil, err
 	}
@@ -150,10 +149,10 @@ func (k *KeyStore) Verify(ctx context.Context, in *pbkeys.VerifyRequest) (*pbkey
 		return nil, fmt.Errorf("Signature does not match")
 	}
 
-	return &pbkeys.VerifyResponse{}, nil
+	return &VerifyResponse{}, nil
 }
 
-func (k *KeyStore) Hash(ctx context.Context, in *pbkeys.HashRequest) (*pbkeys.HashResponse, error) {
+func (k *KeyStore) Hash(ctx context.Context, in *HashRequest) (*HashResponse, error) {
 	var hasher hash.Hash
 	switch in.GetHashtype() {
 	case "ripemd160":
@@ -167,10 +166,10 @@ func (k *KeyStore) Hash(ctx context.Context, in *pbkeys.HashRequest) (*pbkeys.Ha
 
 	hasher.Write(in.GetMessage())
 
-	return &pbkeys.HashResponse{Hash: hex.EncodeUpperToString(hasher.Sum(nil))}, nil
+	return &HashResponse{Hash: hex.EncodeUpperToString(hasher.Sum(nil))}, nil
 }
 
-func (k *KeyStore) ImportJSON(ctx context.Context, in *pbkeys.ImportJSONRequest) (*pbkeys.ImportResponse, error) {
+func (k *KeyStore) ImportJSON(ctx context.Context, in *ImportJSONRequest) (*ImportResponse, error) {
 	keyJSON := []byte(in.GetJSON())
 	var err error
 	addr := IsValidKeyJson(keyJSON)
@@ -182,15 +181,15 @@ func (k *KeyStore) ImportJSON(ctx context.Context, in *pbkeys.ImportJSONRequest)
 	if err != nil {
 		return nil, err
 	}
-	return &pbkeys.ImportResponse{Address: hex.EncodeUpperToString(addr)}, nil
+	return &ImportResponse{Address: hex.EncodeUpperToString(addr)}, nil
 }
 
-func (k *KeyStore) Import(ctx context.Context, in *pbkeys.ImportRequest) (*pbkeys.ImportResponse, error) {
-	curveT, err := crypto.CurveTypeFromString(in.GetCurvetype())
+func (k *KeyStore) Import(ctx context.Context, in *ImportRequest) (*ImportResponse, error) {
+	curveT, err := crypto.CurveTypeFromString(in.GetCurveType())
 	if err != nil {
 		return nil, err
 	}
-	key, err := NewKeyFromPriv(curveT, in.GetKeybytes())
+	key, err := NewKeyFromPriv(curveT, in.GetKeyBytes())
 	if err != nil {
 		return nil, err
 	}
@@ -205,33 +204,33 @@ func (k *KeyStore) Import(ctx context.Context, in *pbkeys.ImportRequest) (*pbkey
 			return nil, err
 		}
 	}
-	return &pbkeys.ImportResponse{Address: hex.EncodeUpperToString(key.Address[:])}, nil
+	return &ImportResponse{Address: hex.EncodeUpperToString(key.Address[:])}, nil
 }
 
-func (k *KeyStore) List(ctx context.Context, in *pbkeys.ListRequest) (*pbkeys.ListResponse, error) {
+func (k *KeyStore) List(ctx context.Context, in *ListRequest) (*ListResponse, error) {
 	names, err := coreNameList(k.keysDirPath)
 	if err != nil {
 		return nil, err
 	}
 
-	var list []*pbkeys.Key
+	var list []*KeyID
 
 	for name, addr := range names {
-		list = append(list, &pbkeys.Key{Keyname: name, Address: addr})
+		list = append(list, &KeyID{KeyName: name, Address: addr})
 	}
 
-	return &pbkeys.ListResponse{Key: list}, nil
+	return &ListResponse{Key: list}, nil
 }
 
-func (k *KeyStore) RemoveName(ctx context.Context, in *pbkeys.RemoveNameRequest) (*pbkeys.RemoveNameResponse, error) {
-	if in.GetKeyname() == "" {
+func (k *KeyStore) RemoveName(ctx context.Context, in *RemoveNameRequest) (*RemoveNameResponse, error) {
+	if in.GetKeyName() == "" {
 		return nil, fmt.Errorf("please specify a name")
 	}
 
-	return &pbkeys.RemoveNameResponse{}, coreNameRm(k.keysDirPath, in.GetKeyname())
+	return &RemoveNameResponse{}, coreNameRm(k.keysDirPath, in.GetKeyName())
 }
 
-func (k *KeyStore) AddName(ctx context.Context, in *pbkeys.AddNameRequest) (*pbkeys.AddNameResponse, error) {
+func (k *KeyStore) AddName(ctx context.Context, in *AddNameRequest) (*AddNameResponse, error) {
 	if in.GetKeyname() == "" {
 		return nil, fmt.Errorf("please specify a name")
 	}
@@ -240,5 +239,5 @@ func (k *KeyStore) AddName(ctx context.Context, in *pbkeys.AddNameRequest) (*pbk
 		return nil, fmt.Errorf("please specify an address")
 	}
 
-	return &pbkeys.AddNameResponse{}, coreNameAdd(k.keysDirPath, in.GetKeyname(), strings.ToUpper(in.GetAddress()))
+	return &AddNameResponse{}, coreNameAdd(k.keysDirPath, in.GetKeyname(), strings.ToUpper(in.GetAddress()))
 }
diff --git a/keys/server_test.go b/keys/server_test.go
index 5ee1e204f571b3d61781b0ca73ef4b6aaf126761..68ed229b225c1d2a6c3ea5a2104e4b14950ff5fb 100644
--- a/keys/server_test.go
+++ b/keys/server_test.go
@@ -13,7 +13,6 @@ import (
 
 	"github.com/hyperledger/burrow/crypto"
 	"github.com/hyperledger/burrow/execution/evm/sha3"
-	"github.com/hyperledger/burrow/keys/pbkeys"
 	"github.com/hyperledger/burrow/logging"
 	tm_crypto "github.com/tendermint/go-crypto"
 	"google.golang.org/grpc"
@@ -52,7 +51,7 @@ func init() {
 	}
 }
 
-func grpcKeysClient() pbkeys.KeysClient {
+func grpcKeysClient() KeysClient {
 	var opts []grpc.DialOption
 	opts = append(opts, grpc.WithInsecure())
 	conn, err := grpc.Dial(DefaultHost+":"+TestPort, opts...)
@@ -60,7 +59,7 @@ func grpcKeysClient() pbkeys.KeysClient {
 		fmt.Printf("Failed to connect to grpc server: %v\n", err)
 		os.Exit(1)
 	}
-	return pbkeys.NewKeysClient(conn)
+	return NewKeysClient(conn)
 }
 
 func checkAddrFromPub(typ string, pub, addr []byte) error {
@@ -90,12 +89,12 @@ func testServerKeygenAndPub(t *testing.T, typ string) {
 	c := grpcKeysClient()
 	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
 	defer cancel()
-	genresp, err := c.GenerateKey(ctx, &pbkeys.GenRequest{Curvetype: typ})
+	genresp, err := c.GenerateKey(ctx, &GenRequest{CurveType: typ})
 	if err != nil {
 		t.Fatal(err)
 	}
 	addr := genresp.Address
-	resp, err := c.PublicKey(ctx, &pbkeys.PubRequest{Address: addr})
+	resp, err := c.PublicKey(ctx, &PubRequest{Address: addr})
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -103,7 +102,7 @@ func testServerKeygenAndPub(t *testing.T, typ string) {
 	if err != nil {
 		t.Fatal(err)
 	}
-	if err = checkAddrFromPub(typ, resp.GetPub(), addrB[:]); err != nil {
+	if err = checkAddrFromPub(typ, resp.GetPublicKey(), addrB[:]); err != nil {
 		t.Fatal(err)
 	}
 }
@@ -118,23 +117,27 @@ func testServerSignAndVerify(t *testing.T, typ string) {
 	c := grpcKeysClient()
 	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
 	defer cancel()
-	genresp, err := c.GenerateKey(ctx, &pbkeys.GenRequest{Curvetype: typ})
+	genresp, err := c.GenerateKey(ctx, &GenRequest{CurveType: typ})
 	if err != nil {
 		t.Fatal(err)
 	}
 	addr := genresp.Address
-	resp, err := c.PublicKey(ctx, &pbkeys.PubRequest{Address: addr})
+	resp, err := c.PublicKey(ctx, &PubRequest{Address: addr})
 	if err != nil {
 		t.Fatal(err)
 	}
 	hash := sha3.Sha3([]byte("the hash of something!"))
 
-	sig, err := c.Sign(ctx, &pbkeys.SignRequest{Address: addr, Message: hash})
+	sig, err := c.Sign(ctx, &SignRequest{Address: addr, Message: hash})
 	if err != nil {
 		t.Fatal(err)
 	}
 
-	_, err = c.Verify(ctx, &pbkeys.VerifyRequest{Signature: sig.GetSignature(), Pub: resp.GetPub(), Message: hash, Curvetype: typ})
+	_, err = c.Verify(ctx, &VerifyRequest{
+		Signature: sig.GetSignature(),
+		PublicKey: resp.GetPublicKey(),
+		Message:   hash,
+		CurveType: typ})
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -153,7 +156,7 @@ func testServerHash(t *testing.T, typ string) {
 	c := grpcKeysClient()
 	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
 	defer cancel()
-	resp, err := c.Hash(ctx, &pbkeys.HashRequest{Hashtype: typ, Message: []byte(data)})
+	resp, err := c.Hash(ctx, &HashRequest{Hashtype: typ, Message: []byte(data)})
 	if err != nil {
 		t.Fatal(err)
 	}
diff --git a/permission/types/account_permissions.go b/permission/account_permissions.go
similarity index 93%
rename from permission/types/account_permissions.go
rename to permission/account_permissions.go
index 91bee5f818dde74fd8f5a351ff84085da6ccbe17..6de0a44312c892bfbe1639caeba610ddb3ba0727 100644
--- a/permission/types/account_permissions.go
+++ b/permission/account_permissions.go
@@ -1,12 +1,7 @@
-package types
+package permission
 
 import "github.com/hyperledger/burrow/binary"
 
-type AccountPermissions struct {
-	Base  BasePermissions
-	Roles []string
-}
-
 // Returns true if the role is found
 func (ap AccountPermissions) HasRole(role string) bool {
 	role = string(binary.RightPadBytes([]byte(role), 32))
diff --git a/permission/types/base_permissions.go b/permission/base_permissions.go
similarity index 83%
rename from permission/types/base_permissions.go
rename to permission/base_permissions.go
index 401f46d1225a4589311cfa8472ce52310bbd576c..8aa80cd47607a3ef28a21e4b427aa93ef7d67c13 100644
--- a/permission/types/base_permissions.go
+++ b/permission/base_permissions.go
@@ -1,16 +1,7 @@
-package types
+package permission
 
 import "fmt"
 
-// Base chain permissions struct
-type BasePermissions struct {
-	// bit array with "has"/"doesn't have" for each permission
-	Perms PermFlag
-
-	// bit array with "set"/"not set" for each permission (not-set should fall back to global)
-	SetBit PermFlag
-}
-
 // Gets the permission value.
 // ErrValueNotSet is returned if the permission's set bits are not all on,
 // and should be caught by caller so the global permission can be fetched
@@ -74,5 +65,3 @@ func (bp BasePermissions) Compose(bpFallthrough BasePermissions) BasePermissions
 func (bp BasePermissions) String() string {
 	return fmt.Sprintf("Base: %b; Set: %b", bp.Perms, bp.SetBit)
 }
-
-//---------------------------------------------------------------------------------------------
diff --git a/permission/types/base_permissions_test.go b/permission/base_permissions_test.go
similarity index 99%
rename from permission/types/base_permissions_test.go
rename to permission/base_permissions_test.go
index 700006c45898858406c91bddcd4151b86146cf5f..9d0b8f288b8930e8ed62f42661129293c45d0305 100644
--- a/permission/types/base_permissions_test.go
+++ b/permission/base_permissions_test.go
@@ -1,4 +1,4 @@
-package types
+package permission
 
 import (
 	"strconv"
diff --git a/permission/types/errors.go b/permission/errors.go
similarity index 98%
rename from permission/types/errors.go
rename to permission/errors.go
index 0b022277e9352561b2fe83a655f750c6a146d21f..316ee913d8be0166990ef52d54bb7f26385582d5 100644
--- a/permission/types/errors.go
+++ b/permission/errors.go
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package types
+package permission
 
 import (
 	"fmt"
diff --git a/permission/types/perm_flag.go b/permission/perm_flag.go
similarity index 99%
rename from permission/types/perm_flag.go
rename to permission/perm_flag.go
index c749aa308b6f3e1b292b0e30cefc4a4030958b24..617aa561fcc425fdff99ffc3e5d84bf0f3fb79c3 100644
--- a/permission/types/perm_flag.go
+++ b/permission/perm_flag.go
@@ -1,4 +1,4 @@
-package types
+package permission
 
 import (
 	"fmt"
diff --git a/permission/types/perm_flag_test.go b/permission/perm_flag_test.go
similarity index 91%
rename from permission/types/perm_flag_test.go
rename to permission/perm_flag_test.go
index 2ec7a6edb257f51ff897cc7d29151df051706e3a..5d930a7c703809a04adbf4cfe2512249b1490481 100644
--- a/permission/types/perm_flag_test.go
+++ b/permission/perm_flag_test.go
@@ -1,4 +1,4 @@
-package types
+package permission
 
 import (
 	"testing"
diff --git a/permission/permission.pb.go b/permission/permission.pb.go
new file mode 100644
index 0000000000000000000000000000000000000000..b72986011d0be70e3ed447ac9745961bd7388b3e
--- /dev/null
+++ b/permission/permission.pb.go
@@ -0,0 +1,844 @@
+// Code generated by protoc-gen-gogo. DO NOT EDIT.
+// source: permission.proto
+
+/*
+	Package permission is a generated protocol buffer package.
+
+	It is generated from these files:
+		permission.proto
+
+	It has these top-level messages:
+		AccountPermissions
+		BasePermissions
+		PermArgs
+*/
+package permission
+
+import proto "github.com/gogo/protobuf/proto"
+import golang_proto "github.com/golang/protobuf/proto"
+import fmt "fmt"
+import math "math"
+import _ "github.com/gogo/protobuf/gogoproto"
+
+import github_com_hyperledger_burrow_crypto "github.com/hyperledger/burrow/crypto"
+
+import io "io"
+
+// Reference imports to suppress errors if they are not otherwise used.
+var _ = proto.Marshal
+var _ = golang_proto.Marshal
+var _ = fmt.Errorf
+var _ = math.Inf
+
+// This is a compile-time assertion to ensure that this generated file
+// is compatible with the proto package it is being compiled against.
+// A compilation error at this line likely means your copy of the
+// proto package needs to be updated.
+const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package
+
+type AccountPermissions struct {
+	Base             BasePermissions `protobuf:"bytes,1,opt,name=Base" json:"Base"`
+	Roles            []string        `protobuf:"bytes,2,rep,name=Roles" json:"Roles,omitempty"`
+	XXX_unrecognized []byte          `json:"-"`
+}
+
+func (m *AccountPermissions) Reset()                    { *m = AccountPermissions{} }
+func (m *AccountPermissions) String() string            { return proto.CompactTextString(m) }
+func (*AccountPermissions) ProtoMessage()               {}
+func (*AccountPermissions) Descriptor() ([]byte, []int) { return fileDescriptorPermission, []int{0} }
+
+func (m *AccountPermissions) GetBase() BasePermissions {
+	if m != nil {
+		return m.Base
+	}
+	return BasePermissions{}
+}
+
+func (m *AccountPermissions) GetRoles() []string {
+	if m != nil {
+		return m.Roles
+	}
+	return nil
+}
+
+func (*AccountPermissions) XXX_MessageName() string {
+	return "permission.AccountPermissions"
+}
+
+type BasePermissions struct {
+	Perms            PermFlag `protobuf:"varint,1,opt,name=Perms,casttype=PermFlag" json:"Perms"`
+	SetBit           PermFlag `protobuf:"varint,2,opt,name=SetBit,casttype=PermFlag" json:"SetBit"`
+	XXX_unrecognized []byte   `json:"-"`
+}
+
+func (m *BasePermissions) Reset()                    { *m = BasePermissions{} }
+func (*BasePermissions) ProtoMessage()               {}
+func (*BasePermissions) Descriptor() ([]byte, []int) { return fileDescriptorPermission, []int{1} }
+
+func (m *BasePermissions) GetPerms() PermFlag {
+	if m != nil {
+		return m.Perms
+	}
+	return 0
+}
+
+func (m *BasePermissions) GetSetBit() PermFlag {
+	if m != nil {
+		return m.SetBit
+	}
+	return 0
+}
+
+func (*BasePermissions) XXX_MessageName() string {
+	return "permission.BasePermissions"
+}
+
+type PermArgs struct {
+	PermFlag   PermFlag                                      `protobuf:"varint,1,opt,name=PermFlag,casttype=PermFlag" json:"PermFlag"`
+	Address    *github_com_hyperledger_burrow_crypto.Address `protobuf:"bytes,2,opt,name=Address,customtype=github.com/hyperledger/burrow/crypto.Address" json:"Address,omitempty"`
+	Permission *PermFlag                                     `protobuf:"varint,3,opt,name=Permission,casttype=PermFlag" json:"Permission,omitempty"`
+	Role       *string                                       `protobuf:"bytes,4,opt,name=Role" json:"Role,omitempty"`
+	Value      *bool                                         `protobuf:"varint,5,opt,name=Value" json:"Value,omitempty"`
+}
+
+func (m *PermArgs) Reset()                    { *m = PermArgs{} }
+func (*PermArgs) ProtoMessage()               {}
+func (*PermArgs) Descriptor() ([]byte, []int) { return fileDescriptorPermission, []int{2} }
+
+func (m *PermArgs) GetPermFlag() PermFlag {
+	if m != nil {
+		return m.PermFlag
+	}
+	return 0
+}
+
+func (m *PermArgs) GetPermission() PermFlag {
+	if m != nil && m.Permission != nil {
+		return *m.Permission
+	}
+	return 0
+}
+
+func (m *PermArgs) GetRole() string {
+	if m != nil && m.Role != nil {
+		return *m.Role
+	}
+	return ""
+}
+
+func (m *PermArgs) GetValue() bool {
+	if m != nil && m.Value != nil {
+		return *m.Value
+	}
+	return false
+}
+
+func (*PermArgs) XXX_MessageName() string {
+	return "permission.PermArgs"
+}
+func init() {
+	proto.RegisterType((*AccountPermissions)(nil), "permission.AccountPermissions")
+	golang_proto.RegisterType((*AccountPermissions)(nil), "permission.AccountPermissions")
+	proto.RegisterType((*BasePermissions)(nil), "permission.BasePermissions")
+	golang_proto.RegisterType((*BasePermissions)(nil), "permission.BasePermissions")
+	proto.RegisterType((*PermArgs)(nil), "permission.PermArgs")
+	golang_proto.RegisterType((*PermArgs)(nil), "permission.PermArgs")
+}
+func (m *AccountPermissions) Marshal() (dAtA []byte, err error) {
+	size := m.Size()
+	dAtA = make([]byte, size)
+	n, err := m.MarshalTo(dAtA)
+	if err != nil {
+		return nil, err
+	}
+	return dAtA[:n], nil
+}
+
+func (m *AccountPermissions) MarshalTo(dAtA []byte) (int, error) {
+	var i int
+	_ = i
+	var l int
+	_ = l
+	dAtA[i] = 0xa
+	i++
+	i = encodeVarintPermission(dAtA, i, uint64(m.Base.Size()))
+	n1, err := m.Base.MarshalTo(dAtA[i:])
+	if err != nil {
+		return 0, err
+	}
+	i += n1
+	if len(m.Roles) > 0 {
+		for _, s := range m.Roles {
+			dAtA[i] = 0x12
+			i++
+			l = len(s)
+			for l >= 1<<7 {
+				dAtA[i] = uint8(uint64(l)&0x7f | 0x80)
+				l >>= 7
+				i++
+			}
+			dAtA[i] = uint8(l)
+			i++
+			i += copy(dAtA[i:], s)
+		}
+	}
+	if m.XXX_unrecognized != nil {
+		i += copy(dAtA[i:], m.XXX_unrecognized)
+	}
+	return i, nil
+}
+
+func (m *BasePermissions) Marshal() (dAtA []byte, err error) {
+	size := m.Size()
+	dAtA = make([]byte, size)
+	n, err := m.MarshalTo(dAtA)
+	if err != nil {
+		return nil, err
+	}
+	return dAtA[:n], nil
+}
+
+func (m *BasePermissions) MarshalTo(dAtA []byte) (int, error) {
+	var i int
+	_ = i
+	var l int
+	_ = l
+	dAtA[i] = 0x8
+	i++
+	i = encodeVarintPermission(dAtA, i, uint64(m.Perms))
+	dAtA[i] = 0x10
+	i++
+	i = encodeVarintPermission(dAtA, i, uint64(m.SetBit))
+	if m.XXX_unrecognized != nil {
+		i += copy(dAtA[i:], m.XXX_unrecognized)
+	}
+	return i, nil
+}
+
+func (m *PermArgs) Marshal() (dAtA []byte, err error) {
+	size := m.Size()
+	dAtA = make([]byte, size)
+	n, err := m.MarshalTo(dAtA)
+	if err != nil {
+		return nil, err
+	}
+	return dAtA[:n], nil
+}
+
+func (m *PermArgs) MarshalTo(dAtA []byte) (int, error) {
+	var i int
+	_ = i
+	var l int
+	_ = l
+	dAtA[i] = 0x8
+	i++
+	i = encodeVarintPermission(dAtA, i, uint64(m.PermFlag))
+	if m.Address != nil {
+		dAtA[i] = 0x12
+		i++
+		i = encodeVarintPermission(dAtA, i, uint64(m.Address.Size()))
+		n2, err := m.Address.MarshalTo(dAtA[i:])
+		if err != nil {
+			return 0, err
+		}
+		i += n2
+	}
+	if m.Permission != nil {
+		dAtA[i] = 0x18
+		i++
+		i = encodeVarintPermission(dAtA, i, uint64(*m.Permission))
+	}
+	if m.Role != nil {
+		dAtA[i] = 0x22
+		i++
+		i = encodeVarintPermission(dAtA, i, uint64(len(*m.Role)))
+		i += copy(dAtA[i:], *m.Role)
+	}
+	if m.Value != nil {
+		dAtA[i] = 0x28
+		i++
+		if *m.Value {
+			dAtA[i] = 1
+		} else {
+			dAtA[i] = 0
+		}
+		i++
+	}
+	return i, nil
+}
+
+func encodeVarintPermission(dAtA []byte, offset int, v uint64) int {
+	for v >= 1<<7 {
+		dAtA[offset] = uint8(v&0x7f | 0x80)
+		v >>= 7
+		offset++
+	}
+	dAtA[offset] = uint8(v)
+	return offset + 1
+}
+func (m *AccountPermissions) Size() (n int) {
+	var l int
+	_ = l
+	l = m.Base.Size()
+	n += 1 + l + sovPermission(uint64(l))
+	if len(m.Roles) > 0 {
+		for _, s := range m.Roles {
+			l = len(s)
+			n += 1 + l + sovPermission(uint64(l))
+		}
+	}
+	if m.XXX_unrecognized != nil {
+		n += len(m.XXX_unrecognized)
+	}
+	return n
+}
+
+func (m *BasePermissions) Size() (n int) {
+	var l int
+	_ = l
+	n += 1 + sovPermission(uint64(m.Perms))
+	n += 1 + sovPermission(uint64(m.SetBit))
+	if m.XXX_unrecognized != nil {
+		n += len(m.XXX_unrecognized)
+	}
+	return n
+}
+
+func (m *PermArgs) Size() (n int) {
+	var l int
+	_ = l
+	n += 1 + sovPermission(uint64(m.PermFlag))
+	if m.Address != nil {
+		l = m.Address.Size()
+		n += 1 + l + sovPermission(uint64(l))
+	}
+	if m.Permission != nil {
+		n += 1 + sovPermission(uint64(*m.Permission))
+	}
+	if m.Role != nil {
+		l = len(*m.Role)
+		n += 1 + l + sovPermission(uint64(l))
+	}
+	if m.Value != nil {
+		n += 2
+	}
+	return n
+}
+
+func sovPermission(x uint64) (n int) {
+	for {
+		n++
+		x >>= 7
+		if x == 0 {
+			break
+		}
+	}
+	return n
+}
+func sozPermission(x uint64) (n int) {
+	return sovPermission(uint64((x << 1) ^ uint64((int64(x) >> 63))))
+}
+func (m *AccountPermissions) Unmarshal(dAtA []byte) error {
+	l := len(dAtA)
+	iNdEx := 0
+	for iNdEx < l {
+		preIndex := iNdEx
+		var wire uint64
+		for shift := uint(0); ; shift += 7 {
+			if shift >= 64 {
+				return ErrIntOverflowPermission
+			}
+			if iNdEx >= l {
+				return io.ErrUnexpectedEOF
+			}
+			b := dAtA[iNdEx]
+			iNdEx++
+			wire |= (uint64(b) & 0x7F) << shift
+			if b < 0x80 {
+				break
+			}
+		}
+		fieldNum := int32(wire >> 3)
+		wireType := int(wire & 0x7)
+		if wireType == 4 {
+			return fmt.Errorf("proto: AccountPermissions: wiretype end group for non-group")
+		}
+		if fieldNum <= 0 {
+			return fmt.Errorf("proto: AccountPermissions: illegal tag %d (wire type %d)", fieldNum, wire)
+		}
+		switch fieldNum {
+		case 1:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Base", wireType)
+			}
+			var msglen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowPermission
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				msglen |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if msglen < 0 {
+				return ErrInvalidLengthPermission
+			}
+			postIndex := iNdEx + msglen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			if err := m.Base.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+				return err
+			}
+			iNdEx = postIndex
+		case 2:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Roles", wireType)
+			}
+			var stringLen uint64
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowPermission
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				stringLen |= (uint64(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			intStringLen := int(stringLen)
+			if intStringLen < 0 {
+				return ErrInvalidLengthPermission
+			}
+			postIndex := iNdEx + intStringLen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			m.Roles = append(m.Roles, string(dAtA[iNdEx:postIndex]))
+			iNdEx = postIndex
+		default:
+			iNdEx = preIndex
+			skippy, err := skipPermission(dAtA[iNdEx:])
+			if err != nil {
+				return err
+			}
+			if skippy < 0 {
+				return ErrInvalidLengthPermission
+			}
+			if (iNdEx + skippy) > l {
+				return io.ErrUnexpectedEOF
+			}
+			m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...)
+			iNdEx += skippy
+		}
+	}
+
+	if iNdEx > l {
+		return io.ErrUnexpectedEOF
+	}
+	return nil
+}
+func (m *BasePermissions) Unmarshal(dAtA []byte) error {
+	l := len(dAtA)
+	iNdEx := 0
+	for iNdEx < l {
+		preIndex := iNdEx
+		var wire uint64
+		for shift := uint(0); ; shift += 7 {
+			if shift >= 64 {
+				return ErrIntOverflowPermission
+			}
+			if iNdEx >= l {
+				return io.ErrUnexpectedEOF
+			}
+			b := dAtA[iNdEx]
+			iNdEx++
+			wire |= (uint64(b) & 0x7F) << shift
+			if b < 0x80 {
+				break
+			}
+		}
+		fieldNum := int32(wire >> 3)
+		wireType := int(wire & 0x7)
+		if wireType == 4 {
+			return fmt.Errorf("proto: BasePermissions: wiretype end group for non-group")
+		}
+		if fieldNum <= 0 {
+			return fmt.Errorf("proto: BasePermissions: illegal tag %d (wire type %d)", fieldNum, wire)
+		}
+		switch fieldNum {
+		case 1:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Perms", wireType)
+			}
+			m.Perms = 0
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowPermission
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				m.Perms |= (PermFlag(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+		case 2:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field SetBit", wireType)
+			}
+			m.SetBit = 0
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowPermission
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				m.SetBit |= (PermFlag(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+		default:
+			iNdEx = preIndex
+			skippy, err := skipPermission(dAtA[iNdEx:])
+			if err != nil {
+				return err
+			}
+			if skippy < 0 {
+				return ErrInvalidLengthPermission
+			}
+			if (iNdEx + skippy) > l {
+				return io.ErrUnexpectedEOF
+			}
+			m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...)
+			iNdEx += skippy
+		}
+	}
+
+	if iNdEx > l {
+		return io.ErrUnexpectedEOF
+	}
+	return nil
+}
+func (m *PermArgs) Unmarshal(dAtA []byte) error {
+	l := len(dAtA)
+	iNdEx := 0
+	for iNdEx < l {
+		preIndex := iNdEx
+		var wire uint64
+		for shift := uint(0); ; shift += 7 {
+			if shift >= 64 {
+				return ErrIntOverflowPermission
+			}
+			if iNdEx >= l {
+				return io.ErrUnexpectedEOF
+			}
+			b := dAtA[iNdEx]
+			iNdEx++
+			wire |= (uint64(b) & 0x7F) << shift
+			if b < 0x80 {
+				break
+			}
+		}
+		fieldNum := int32(wire >> 3)
+		wireType := int(wire & 0x7)
+		if wireType == 4 {
+			return fmt.Errorf("proto: PermArgs: wiretype end group for non-group")
+		}
+		if fieldNum <= 0 {
+			return fmt.Errorf("proto: PermArgs: illegal tag %d (wire type %d)", fieldNum, wire)
+		}
+		switch fieldNum {
+		case 1:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field PermFlag", wireType)
+			}
+			m.PermFlag = 0
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowPermission
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				m.PermFlag |= (PermFlag(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+		case 2:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Address", wireType)
+			}
+			var byteLen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowPermission
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				byteLen |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if byteLen < 0 {
+				return ErrInvalidLengthPermission
+			}
+			postIndex := iNdEx + byteLen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			var v github_com_hyperledger_burrow_crypto.Address
+			m.Address = &v
+			if err := m.Address.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+				return err
+			}
+			iNdEx = postIndex
+		case 3:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Permission", wireType)
+			}
+			var v PermFlag
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowPermission
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				v |= (PermFlag(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			m.Permission = &v
+		case 4:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Role", wireType)
+			}
+			var stringLen uint64
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowPermission
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				stringLen |= (uint64(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			intStringLen := int(stringLen)
+			if intStringLen < 0 {
+				return ErrInvalidLengthPermission
+			}
+			postIndex := iNdEx + intStringLen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			s := string(dAtA[iNdEx:postIndex])
+			m.Role = &s
+			iNdEx = postIndex
+		case 5:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Value", wireType)
+			}
+			var v int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowPermission
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				v |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			b := bool(v != 0)
+			m.Value = &b
+		default:
+			iNdEx = preIndex
+			skippy, err := skipPermission(dAtA[iNdEx:])
+			if err != nil {
+				return err
+			}
+			if skippy < 0 {
+				return ErrInvalidLengthPermission
+			}
+			if (iNdEx + skippy) > l {
+				return io.ErrUnexpectedEOF
+			}
+			iNdEx += skippy
+		}
+	}
+
+	if iNdEx > l {
+		return io.ErrUnexpectedEOF
+	}
+	return nil
+}
+func skipPermission(dAtA []byte) (n int, err error) {
+	l := len(dAtA)
+	iNdEx := 0
+	for iNdEx < l {
+		var wire uint64
+		for shift := uint(0); ; shift += 7 {
+			if shift >= 64 {
+				return 0, ErrIntOverflowPermission
+			}
+			if iNdEx >= l {
+				return 0, io.ErrUnexpectedEOF
+			}
+			b := dAtA[iNdEx]
+			iNdEx++
+			wire |= (uint64(b) & 0x7F) << shift
+			if b < 0x80 {
+				break
+			}
+		}
+		wireType := int(wire & 0x7)
+		switch wireType {
+		case 0:
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return 0, ErrIntOverflowPermission
+				}
+				if iNdEx >= l {
+					return 0, io.ErrUnexpectedEOF
+				}
+				iNdEx++
+				if dAtA[iNdEx-1] < 0x80 {
+					break
+				}
+			}
+			return iNdEx, nil
+		case 1:
+			iNdEx += 8
+			return iNdEx, nil
+		case 2:
+			var length int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return 0, ErrIntOverflowPermission
+				}
+				if iNdEx >= l {
+					return 0, io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				length |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			iNdEx += length
+			if length < 0 {
+				return 0, ErrInvalidLengthPermission
+			}
+			return iNdEx, nil
+		case 3:
+			for {
+				var innerWire uint64
+				var start int = iNdEx
+				for shift := uint(0); ; shift += 7 {
+					if shift >= 64 {
+						return 0, ErrIntOverflowPermission
+					}
+					if iNdEx >= l {
+						return 0, io.ErrUnexpectedEOF
+					}
+					b := dAtA[iNdEx]
+					iNdEx++
+					innerWire |= (uint64(b) & 0x7F) << shift
+					if b < 0x80 {
+						break
+					}
+				}
+				innerWireType := int(innerWire & 0x7)
+				if innerWireType == 4 {
+					break
+				}
+				next, err := skipPermission(dAtA[start:])
+				if err != nil {
+					return 0, err
+				}
+				iNdEx = start + next
+			}
+			return iNdEx, nil
+		case 4:
+			return iNdEx, nil
+		case 5:
+			iNdEx += 4
+			return iNdEx, nil
+		default:
+			return 0, fmt.Errorf("proto: illegal wireType %d", wireType)
+		}
+	}
+	panic("unreachable")
+}
+
+var (
+	ErrInvalidLengthPermission = fmt.Errorf("proto: negative length found during unmarshaling")
+	ErrIntOverflowPermission   = fmt.Errorf("proto: integer overflow")
+)
+
+func init() { proto.RegisterFile("permission.proto", fileDescriptorPermission) }
+func init() { golang_proto.RegisterFile("permission.proto", fileDescriptorPermission) }
+
+var fileDescriptorPermission = []byte{
+	// 351 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x7c, 0x51, 0x31, 0x4b, 0xc3, 0x40,
+	0x14, 0xee, 0xb5, 0xa9, 0xb6, 0xcf, 0x82, 0xe5, 0x70, 0x08, 0x0a, 0x49, 0xe8, 0x20, 0x19, 0x6a,
+	0x22, 0x82, 0x4b, 0x07, 0xa1, 0x19, 0x1c, 0x9c, 0xe4, 0x04, 0x07, 0xb7, 0x34, 0x3d, 0xd3, 0x40,
+	0xda, 0x0b, 0x77, 0x17, 0xa4, 0xff, 0xc4, 0x51, 0xff, 0x89, 0x63, 0xc7, 0xce, 0x0e, 0x45, 0x5a,
+	0xf0, 0x47, 0x38, 0xc9, 0x5d, 0x6a, 0x1b, 0x85, 0xba, 0xbd, 0xef, 0x7d, 0xdf, 0x7b, 0xdf, 0xbd,
+	0xef, 0xa0, 0x9d, 0x51, 0x3e, 0x4e, 0x84, 0x48, 0xd8, 0xc4, 0xcb, 0x38, 0x93, 0x0c, 0xc3, 0xb6,
+	0x73, 0x7c, 0x16, 0x27, 0x72, 0x94, 0x0f, 0xbc, 0x88, 0x8d, 0xfd, 0x98, 0xc5, 0xcc, 0xd7, 0x92,
+	0x41, 0xfe, 0xa8, 0x91, 0x06, 0xba, 0x2a, 0x46, 0x3b, 0x21, 0xe0, 0x7e, 0x14, 0xb1, 0x7c, 0x22,
+	0x6f, 0x37, 0x3b, 0x04, 0xbe, 0x04, 0x23, 0x08, 0x05, 0x35, 0x91, 0x83, 0xdc, 0x83, 0x8b, 0x13,
+	0xaf, 0xe4, 0xa8, 0xfa, 0x25, 0x69, 0x60, 0xcc, 0x16, 0x76, 0x85, 0x68, 0x39, 0x3e, 0x82, 0x3a,
+	0x61, 0x29, 0x15, 0x66, 0xd5, 0xa9, 0xb9, 0x4d, 0x52, 0x80, 0x4e, 0x02, 0x87, 0x7f, 0x86, 0xf0,
+	0x29, 0xd4, 0x15, 0x14, 0xda, 0xc0, 0x08, 0xda, 0x6a, 0xc7, 0xd7, 0xc2, 0x6e, 0xa8, 0xe6, 0x75,
+	0x1a, 0xc6, 0xa4, 0xa0, 0xb1, 0x0b, 0x7b, 0x77, 0x54, 0x06, 0x89, 0x34, 0xab, 0x3b, 0x84, 0x6b,
+	0xbe, 0x67, 0x3c, 0xbf, 0xd8, 0x95, 0xce, 0x27, 0x02, 0x4d, 0xf5, 0x79, 0x2c, 0x70, 0x17, 0x36,
+	0xb2, 0x9d, 0x3e, 0x9b, 0x0a, 0xdf, 0xc0, 0x7e, 0x7f, 0x38, 0xe4, 0x54, 0x08, 0xed, 0xd5, 0x0a,
+	0xce, 0xdf, 0x17, 0x76, 0xb7, 0x14, 0xe6, 0x68, 0x9a, 0x51, 0x9e, 0xd2, 0x61, 0x4c, 0xb9, 0x3f,
+	0xc8, 0x39, 0x67, 0x4f, 0x7e, 0xc4, 0xa7, 0x99, 0x64, 0xde, 0x7a, 0x8e, 0xfc, 0x2c, 0xc0, 0x5d,
+	0x80, 0xed, 0xb5, 0x66, 0x4d, 0x7b, 0xb7, 0x7e, 0xf9, 0x96, 0x78, 0x8c, 0xc1, 0x50, 0x41, 0x99,
+	0x86, 0x83, 0xdc, 0x26, 0xd1, 0xb5, 0x4a, 0xf2, 0x3e, 0x4c, 0x73, 0x6a, 0xd6, 0x1d, 0xe4, 0x36,
+	0x48, 0x01, 0x7a, 0x0d, 0x75, 0xe4, 0xfc, 0xd5, 0xae, 0x04, 0x57, 0xb3, 0xa5, 0x85, 0xe6, 0x4b,
+	0x0b, 0x7d, 0x2c, 0x2d, 0xf4, 0xb6, 0xb2, 0xd0, 0x6c, 0x65, 0xa1, 0x07, 0xf7, 0xff, 0xe7, 0x6e,
+	0x7f, 0xf1, 0x3b, 0x00, 0x00, 0xff, 0xff, 0x75, 0xf4, 0x5f, 0xe9, 0x44, 0x02, 0x00, 0x00,
+}
diff --git a/permission/permissions.go b/permission/permissions.go
index 48b5bd9dd3bd2e11353993c8ce96964017a8a75a..3cac17d4e920e050f566011b6cb1c661ba91b446 100644
--- a/permission/permissions.go
+++ b/permission/permissions.go
@@ -14,26 +14,25 @@
 
 package permission
 
-import (
-	"github.com/hyperledger/burrow/permission/types"
-)
-
 var (
-	ZeroBasePermissions    = types.BasePermissions{0, 0}
-	ZeroAccountPermissions = types.AccountPermissions{
+	ZeroBasePermissions = BasePermissions{
+		Perms:  0,
+		SetBit: 0,
+	}
+	ZeroAccountPermissions = AccountPermissions{
 		Base: ZeroBasePermissions,
 	}
-	DefaultAccountPermissions = types.AccountPermissions{
-		Base: types.BasePermissions{
-			Perms:  types.DefaultPermFlags,
-			SetBit: types.AllPermFlags,
+	DefaultAccountPermissions = AccountPermissions{
+		Base: BasePermissions{
+			Perms:  DefaultPermFlags,
+			SetBit: AllPermFlags,
 		},
 		Roles: []string{},
 	}
-	AllAccountPermissions = types.AccountPermissions{
-		Base: types.BasePermissions{
-			Perms:  types.AllPermFlags,
-			SetBit: types.AllPermFlags,
+	AllAccountPermissions = AccountPermissions{
+		Base: BasePermissions{
+			Perms:  AllPermFlags,
+			SetBit: AllPermFlags,
 		},
 		Roles: []string{},
 	}
diff --git a/permission/snatives/snatives.go b/permission/snatives.go
similarity index 65%
rename from permission/snatives/snatives.go
rename to permission/snatives.go
index 5b47b8af5e894c0b9f5cdf6e26947db2ad398c35..6f3df0a1ec184c07c3f0975a1e3c7693cdb3287a 100644
--- a/permission/snatives/snatives.go
+++ b/permission/snatives.go
@@ -12,37 +12,26 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package snatives
+package permission
 
 import (
 	"fmt"
 	"strings"
 
 	"github.com/hyperledger/burrow/crypto"
-	"github.com/hyperledger/burrow/permission"
-	"github.com/hyperledger/burrow/permission/types"
-	ptypes "github.com/hyperledger/burrow/permission/types"
 )
 
 //---------------------------------------------------------------------------------------------------
 // PermissionsTx.PermArgs interface and argument encoding
 
-type PermArgs struct {
-	PermFlag   types.PermFlag
-	Address    *crypto.Address `json:",omitempty"`
-	Permission *types.PermFlag `json:",omitempty"`
-	Role       *string         `json:",omitempty"`
-	Value      *bool           `json:",omitempty"`
-}
-
 func (pa PermArgs) String() string {
 	body := make([]string, 0, 5)
-	body = append(body, fmt.Sprintf("PermFlag: %v", permission.String(pa.PermFlag)))
+	body = append(body, fmt.Sprintf("PermFlag: %v", String(pa.PermFlag)))
 	if pa.Address != nil {
 		body = append(body, fmt.Sprintf("Address: %s", *pa.Address))
 	}
 	if pa.Permission != nil {
-		body = append(body, fmt.Sprintf("Permission: %v", permission.String(*pa.Permission)))
+		body = append(body, fmt.Sprintf("Permission: %v", String(*pa.Permission)))
 	}
 	if pa.Role != nil {
 		body = append(body, fmt.Sprintf("Role: %s", *pa.Role))
@@ -56,10 +45,10 @@ func (pa PermArgs) String() string {
 func (pa PermArgs) EnsureValid() error {
 	pf := pa.PermFlag
 	// Address
-	if pa.Address == nil && pf != ptypes.SetGlobal {
+	if pa.Address == nil && pf != SetGlobal {
 		return fmt.Errorf("PermArgs for PermFlag %v requires Address to be provided but was nil", pf)
 	}
-	if pf == ptypes.HasRole || pf == ptypes.AddRole || pf == ptypes.RemoveRole {
+	if pf == HasRole || pf == AddRole || pf == RemoveRole {
 		// Role
 		if pa.Role == nil {
 			return fmt.Errorf("PermArgs for PermFlag %v requires Role to be provided but was nil", pf)
@@ -68,40 +57,40 @@ func (pa PermArgs) EnsureValid() error {
 	} else if pa.Permission == nil {
 		return fmt.Errorf("PermArgs for PermFlag %v requires Permission to be provided but was nil", pf)
 		// Value
-	} else if (pf == ptypes.SetBase || pf == ptypes.SetGlobal) && pa.Value == nil {
+	} else if (pf == SetBase || pf == SetGlobal) && pa.Value == nil {
 		return fmt.Errorf("PermArgs for PermFlag %v requires Value to be provided but was nil", pf)
 	}
 	return nil
 }
 
-func HasBaseArgs(address crypto.Address, permFlag types.PermFlag) PermArgs {
+func HasBaseArgs(address crypto.Address, permFlag PermFlag) PermArgs {
 	return PermArgs{
-		PermFlag:   ptypes.HasBase,
+		PermFlag:   HasBase,
 		Address:    &address,
 		Permission: &permFlag,
 	}
 }
 
-func SetBaseArgs(address crypto.Address, permFlag types.PermFlag, value bool) PermArgs {
+func SetBaseArgs(address crypto.Address, permFlag PermFlag, value bool) PermArgs {
 	return PermArgs{
-		PermFlag:   ptypes.SetBase,
+		PermFlag:   SetBase,
 		Address:    &address,
 		Permission: &permFlag,
 		Value:      &value,
 	}
 }
 
-func UnsetBaseArgs(address crypto.Address, permFlag types.PermFlag) PermArgs {
+func UnsetBaseArgs(address crypto.Address, permFlag PermFlag) PermArgs {
 	return PermArgs{
-		PermFlag:   ptypes.UnsetBase,
+		PermFlag:   UnsetBase,
 		Address:    &address,
 		Permission: &permFlag,
 	}
 }
 
-func SetGlobalArgs(permFlag types.PermFlag, value bool) PermArgs {
+func SetGlobalArgs(permFlag PermFlag, value bool) PermArgs {
 	return PermArgs{
-		PermFlag:   ptypes.SetGlobal,
+		PermFlag:   SetGlobal,
 		Permission: &permFlag,
 		Value:      &value,
 	}
@@ -109,7 +98,7 @@ func SetGlobalArgs(permFlag types.PermFlag, value bool) PermArgs {
 
 func HasRoleArgs(address crypto.Address, role string) PermArgs {
 	return PermArgs{
-		PermFlag: ptypes.HasRole,
+		PermFlag: HasRole,
 		Address:  &address,
 		Role:     &role,
 	}
@@ -117,7 +106,7 @@ func HasRoleArgs(address crypto.Address, role string) PermArgs {
 
 func AddRoleArgs(address crypto.Address, role string) PermArgs {
 	return PermArgs{
-		PermFlag: ptypes.AddRole,
+		PermFlag: AddRole,
 		Address:  &address,
 		Role:     &role,
 	}
@@ -125,7 +114,7 @@ func AddRoleArgs(address crypto.Address, role string) PermArgs {
 
 func RemoveRoleArgs(address crypto.Address, role string) PermArgs {
 	return PermArgs{
-		PermFlag: ptypes.RemoveRole,
+		PermFlag: RemoveRole,
 		Address:  &address,
 		Role:     &role,
 	}
diff --git a/permission/snatives/snatives_test.go b/permission/snatives/snatives_test.go
deleted file mode 100644
index 9441ed15eaccc20c7391e3ce4452ec01933ecb4a..0000000000000000000000000000000000000000
--- a/permission/snatives/snatives_test.go
+++ /dev/null
@@ -1,22 +0,0 @@
-package snatives
-
-import (
-	"testing"
-
-	permission "github.com/hyperledger/burrow/permission/types"
-	"github.com/stretchr/testify/assert"
-)
-
-func TestPermArgs_String(t *testing.T) {
-	role := "foo"
-	value := true
-	permFlag := permission.AddRole | permission.RemoveRole
-	permArgs := PermArgs{
-		PermFlag:   permission.SetBase,
-		Permission: &permFlag,
-		Role:       &role,
-		Value:      &value,
-	}
-	assert.Equal(t, "PermArgs{PermFlag: setBase, Permission: addRole | removeRole, Role: foo, Value: true}",
-		permArgs.String())
-}
diff --git a/permission/util.go b/permission/util.go
index 7470b94d90b27ee48b04cf40b67b215c8370f4c2..6f4ba1ebe412695f6e8bb79b265999414f4bd037 100644
--- a/permission/util.go
+++ b/permission/util.go
@@ -17,8 +17,6 @@ package permission
 import (
 	"fmt"
 	"strings"
-
-	"github.com/hyperledger/burrow/permission/types"
 )
 
 // ConvertMapStringIntToPermissions converts a map of string-bool pairs and a slice of
@@ -27,9 +25,9 @@ import (
 // will be set in the AccountsPermissions. For all unmentioned permissions the
 // ZeroBasePermissions is defaulted to.
 func ConvertPermissionsMapAndRolesToAccountPermissions(permissions map[string]bool,
-	roles []string) (*types.AccountPermissions, error) {
+	roles []string) (*AccountPermissions, error) {
 	var err error
-	accountPermissions := &types.AccountPermissions{}
+	accountPermissions := &AccountPermissions{}
 	accountPermissions.Base, err = convertPermissionsMapStringIntToBasePermissions(permissions)
 	if err != nil {
 		return nil, err
@@ -40,12 +38,12 @@ func ConvertPermissionsMapAndRolesToAccountPermissions(permissions map[string]bo
 
 // convertPermissionsMapStringIntToBasePermissions converts a map of string-bool
 // pairs to BasePermissions.
-func convertPermissionsMapStringIntToBasePermissions(permissions map[string]bool) (types.BasePermissions, error) {
+func convertPermissionsMapStringIntToBasePermissions(permissions map[string]bool) (BasePermissions, error) {
 	// initialise basePermissions as ZeroBasePermissions
 	basePermissions := ZeroBasePermissions
 
 	for permissionName, value := range permissions {
-		permissionsFlag, err := types.PermStringToFlag(permissionName)
+		permissionsFlag, err := PermStringToFlag(permissionName)
 		if err != nil {
 			return basePermissions, err
 		}
@@ -58,12 +56,12 @@ func convertPermissionsMapStringIntToBasePermissions(permissions map[string]bool
 
 // Builds a composite BasePermission by creating a PermFlag from permissions strings and
 // setting them all
-func BasePermissionsFromStringList(permissions []string) (types.BasePermissions, error) {
+func BasePermissionsFromStringList(permissions []string) (BasePermissions, error) {
 	permFlag, err := PermFlagFromStringList(permissions)
 	if err != nil {
 		return ZeroBasePermissions, err
 	}
-	return types.BasePermissions{
+	return BasePermissions{
 		Perms:  permFlag,
 		SetBit: permFlag,
 	}, nil
@@ -71,10 +69,10 @@ func BasePermissionsFromStringList(permissions []string) (types.BasePermissions,
 
 // Builds a composite PermFlag by mapping each permission string in permissions to its
 // flag and composing them with binary or
-func PermFlagFromStringList(permissions []string) (types.PermFlag, error) {
-	var permFlag types.PermFlag
+func PermFlagFromStringList(permissions []string) (PermFlag, error) {
+	var permFlag PermFlag
 	for _, perm := range permissions {
-		flag, err := types.PermStringToFlag(perm)
+		flag, err := PermStringToFlag(perm)
 		if err != nil {
 			return permFlag, err
 		}
@@ -85,19 +83,19 @@ func PermFlagFromStringList(permissions []string) (types.PermFlag, error) {
 
 // Builds a list of set permissions from a BasePermission by creating a list of permissions strings
 // from the resultant permissions of basePermissions
-func BasePermissionsToStringList(basePermissions types.BasePermissions) ([]string, error) {
+func BasePermissionsToStringList(basePermissions BasePermissions) ([]string, error) {
 	return PermFlagToStringList(basePermissions.ResultantPerms())
 }
 
 // Creates a list of individual permission flag strings from a possibly composite PermFlag
 // by projecting out each bit and adding its permission string if it is set
-func PermFlagToStringList(permFlag types.PermFlag) ([]string, error) {
-	permStrings := make([]string, 0, types.NumPermissions)
-	if permFlag > types.AllPermFlags {
+func PermFlagToStringList(permFlag PermFlag) ([]string, error) {
+	permStrings := make([]string, 0, NumPermissions)
+	if permFlag > AllPermFlags {
 		return nil, fmt.Errorf("resultant permission 0b%b is invalid: has permission flag set above top flag 0b%b",
-			permFlag, types.TopPermFlag)
+			permFlag, TopPermFlag)
 	}
-	for i := uint(0); i < types.NumPermissions; i++ {
+	for i := uint(0); i < NumPermissions; i++ {
 		permFlag := permFlag & (1 << i)
 		if permFlag > 0 {
 			permStrings = append(permStrings, permFlag.String())
@@ -107,18 +105,18 @@ func PermFlagToStringList(permFlag types.PermFlag) ([]string, error) {
 }
 
 // Generates a human readable string from the resultant permissions of basePermission
-func BasePermissionsString(basePermissions types.BasePermissions) string {
+func BasePermissionsString(basePermissions BasePermissions) string {
 	permStrings, err := BasePermissionsToStringList(basePermissions)
 	if err != nil {
-		return types.UnknownString
+		return UnknownString
 	}
 	return strings.Join(permStrings, " | ")
 }
 
-func String(permFlag types.PermFlag) string {
+func String(permFlag PermFlag) string {
 	permStrings, err := PermFlagToStringList(permFlag)
 	if err != nil {
-		return types.UnknownString
+		return UnknownString
 	}
 	return strings.Join(permStrings, " | ")
 }
diff --git a/permission/util_test.go b/permission/util_test.go
index 780c1651cb91900798536133288d0a8cdfeed134..1055361206e1a36745c7611439cf87f9a049571e 100644
--- a/permission/util_test.go
+++ b/permission/util_test.go
@@ -3,21 +3,20 @@ package permission
 import (
 	"testing"
 
-	"github.com/hyperledger/burrow/permission/types"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
 )
 
 func TestBasePermissionsFromStringList(t *testing.T) {
-	basePerms, err := BasePermissionsFromStringList([]string{types.HasRoleString, types.CreateContractString, types.SendString})
+	basePerms, err := BasePermissionsFromStringList([]string{HasRoleString, CreateContractString, SendString})
 	require.NoError(t, err)
-	permFlag := types.HasRole | types.CreateContract | types.Send
+	permFlag := HasRole | CreateContract | Send
 	assert.Equal(t, permFlag, basePerms.Perms)
 	assert.Equal(t, permFlag, basePerms.SetBit)
 
-	basePerms, err = BasePermissionsFromStringList([]string{types.AllString})
+	basePerms, err = BasePermissionsFromStringList([]string{AllString})
 	require.NoError(t, err)
-	permFlag = types.AllPermFlags
+	permFlag = AllPermFlags
 	assert.Equal(t, permFlag, basePerms.Perms)
 	assert.Equal(t, permFlag, basePerms.SetBit)
 
@@ -26,27 +25,27 @@ func TestBasePermissionsFromStringList(t *testing.T) {
 }
 
 func TestBasePermissionsToStringList(t *testing.T) {
-	permStrings, err := BasePermissionsToStringList(allSetBasePermission(types.Root | types.HasRole | types.SetBase | types.Call))
+	permStrings, err := BasePermissionsToStringList(allSetBasePermission(Root | HasRole | SetBase | Call))
 	require.NoError(t, err)
 	assert.Equal(t, []string{"root", "call", "setBase", "hasRole"}, permStrings)
 
-	permStrings, err = BasePermissionsToStringList(allSetBasePermission(types.AllPermFlags))
+	permStrings, err = BasePermissionsToStringList(allSetBasePermission(AllPermFlags))
 	require.NoError(t, err)
 	assert.Equal(t, []string{"root", "send", "call", "createContract", "createAccount", "bond", "name", "hasBase",
 		"setBase", "unsetBase", "setGlobal", "hasRole", "addRole", "removeRole"}, permStrings)
 
-	permStrings, err = BasePermissionsToStringList(allSetBasePermission(types.AllPermFlags + 1))
+	permStrings, err = BasePermissionsToStringList(allSetBasePermission(AllPermFlags + 1))
 	assert.Error(t, err)
 }
 
 func TestBasePermissionsString(t *testing.T) {
-	permissionString := BasePermissionsString(allSetBasePermission(types.AllPermFlags &^ types.Root))
+	permissionString := BasePermissionsString(allSetBasePermission(AllPermFlags &^ Root))
 	assert.Equal(t, "send | call | createContract | createAccount | bond | name | hasBase | "+
 		"setBase | unsetBase | setGlobal | hasRole | addRole | removeRole", permissionString)
 }
 
-func allSetBasePermission(perms types.PermFlag) types.BasePermissions {
-	return types.BasePermissions{
+func allSetBasePermission(perms PermFlag) BasePermissions {
+	return BasePermissions{
 		Perms:  perms,
 		SetBit: perms,
 	}
diff --git a/rpc/config.go b/rpc/config.go
index 549961f344ea3a77bb77f239fa7090b0afbea01a..ef5095817727fd0b9e2ff7005416516f7b9e35c5 100644
--- a/rpc/config.go
+++ b/rpc/config.go
@@ -1,9 +1,6 @@
 package rpc
 
-import "github.com/hyperledger/burrow/rpc/v0/server"
-
 type RPCConfig struct {
-	V0       *V0Config      `json:",omitempty" toml:",omitempty"`
 	TM       *ServerConfig  `json:",omitempty" toml:",omitempty"`
 	Profiler *ServerConfig  `json:",omitempty" toml:",omitempty"`
 	GRPC     *ServerConfig  `json:",omitempty" toml:",omitempty"`
@@ -15,11 +12,6 @@ type ServerConfig struct {
 	ListenAddress string
 }
 
-type V0Config struct {
-	Enabled bool
-	Server  *server.ServerConfig
-}
-
 type ProfilerConfig struct {
 	Enabled       bool
 	ListenAddress string
@@ -40,20 +32,12 @@ type MetricsConfig struct {
 func DefaultRPCConfig() *RPCConfig {
 	return &RPCConfig{
 		TM:       DefaultTMConfig(),
-		V0:       DefaultV0Config(),
 		Profiler: DefaultProfilerConfig(),
 		GRPC:     DefaultGRPCConfig(),
 		Metrics:  DefaultMetricsConfig(),
 	}
 }
 
-func DefaultV0Config() *V0Config {
-	return &V0Config{
-		Enabled: true,
-		Server:  server.DefaultServerConfig(),
-	}
-}
-
 func DefaultTMConfig() *ServerConfig {
 	return &ServerConfig{
 		Enabled:       true,
diff --git a/rpc/filters/accounts.go b/rpc/filters/accounts.go
deleted file mode 100644
index d1cad4a301e8fb8fa21bb00ab2d1dcbef27cccc0..0000000000000000000000000000000000000000
--- a/rpc/filters/accounts.go
+++ /dev/null
@@ -1,119 +0,0 @@
-// Copyright 2017 Monax Industries Limited
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//    http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package filters
-
-// Accounts is part of the pipe for BurrowMint and provides the implementation
-// for the pipe to call into the BurrowMint application
-
-import (
-	"bytes"
-	"encoding/hex"
-	"fmt"
-	"sync"
-
-	acm "github.com/hyperledger/burrow/account"
-)
-
-// TODO: [Silas] there are various notes about using mempool (which I guess translates to CheckTx cache). We need
-// to understand if this is the right thing to do, since we cannot guarantee stability of the check cache it doesn't
-// seem like the right thing to do....
-func NewAccountFilterFactory() *FilterFactory {
-	filterFactory := NewFilterFactory()
-
-	filterFactory.RegisterFilterPool("code", &sync.Pool{
-		New: func() interface{} {
-			return &AccountCodeFilter{}
-		},
-	})
-
-	filterFactory.RegisterFilterPool("balance", &sync.Pool{
-		New: func() interface{} {
-			return &AccountBalanceFilter{}
-		},
-	})
-
-	return filterFactory
-}
-
-// Filter for account code.
-// Ops: == or !=
-// Could be used to match against nil, to see if an account is a contract account.
-type AccountCodeFilter struct {
-	op    string
-	value []byte
-	match func([]byte, []byte) bool
-}
-
-func (acf *AccountCodeFilter) Configure(fd *FilterData) error {
-	op := fd.Op
-	val, err := hex.DecodeString(fd.Value)
-
-	if err != nil {
-		return fmt.Errorf("Wrong value type.")
-	}
-	if op == "==" {
-		acf.match = func(a, b []byte) bool {
-			return bytes.Equal(a, b)
-		}
-	} else if op == "!=" {
-		acf.match = func(a, b []byte) bool {
-			return !bytes.Equal(a, b)
-		}
-	} else {
-		return fmt.Errorf("Op: " + acf.op + " is not supported for 'code' filtering")
-	}
-	acf.op = op
-	acf.value = val
-	return nil
-}
-
-func (acf *AccountCodeFilter) Match(v interface{}) bool {
-	acc, ok := v.(acm.Account)
-	if !ok {
-		return false
-	}
-	return acf.match(acc.Code(), acf.value)
-}
-
-// Filter for account balance.
-// Ops: All
-type AccountBalanceFilter struct {
-	op    string
-	value uint64
-	match func(uint64, uint64) bool
-}
-
-func (abf *AccountBalanceFilter) Configure(fd *FilterData) error {
-	val, err := ParseNumberValue(fd.Value)
-	if err != nil {
-		return err
-	}
-	match, err2 := GetRangeFilter(fd.Op, "balance")
-	if err2 != nil {
-		return err2
-	}
-	abf.match = match
-	abf.op = fd.Op
-	abf.value = uint64(val)
-	return nil
-}
-
-func (abf *AccountBalanceFilter) Match(v interface{}) bool {
-	acc, ok := v.(acm.Account)
-	if !ok {
-		return false
-	}
-	return abf.match(acc.Balance(), abf.value)
-}
diff --git a/rpc/filters/filter.go b/rpc/filters/filter.go
deleted file mode 100644
index ae9c2d785def9b45ccfb9baf179eb980b4336f58..0000000000000000000000000000000000000000
--- a/rpc/filters/filter.go
+++ /dev/null
@@ -1,134 +0,0 @@
-// Copyright 2017 Monax Industries Limited
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//    http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package filters
-
-import (
-	"fmt"
-	"math"
-	"strconv"
-	"strings"
-)
-
-// TODO add generic filters for various different kinds of matching.
-
-// Filters based on fields.
-type Filter interface {
-	Match(v interface{}) bool
-}
-
-// A filter that can be configured with in-data.
-type ConfigurableFilter interface {
-	Filter
-	Configure(*FilterData) error
-}
-
-// Used to filter.
-// Op can be any of the following:
-// The usual relative operators: <, >, <=, >=, ==, != (where applicable)
-// A range parameter (see: https://help.github.com/articles/search-syntax/)
-type FilterData struct {
-	Field string `json:"field"`
-	Op    string `json:"op"`
-	Value string `json:"value"`
-}
-
-// Filter made up of many filters.
-type CompositeFilter struct {
-	filters []Filter
-}
-
-func (cf *CompositeFilter) SetData(filters []Filter) {
-	cf.filters = filters
-}
-
-func (cf *CompositeFilter) Match(v interface{}) bool {
-	for _, f := range cf.filters {
-		if !f.Match(v) {
-			return false
-		}
-	}
-	return true
-}
-
-// Rubberstamps everything.
-type MatchAllFilter struct{}
-
-func (maf *MatchAllFilter) Match(v interface{}) bool { return true }
-
-// Some standard value parsing functions.
-
-func ParseNumberValue(value string) (uint64, error) {
-	var val uint64
-	// Check for wildcards.
-	if value == "min" {
-		val = 0
-	} else if value == "max" {
-		val = math.MaxUint64
-	} else {
-		tv, err := strconv.ParseUint(value, 10, 64)
-
-		if err != nil {
-			return 0, fmt.Errorf("Wrong value type.")
-		}
-		val = tv
-	}
-	return val, nil
-}
-
-// Some standard filtering functions.
-
-func GetRangeFilter(op, fName string) (func(a, b uint64) bool, error) {
-	if op == "==" {
-		return func(a, b uint64) bool {
-			return a == b
-		}, nil
-	} else if op == "!=" {
-		return func(a, b uint64) bool {
-			return a != b
-		}, nil
-	} else if op == "<=" {
-		return func(a, b uint64) bool {
-			return a <= b
-		}, nil
-	} else if op == ">=" {
-		return func(a, b uint64) bool {
-			return a >= b
-		}, nil
-	} else if op == "<" {
-		return func(a, b uint64) bool {
-			return a < b
-		}, nil
-	} else if op == ">" {
-		return func(a, b uint64) bool {
-			return a > b
-		}, nil
-	} else {
-		return nil, fmt.Errorf("Op: " + op + " is not supported for '" + fName + "' filtering")
-	}
-}
-
-func GetStringFilter(op, fName string) (func(s0, s1 string) bool, error) {
-	if op == "==" {
-		return func(s0, s1 string) bool {
-			return strings.EqualFold(s0, s1)
-		}, nil
-	} else if op == "!=" {
-		return func(s0, s1 string) bool {
-			return !strings.EqualFold(s0, s1)
-		}, nil
-	} else {
-		return nil, fmt.Errorf("Op: " + op + " is not supported for '" + fName + "' filtering.")
-	}
-}
diff --git a/rpc/filters/filter_factory.go b/rpc/filters/filter_factory.go
deleted file mode 100644
index 02a4016a939e3b2735bb3f2544fdb56ad54ace86..0000000000000000000000000000000000000000
--- a/rpc/filters/filter_factory.go
+++ /dev/null
@@ -1,78 +0,0 @@
-package filters
-
-import (
-	"fmt"
-	"strings"
-	"sync"
-)
-
-// Used to generate filters based on filter data.
-// Keeping separate pools for "edge cases" (Composite and MatchAll)
-type FilterFactory struct {
-	filterPools         map[string]*sync.Pool
-	compositeFilterPool *sync.Pool
-	matchAllFilterPool  *sync.Pool
-}
-
-func NewFilterFactory() *FilterFactory {
-	aff := &FilterFactory{}
-	// Match all.
-	aff.matchAllFilterPool = &sync.Pool{
-		New: func() interface{} {
-			return &MatchAllFilter{}
-		},
-	}
-	// Composite.
-	aff.compositeFilterPool = &sync.Pool{
-		New: func() interface{} {
-			return &CompositeFilter{}
-		},
-	}
-	// Regular.
-	aff.filterPools = make(map[string]*sync.Pool)
-
-	return aff
-}
-
-func (ff *FilterFactory) RegisterFilterPool(fieldName string, pool *sync.Pool) {
-	ff.filterPools[strings.ToLower(fieldName)] = pool
-}
-
-// Creates a new filter given the input data array. If the array is zero length or nil, an empty
-// filter will be returned that returns true on all matches. If the array is of size 1, a regular
-// filter is returned, otherwise a CompositeFieldFilter is returned, which is a special filter that
-// contains a number of other filters. It implements AccountFieldFilter, and will match an account
-// only if all the sub-filters matches.
-func (ff *FilterFactory) NewFilter(fdArr []*FilterData) (Filter, error) {
-
-	if len(fdArr) == 0 {
-		return &MatchAllFilter{}, nil
-	}
-	if len(fdArr) == 1 {
-		return ff.newSingleFilter(fdArr[0])
-	}
-	filters := []Filter{}
-	for _, fd := range fdArr {
-		f, err := ff.newSingleFilter(fd)
-		if err != nil {
-			return nil, err
-		}
-		filters = append(filters, f)
-	}
-	cf := ff.compositeFilterPool.Get().(*CompositeFilter)
-	cf.filters = filters
-	return cf, nil
-}
-
-func (ff *FilterFactory) newSingleFilter(fd *FilterData) (ConfigurableFilter, error) {
-	fp, ok := ff.filterPools[strings.ToLower(fd.Field)]
-	if !ok {
-		return nil, fmt.Errorf("Field is not supported: " + fd.Field)
-	}
-	f := fp.Get().(ConfigurableFilter)
-	err := f.Configure(fd)
-	if err != nil {
-		return nil, err
-	}
-	return f, nil
-}
diff --git a/rpc/filters/filter_test.go b/rpc/filters/filter_test.go
deleted file mode 100644
index b635c0296e7a1b5c1bf1075c61befe526dcbe532..0000000000000000000000000000000000000000
--- a/rpc/filters/filter_test.go
+++ /dev/null
@@ -1,258 +0,0 @@
-// Copyright 2017 Monax Industries Limited
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//    http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package filters
-
-import (
-	"fmt"
-	"sync"
-	"testing"
-
-	"github.com/stretchr/testify/suite"
-)
-
-const OBJECTS = 100
-
-type FilterableObject struct {
-	Integer int
-	String  string
-}
-
-// Filter for integer value.
-// Ops: All
-type IntegerFilter struct {
-	op    string
-	value uint64
-	match func(uint64, uint64) bool
-}
-
-func (this *IntegerFilter) Configure(fd *FilterData) error {
-	val, err := ParseNumberValue(fd.Value)
-	if err != nil {
-		return err
-	}
-	match, err2 := GetRangeFilter(fd.Op, "integer")
-	if err2 != nil {
-		return err2
-	}
-	this.match = match
-	this.op = fd.Op
-	this.value = val
-	return nil
-}
-
-func (this *IntegerFilter) Match(v interface{}) bool {
-	fo, ok := v.(FilterableObject)
-	if !ok {
-		return false
-	}
-	return this.match(uint64(fo.Integer), this.value)
-}
-
-// Filter for integer value.
-// Ops: All
-type StringFilter struct {
-	op    string
-	value string
-	match func(string, string) bool
-}
-
-func (this *StringFilter) Configure(fd *FilterData) error {
-	match, err := GetStringFilter(fd.Op, "string")
-	if err != nil {
-		return err
-	}
-	this.match = match
-	this.op = fd.Op
-	this.value = fd.Value
-	return nil
-}
-
-func (this *StringFilter) Match(v interface{}) bool {
-	fo, ok := v.(FilterableObject)
-	if !ok {
-		return false
-	}
-	return this.match(fo.String, this.value)
-}
-
-// Test suite
-type FilterSuite struct {
-	suite.Suite
-	objects       []FilterableObject
-	filterFactory *FilterFactory
-}
-
-func (fs *FilterSuite) SetupSuite() {
-	objects := make([]FilterableObject, OBJECTS)
-
-	for i := 0; i < 100; i++ {
-		objects[i] = FilterableObject{i, fmt.Sprintf("string%d", i)}
-	}
-
-	ff := NewFilterFactory()
-
-	ff.RegisterFilterPool("integer", &sync.Pool{
-		New: func() interface{} {
-			return &IntegerFilter{}
-		},
-	})
-
-	ff.RegisterFilterPool("string", &sync.Pool{
-		New: func() interface{} {
-			return &StringFilter{}
-		},
-	})
-
-	fs.objects = objects
-	fs.filterFactory = ff
-}
-
-func (fs *FilterSuite) TearDownSuite() {
-
-}
-
-// ********************************************* Tests *********************************************
-
-func (fs *FilterSuite) Test_FilterIntegersEquals() {
-	fd := &FilterData{"integer", "==", "5"}
-	filter, err := fs.filterFactory.NewFilter([]*FilterData{fd})
-	fs.NoError(err)
-	arr := []FilterableObject{}
-	for _, o := range fs.objects {
-		if filter.Match(o) {
-			arr = append(arr, o)
-			break
-		}
-	}
-	fs.Equal(arr, fs.objects[5:6])
-}
-
-func (fs *FilterSuite) Test_FilterIntegersLT() {
-	fd := &FilterData{"integer", "<", "5"}
-	filter, err := fs.filterFactory.NewFilter([]*FilterData{fd})
-	fs.NoError(err)
-	arr := []FilterableObject{}
-	for _, o := range fs.objects {
-		if filter.Match(o) {
-			arr = append(arr, o)
-		}
-	}
-	fs.Equal(arr, fs.objects[:5])
-}
-
-func (fs *FilterSuite) Test_FilterIntegersLTEQ() {
-	fd := &FilterData{"integer", "<=", "10"}
-	filter, err := fs.filterFactory.NewFilter([]*FilterData{fd})
-	fs.NoError(err)
-	arr := []FilterableObject{}
-	for _, o := range fs.objects {
-		if filter.Match(o) {
-			arr = append(arr, o)
-		}
-	}
-	fs.Equal(arr, fs.objects[:11])
-}
-
-func (fs *FilterSuite) Test_FilterIntegersGT() {
-	fd := &FilterData{"integer", ">", "50"}
-	filter, err := fs.filterFactory.NewFilter([]*FilterData{fd})
-	fs.NoError(err)
-	arr := []FilterableObject{}
-	for _, o := range fs.objects {
-		if filter.Match(o) {
-			arr = append(arr, o)
-		}
-	}
-	fs.Equal(arr, fs.objects[51:])
-}
-
-func (fs *FilterSuite) Test_FilterIntegersRange() {
-	fd0 := &FilterData{"integer", ">", "5"}
-	fd1 := &FilterData{"integer", "<", "38"}
-	filter, err := fs.filterFactory.NewFilter([]*FilterData{fd0, fd1})
-	fs.NoError(err)
-	arr := []FilterableObject{}
-	for _, o := range fs.objects {
-		if filter.Match(o) {
-			arr = append(arr, o)
-		}
-	}
-	fs.Equal(arr, fs.objects[6:38])
-}
-
-func (fs *FilterSuite) Test_FilterIntegersGTEQ() {
-	fd := &FilterData{"integer", ">=", "77"}
-	filter, err := fs.filterFactory.NewFilter([]*FilterData{fd})
-	fs.NoError(err)
-	arr := []FilterableObject{}
-	for _, o := range fs.objects {
-		if filter.Match(o) {
-			arr = append(arr, o)
-		}
-	}
-	fs.Equal(arr, fs.objects[77:])
-}
-
-func (fs *FilterSuite) Test_FilterIntegersNEQ() {
-	fd := &FilterData{"integer", "!=", "50"}
-	filter, err := fs.filterFactory.NewFilter([]*FilterData{fd})
-	fs.NoError(err)
-	arr := []FilterableObject{}
-	for _, o := range fs.objects {
-		if filter.Match(o) {
-			arr = append(arr, o)
-		}
-	}
-	res := make([]FilterableObject, OBJECTS)
-	copy(res, fs.objects)
-	res = append(res[:50], res[51:]...)
-	fs.Equal(arr, res)
-}
-
-func (fs *FilterSuite) Test_FilterStringEquals() {
-	fd := &FilterData{"string", "==", "string7"}
-	filter, err := fs.filterFactory.NewFilter([]*FilterData{fd})
-	fs.NoError(err)
-	arr := []FilterableObject{}
-	for _, o := range fs.objects {
-		if filter.Match(o) {
-			arr = append(arr, o)
-		}
-	}
-	fs.Equal(arr, fs.objects[7:8])
-}
-
-func (fs *FilterSuite) Test_FilterStringNEQ() {
-	fd := &FilterData{"string", "!=", "string50"}
-	filter, err := fs.filterFactory.NewFilter([]*FilterData{fd})
-	fs.NoError(err)
-	arr := []FilterableObject{}
-
-	for _, o := range fs.objects {
-		if filter.Match(o) {
-			arr = append(arr, o)
-		}
-	}
-	res := make([]FilterableObject, OBJECTS)
-	copy(res, fs.objects)
-	res = append(res[:50], res[51:]...)
-	fs.Equal(arr, res)
-}
-
-// ********************************************* Entrypoint *********************************************
-
-func TestFilterSuite(t *testing.T) {
-	suite.Run(t, &FilterSuite{})
-}
diff --git a/rpc/filters/namereg.go b/rpc/filters/namereg.go
deleted file mode 100644
index 6d822fb177c21221a627d8cb4f8c90211de744a9..0000000000000000000000000000000000000000
--- a/rpc/filters/namereg.go
+++ /dev/null
@@ -1,196 +0,0 @@
-// Copyright 2017 Monax Industries Limited
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//    http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package filters
-
-import (
-	"bytes"
-	"encoding/hex"
-	"fmt"
-	"sync"
-
-	"github.com/hyperledger/burrow/execution/names"
-)
-
-func NewNameRegFilterFactory() *FilterFactory {
-	filterFactory := NewFilterFactory()
-
-	filterFactory.RegisterFilterPool("name", &sync.Pool{
-		New: func() interface{} {
-			return &NameRegNameFilter{}
-		},
-	})
-
-	filterFactory.RegisterFilterPool("owner", &sync.Pool{
-		New: func() interface{} {
-			return &NameRegOwnerFilter{}
-		},
-	})
-
-	filterFactory.RegisterFilterPool("data", &sync.Pool{
-		New: func() interface{} {
-			return &NameRegDataFilter{}
-		},
-	})
-
-	filterFactory.RegisterFilterPool("expires", &sync.Pool{
-		New: func() interface{} {
-			return &NameRegExpiresFilter{}
-		},
-	})
-
-	return filterFactory
-}
-
-// Filter for namereg name. This should not be used to get individual entries by name.
-// Ops: == or !=
-type NameRegNameFilter struct {
-	op    string
-	value string
-	match func(string, string) bool
-}
-
-func (nrnf *NameRegNameFilter) Configure(fd *FilterData) error {
-	op := fd.Op
-	val := fd.Value
-
-	if op == "==" {
-		nrnf.match = func(a, b string) bool {
-			return a == b
-		}
-	} else if op == "!=" {
-		nrnf.match = func(a, b string) bool {
-			return a != b
-		}
-	} else {
-		return fmt.Errorf("Op: " + nrnf.op + " is not supported for 'name' filtering")
-	}
-	nrnf.op = op
-	nrnf.value = val
-	return nil
-}
-
-func (nrnf *NameRegNameFilter) Match(v interface{}) bool {
-	nre, ok := v.(*names.Entry)
-	if !ok {
-		return false
-	}
-	return nrnf.match(nre.Name, nrnf.value)
-}
-
-// Filter for owner.
-// Ops: == or !=
-type NameRegOwnerFilter struct {
-	op    string
-	value []byte
-	match func([]byte, []byte) bool
-}
-
-func (nrof *NameRegOwnerFilter) Configure(fd *FilterData) error {
-	op := fd.Op
-	val, err := hex.DecodeString(fd.Value)
-
-	if err != nil {
-		return fmt.Errorf("wrong value type.")
-	}
-	if op == "==" {
-		nrof.match = func(a, b []byte) bool {
-			return bytes.Equal(a, b)
-		}
-	} else if op == "!=" {
-		nrof.match = func(a, b []byte) bool {
-			return !bytes.Equal(a, b)
-		}
-	} else {
-		return fmt.Errorf("Op: " + nrof.op + " is not supported for 'owner' filtering")
-	}
-	nrof.op = op
-	nrof.value = val
-	return nil
-}
-
-func (nrof *NameRegOwnerFilter) Match(v interface{}) bool {
-	nre, ok := v.(*names.Entry)
-	if !ok {
-		return false
-	}
-	return nrof.match(nre.Owner.Bytes(), nrof.value)
-}
-
-// Filter for namereg data. Useful for example if you store an ipfs hash and know the hash but need the key.
-// Ops: == or !=
-type NameRegDataFilter struct {
-	op    string
-	value string
-	match func(string, string) bool
-}
-
-func (nrdf *NameRegDataFilter) Configure(fd *FilterData) error {
-	op := fd.Op
-	val := fd.Value
-
-	if op == "==" {
-		nrdf.match = func(a, b string) bool {
-			return a == b
-		}
-	} else if op == "!=" {
-		nrdf.match = func(a, b string) bool {
-			return a != b
-		}
-	} else {
-		return fmt.Errorf("Op: " + nrdf.op + " is not supported for 'data' filtering")
-	}
-	nrdf.op = op
-	nrdf.value = val
-	return nil
-}
-
-func (nrdf *NameRegDataFilter) Match(v interface{}) bool {
-	nre, ok := v.(*names.Entry)
-	if !ok {
-		return false
-	}
-	return nrdf.match(nre.Data, nrdf.value)
-}
-
-// Filter for expires.
-// Ops: All
-type NameRegExpiresFilter struct {
-	op    string
-	value uint64
-	match func(uint64, uint64) bool
-}
-
-func (nref *NameRegExpiresFilter) Configure(fd *FilterData) error {
-	val, err := ParseNumberValue(fd.Value)
-	if err != nil {
-		return err
-	}
-	match, err2 := GetRangeFilter(fd.Op, "expires")
-	if err2 != nil {
-		return err2
-	}
-	nref.match = match
-	nref.op = fd.Op
-	nref.value = val
-	return nil
-}
-
-func (nref *NameRegExpiresFilter) Match(v interface{}) bool {
-	nre, ok := v.(*names.Entry)
-	if !ok {
-		return false
-	}
-	return nref.match(nre.Expires, nref.value)
-}
diff --git a/rpc/grpc.go b/rpc/grpc.go
index a30bdad14dd20607bdaaf04f31cee111e349f778..c1a17233c4658e702b2d6beb8060da02b251fd52 100644
--- a/rpc/grpc.go
+++ b/rpc/grpc.go
@@ -2,7 +2,6 @@ package rpc
 
 import (
 	"fmt"
-
 	"runtime/debug"
 
 	"github.com/hyperledger/burrow/logging"
@@ -25,7 +24,7 @@ func unaryInterceptor(logger *logging.Logger) grpc.UnaryServerInterceptor {
 		defer func() {
 			if r := recover(); r != nil {
 				logger.InfoMsg("panic in GRPC unary call", structure.ErrorKey, fmt.Sprintf("%v", r))
-				err = fmt.Errorf("panic in GRPC unary call %s: %v", info.FullMethod, r)
+				err = fmt.Errorf("panic in GRPC unary call %s: %v: %s", info.FullMethod, r, debug.Stack())
 			}
 		}()
 		logger.TraceMsg("GRPC unary call")
diff --git a/rpc/lib/client/ws_client.go b/rpc/lib/client/ws_client.go
index e18a6cfb69108d1b7094d7178c0aaa6bdd008f6e..e93f069087b988383c8aeaade16faf076479f4bb 100644
--- a/rpc/lib/client/ws_client.go
+++ b/rpc/lib/client/ws_client.go
@@ -12,7 +12,7 @@ import (
 	"github.com/gorilla/websocket"
 	"github.com/hyperledger/burrow/rpc/lib/types"
 	"github.com/pkg/errors"
-	"github.com/rcrowley/go-metrics"
+	metrics "github.com/rcrowley/go-metrics"
 	cmn "github.com/tendermint/tmlibs/common"
 )
 
diff --git a/rpc/lib/server/http_params.go b/rpc/lib/server/http_params.go
index 248e451b2d9fc5d8f61286cb39966a012a3b3122..cd18cd1023b97c2e4ce8b3b05fd92530b9093cc1 100644
--- a/rpc/lib/server/http_params.go
+++ b/rpc/lib/server/http_params.go
@@ -1,12 +1,12 @@
 package server
 
 import (
+	"encoding/hex"
 	"net/http"
 	"regexp"
 	"strconv"
 
 	"github.com/pkg/errors"
-	"github.com/tmthrgd/go-hex"
 )
 
 var (
diff --git a/rpc/result.go b/rpc/result.go
index 44a61c1d7186c87c06b77555f731352c9b66fc8c..af777d9406642929bb03fbe31f34ea858ea07ade 100644
--- a/rpc/result.go
+++ b/rpc/result.go
@@ -15,17 +15,11 @@
 package rpc
 
 import (
-	"encoding/json"
-	"fmt"
-
 	"time"
 
-	acm "github.com/hyperledger/burrow/account"
+	"github.com/hyperledger/burrow/acm"
 	"github.com/hyperledger/burrow/binary"
 	"github.com/hyperledger/burrow/crypto"
-	"github.com/hyperledger/burrow/execution"
-	"github.com/hyperledger/burrow/execution/events"
-	"github.com/hyperledger/burrow/execution/events/pbevents"
 	"github.com/hyperledger/burrow/execution/names"
 	"github.com/hyperledger/burrow/genesis"
 	"github.com/hyperledger/burrow/txs"
@@ -50,25 +44,12 @@ type ResultGetStorage struct {
 	Value binary.HexBytes
 }
 
-type ResultCall struct {
-	execution.Call
-}
-
-func (rc ResultCall) MarshalJSON() ([]byte, error) {
-	return json.Marshal(rc.Call)
-}
-
-func (rc *ResultCall) UnmarshalJSON(data []byte) (err error) {
-	return json.Unmarshal(data, &rc.Call)
-}
-
 type ResultListAccounts struct {
 	BlockHeight uint64
 	Accounts    []*acm.ConcreteAccount
 }
 
 type ResultDumpStorage struct {
-	StorageRoot  binary.HexBytes
 	StorageItems []StorageItem
 }
 
@@ -188,7 +169,6 @@ type AccountHumanReadable struct {
 	Sequence    uint64
 	Balance     uint64
 	Code        []string
-	StorageRoot string
 	Permissions []string
 	Roles       []string
 }
@@ -197,18 +177,6 @@ type ResultGetAccountHumanReadable struct {
 	Account *AccountHumanReadable
 }
 
-type ResultBroadcastTx struct {
-	txs.Receipt
-}
-
-func (rbt ResultBroadcastTx) MarshalJSON() ([]byte, error) {
-	return json.Marshal(rbt.Receipt)
-}
-
-func (rbt ResultBroadcastTx) UnmarshalJSON(data []byte) (err error) {
-	return json.Unmarshal(data, &rbt.Receipt)
-}
-
 type ResultListUnconfirmedTxs struct {
 	NumTxs int
 	Txs    []*txs.Envelope
@@ -225,67 +193,3 @@ type ResultGenesis struct {
 type ResultSignTx struct {
 	Tx *txs.Envelope
 }
-
-type TendermintEvent struct {
-	tmTypes.TMEventData
-}
-
-func (te TendermintEvent) MarshalJSON() ([]byte, error) {
-	return aminoCodec.MarshalJSON(te.TMEventData)
-}
-
-func (te *TendermintEvent) UnmarshalJSON(data []byte) (err error) {
-	return aminoCodec.UnmarshalJSON(data, &te.TMEventData)
-}
-
-func (te *TendermintEvent) EventDataNewBlock() *tmTypes.EventDataNewBlock {
-	if te != nil {
-		eventData, _ := te.TMEventData.(tmTypes.EventDataNewBlock)
-		return &eventData
-	}
-	return nil
-}
-
-type ResultEvent struct {
-	Event      string
-	Tendermint *TendermintEvent `json:",omitempty"`
-	Execution  *events.Event    `json:",omitempty"`
-}
-
-// Map any supported event data element to our ResultEvent sum type
-func NewResultEvent(event string, eventData interface{}) (*ResultEvent, error) {
-	res := &ResultEvent{
-		Event: event,
-	}
-	switch ed := eventData.(type) {
-	case tmTypes.TMEventData:
-		res.Tendermint = &TendermintEvent{ed}
-	case *events.Event:
-		res.Execution = ed
-	default:
-		return nil, fmt.Errorf("could not map event data of type %T to ResultEvent", eventData)
-	}
-	return res, nil
-}
-
-func (re *ResultEvent) GetEvent() (*pbevents.Event, error) {
-	ev := &pbevents.Event{
-		Name: re.Event,
-	}
-	if re.Tendermint != nil {
-		bs, err := json.Marshal(re.Tendermint)
-		if err != nil {
-			return nil, err
-		}
-		ev.Event = &pbevents.Event_TendermintEventJSON{
-			TendermintEventJSON: string(bs),
-		}
-	} else if re.Execution != nil {
-		ev.Event = &pbevents.Event_ExecutionEvent{
-			ExecutionEvent: pbevents.GetExecutionEvent(re.Execution),
-		}
-	} else {
-		return nil, fmt.Errorf("ResultEvent is empty")
-	}
-	return ev, nil
-}
diff --git a/rpc/result_test.go b/rpc/result_test.go
index ade8a61574da9b417e4b8ac8e3c4b3587f030a8e..ca972de49f7f1357ca6646a7bc7bddc72aba3ca7 100644
--- a/rpc/result_test.go
+++ b/rpc/result_test.go
@@ -22,12 +22,8 @@ import (
 
 	"fmt"
 
-	acm "github.com/hyperledger/burrow/account"
+	"github.com/hyperledger/burrow/acm"
 	"github.com/hyperledger/burrow/binary"
-	"github.com/hyperledger/burrow/crypto"
-	"github.com/hyperledger/burrow/execution"
-	"github.com/hyperledger/burrow/txs"
-	"github.com/hyperledger/burrow/txs/payload"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
 	goCrypto "github.com/tendermint/go-crypto"
@@ -36,36 +32,6 @@ import (
 	"github.com/tendermint/tmlibs/common"
 )
 
-func TestResultBroadcastTx(t *testing.T) {
-	// Make sure these are unpacked as expected
-	res := ResultBroadcastTx{
-		Receipt: txs.Receipt{
-			ContractAddress: crypto.Address{0, 2, 3},
-			CreatesContract: true,
-			TxHash:          []byte("foo"),
-		},
-	}
-
-	bs, err := json.Marshal(res)
-	require.NoError(t, err)
-	assert.Equal(t, `{"TxHash":"666F6F","CreatesContract":true,"ContractAddress":"0002030000000000000000000000000000000000"}`, string(bs))
-}
-
-func TestListUnconfirmedTxs(t *testing.T) {
-	res := &ResultListUnconfirmedTxs{
-		NumTxs: 3,
-		Txs: []*txs.Envelope{
-			txs.Enclose("testChain", &payload.CallTx{
-				Address: &crypto.Address{1},
-			}),
-		},
-	}
-	bs, err := json.Marshal(res)
-	require.NoError(t, err)
-	assert.Equal(t, "{\"NumTxs\":3,\"Txs\":[{\"Signatories\":null,\"Tx\":{\"ChainID\":\"testChain\",\"Type\":\"CallTx\",\"Payload\":{\"Input\":null,\"Address\":\"0100000000000000000000000000000000000000\",\"GasLimit\":0,\"Fee\":0}}}]}",
-		string(bs))
-}
-
 func TestResultListAccounts(t *testing.T) {
 	concreteAcc := acm.AsConcreteAccount(acm.FromAddressable(
 		acm.GeneratePrivateAccountFromSecret("Super Semi Secret")))
@@ -83,56 +49,6 @@ func TestResultListAccounts(t *testing.T) {
 	assert.Equal(t, string(bs), string(bsOut))
 }
 
-func TestResultCall_MarshalJSON(t *testing.T) {
-	res := ResultCall{
-		Call: execution.Call{
-			Return:  []byte("hi"),
-			GasUsed: 1,
-		},
-	}
-	bs, err := json.Marshal(res)
-	require.NoError(t, err)
-
-	resOut := new(ResultCall)
-	json.Unmarshal(bs, resOut)
-	bsOut, err := json.Marshal(resOut)
-	require.NoError(t, err)
-	assert.Equal(t, string(bs), string(bsOut))
-}
-
-func TestResultEvent(t *testing.T) {
-	eventDataNewBlock := tmTypes.EventDataNewBlock{
-		Block: &tmTypes.Block{
-			Header: &tmTypes.Header{
-				ChainID: "chainy",
-				NumTxs:  30,
-			},
-			LastCommit: &tmTypes.Commit{
-				Precommits: []*tmTypes.Vote{
-					{
-						Signature: goCrypto.SignatureEd25519{1, 2, 3},
-					},
-				},
-			},
-		},
-	}
-	res := ResultEvent{
-		Tendermint: &TendermintEvent{
-			TMEventData: &eventDataNewBlock,
-		},
-	}
-	bs, err := json.Marshal(res)
-	require.NoError(t, err)
-
-	resOut := new(ResultEvent)
-	require.NoError(t, json.Unmarshal(bs, resOut))
-	bsOut, err := json.Marshal(resOut)
-	require.NoError(t, err)
-	assert.Equal(t, string(bs), string(bsOut))
-	//fmt.Println(string(bs))
-	//fmt.Println(string(bsOut))
-}
-
 func TestResultGetBlock(t *testing.T) {
 	res := &ResultGetBlock{
 		Block: &Block{&tmTypes.Block{
diff --git a/execution/events/pbevents/blocks.go b/rpc/rpcevents/blocks.go
similarity index 72%
rename from execution/events/pbevents/blocks.go
rename to rpc/rpcevents/blocks.go
index b2df626d2783d1b50472d693864bf5d811170b1b..b016207fe8d8ff5d3c295d631b3c53aa40e43e67 100644
--- a/execution/events/pbevents/blocks.go
+++ b/rpc/rpcevents/blocks.go
@@ -1,18 +1,12 @@
-package pbevents
-
-import "github.com/hyperledger/burrow/execution/events"
+package rpcevents
 
 // Get bounds suitable for events.Provider
-func (br *BlockRange) Bounds(latestBlockHeight uint64) (startKey, endKey events.Key, streaming bool) {
+func (br *BlockRange) Bounds(latestBlockHeight uint64) (startHeight, endHeight uint64, streaming bool) {
 	// End bound is exclusive in state.GetEvents so we increment the height
-	return br.GetStart().Key(latestBlockHeight), br.GetEnd().Key(latestBlockHeight).IncHeight(),
+	return br.GetStart().Bound(latestBlockHeight), br.GetEnd().Bound(latestBlockHeight) + 1,
 		br.GetEnd().GetType() == Bound_STREAM
 }
 
-func (b *Bound) Key(latestBlockHeight uint64) events.Key {
-	return events.NewKey(b.Bound(latestBlockHeight), 0)
-}
-
 func (b *Bound) Bound(latestBlockHeight uint64) uint64 {
 	if b == nil {
 		return latestBlockHeight
diff --git a/execution/events/pbevents/blocks_test.go b/rpc/rpcevents/blocks_test.go
similarity index 56%
rename from execution/events/pbevents/blocks_test.go
rename to rpc/rpcevents/blocks_test.go
index a7a05b47e1e44e7ecb9b0b2418c17962b90d01f3..e773a84e7ad6f8b3657db25af4eff5bbb937772f 100644
--- a/execution/events/pbevents/blocks_test.go
+++ b/rpc/rpcevents/blocks_test.go
@@ -1,9 +1,8 @@
-package pbevents
+package rpcevents
 
 import (
 	"testing"
 
-	"github.com/hyperledger/burrow/execution/events"
 	"github.com/stretchr/testify/assert"
 )
 
@@ -11,7 +10,7 @@ func TestBlockRange_Bounds(t *testing.T) {
 	latestHeight := uint64(2344)
 	br := &BlockRange{}
 	start, end, streaming := br.Bounds(latestHeight)
-	assert.Equal(t, events.NewKey(latestHeight, 0), start)
-	assert.Equal(t, events.NewKey(latestHeight+1, 0), end)
+	assert.Equal(t, latestHeight, start)
+	assert.Equal(t, latestHeight+1, end)
 	assert.False(t, streaming)
 }
diff --git a/rpc/rpcevents/events_server.go b/rpc/rpcevents/events_server.go
deleted file mode 100644
index 699edcbff002a9ab6901b735d9c03344ac5f9b78..0000000000000000000000000000000000000000
--- a/rpc/rpcevents/events_server.go
+++ /dev/null
@@ -1,57 +0,0 @@
-package rpcevents
-
-import (
-	"github.com/hyperledger/burrow/execution/events/pbevents"
-	"github.com/hyperledger/burrow/rpc"
-	"golang.org/x/net/context"
-)
-
-type eventServer struct {
-	subscriptions *rpc.Subscriptions
-}
-
-func NewEventsServer(subscriptions *rpc.Subscriptions) pbevents.EventsServer {
-	return &eventServer{
-		subscriptions: subscriptions,
-	}
-}
-
-func (es *eventServer) EventPoll(ctx context.Context, param *pbevents.SubIdParam) (*pbevents.PollResponse, error) {
-	msgs, err := es.subscriptions.Poll(param.GetSubId())
-	if err != nil {
-		return nil, err
-	}
-	resp := &pbevents.PollResponse{
-		Events: make([]*pbevents.Event, 0, len(msgs)),
-	}
-	for _, msg := range msgs {
-		if resultEvent, ok := msg.(*rpc.ResultEvent); ok {
-			ev, err := resultEvent.GetEvent()
-			if err != nil {
-				return nil, err
-			}
-			resp.Events = append(resp.Events, ev)
-		}
-	}
-	return resp, nil
-}
-
-func (es *eventServer) EventSubscribe(ctx context.Context, param *pbevents.EventIdParam) (*pbevents.SubIdParam, error) {
-	subID, err := es.subscriptions.Add(param.GetEventId())
-	if err != nil {
-		return nil, err
-	}
-	return &pbevents.SubIdParam{
-		SubId: subID,
-	}, nil
-}
-
-func (es *eventServer) EventUnsubscribe(ctx context.Context, param *pbevents.SubIdParam) (*pbevents.EventUnSub, error) {
-	err := es.subscriptions.Remove(param.GetSubId())
-	if err != nil {
-		return nil, err
-	}
-	return &pbevents.EventUnSub{
-		Result: true,
-	}, nil
-}
diff --git a/rpc/rpcevents/execution_events_server.go b/rpc/rpcevents/execution_events_server.go
index 57645b8bb4cd6daeba49107ac3ee4b8ccddcfa72..2b042c77f19851db816fe367e0b12775355b5bd4 100644
--- a/rpc/rpcevents/execution_events_server.go
+++ b/rpc/rpcevents/execution_events_server.go
@@ -1,113 +1,270 @@
 package rpcevents
 
 import (
+	"context"
 	"fmt"
 
-	"context"
+	"io"
 
+	"github.com/gogo/protobuf/proto"
 	bcm "github.com/hyperledger/burrow/blockchain"
-	"github.com/hyperledger/burrow/consensus/tendermint"
 	"github.com/hyperledger/burrow/event"
 	"github.com/hyperledger/burrow/event/query"
-	"github.com/hyperledger/burrow/execution/events"
-	"github.com/hyperledger/burrow/execution/events/pbevents"
-	"github.com/tendermint/tendermint/libs/pubsub"
+	"github.com/hyperledger/burrow/execution/exec"
+	"github.com/hyperledger/burrow/logging"
+	"google.golang.org/grpc"
 )
 
+const SubscribeBufferSize = 100
+
+type Provider interface {
+	// Get a particular BlockExecution
+	GetBlock(height uint64) (*exec.BlockExecution, error)
+	// Get a partiualr TxExecution by hash
+	GetTx(txHash []byte) (*exec.TxExecution, error)
+	// Get events between startKey (inclusive) and endKey (exclusive) - i.e. the half open interval [start, end)
+	GetBlocks(startHeight, endHeight uint64, consumer func(*exec.BlockExecution) (stop bool)) (stopped bool, err error)
+}
+
 type executionEventsServer struct {
-	eventsProvider events.Provider
-	emitter        event.Emitter
+	eventsProvider Provider
+	subscribable   event.Subscribable
 	tip            bcm.TipInfo
+	logger         *logging.Logger
 }
 
-func NewExecutionEventsServer(eventsProvider events.Provider, emitter event.Emitter,
-	tip bcm.TipInfo) pbevents.ExecutionEventsServer {
+func NewExecutionEventsServer(eventsProvider Provider, subscribable event.Subscribable,
+	tip bcm.TipInfo, logger *logging.Logger) ExecutionEventsServer {
 
 	return &executionEventsServer{
 		eventsProvider: eventsProvider,
-		emitter:        emitter,
+		subscribable:   subscribable,
 		tip:            tip,
+		logger:         logger.WithScope("NewExecutionEventsServer"),
 	}
 }
 
-func (ees *executionEventsServer) GetEvents(request *pbevents.GetEventsRequest,
-	stream pbevents.ExecutionEvents_GetEventsServer) error {
+func (ees *executionEventsServer) GetBlock(ctx context.Context, request *GetBlockRequest) (*exec.BlockExecution, error) {
+	be, err := ees.eventsProvider.GetBlock(request.GetHeight())
+	if err != nil {
+		return nil, err
+	}
+	if be != nil {
+		return be, nil
+	}
+	if !request.Wait {
+		if ees.tip.LastBlockHeight() < request.Height {
+			return nil, fmt.Errorf("block at height %v not yet produced (last block height: %v)",
+				request.Height, ees.tip.LastBlockHeight())
+		}
+		return nil, fmt.Errorf("block at height %v not found in state but should have been! (last block height: %v)",
+			request.Height, ees.tip.LastBlockHeight())
+	}
+	err = ees.streamBlocks(ctx, &BlockRange{End: StreamBound()}, func(block *exec.BlockExecution) error {
+		if block.Height == request.Height {
+			be = block
+			return io.EOF
+		}
+		return nil
+	})
+	if err != io.EOF {
+		return nil, err
+	}
+	return be, nil
+}
 
-	blockRange := request.GetBlockRange()
-	start, end, streaming := blockRange.Bounds(ees.tip.LastBlockHeight())
+func (ees *executionEventsServer) GetBlocks(request *BlocksRequest, stream ExecutionEvents_GetBlocksServer) error {
 	qry, err := query.NewBuilder(request.Query).Query()
 	if err != nil {
-		return fmt.Errorf("could not parse event query: %v", err)
+		return fmt.Errorf("could not parse BlockExecution query: %v", err)
+	}
+	return ees.streamBlocks(stream.Context(), request.BlockRange, func(block *exec.BlockExecution) error {
+		if qry.Matches(block.Tagged()) {
+			return flush(stream, block)
+		}
+		return nil
+	})
+}
+
+func (ees *executionEventsServer) GetTx(ctx context.Context, request *GetTxRequest) (*exec.TxExecution, error) {
+	txe, err := ees.eventsProvider.GetTx(request.TxHash)
+	if err != nil {
+		return nil, err
+	}
+	if txe != nil {
+		return txe, nil
+	}
+	if !request.Wait {
+		return nil, fmt.Errorf("transaction with hash %v not found in state", request.TxHash)
+	}
+	subID := event.GenSubID()
+	out, err := ees.subscribable.Subscribe(ctx, subID, exec.QueryForTxExecution(request.TxHash), SubscribeBufferSize)
+	if err != nil {
+		return nil, err
+	}
+	defer ees.subscribable.UnsubscribeAll(ctx, subID)
+	for msg := range out {
+		select {
+		case <-ctx.Done():
+			return nil, ctx.Err()
+		default:
+			return msg.(*exec.TxExecution), nil
+		}
 	}
+	return nil, fmt.Errorf("subscription waiting for tx %v ended prematurely", request.TxHash)
+}
 
-	if !streaming {
-		return ees.steamEvents(stream, start, end, 1, qry)
+func (ees *executionEventsServer) GetTxs(request *BlocksRequest, stream ExecutionEvents_GetTxsServer) error {
+	qry, err := query.NewBuilder(request.Query).Query()
+	if err != nil {
+		return fmt.Errorf("could not parse TxExecution query: %v", err)
 	}
+	return ees.streamBlocks(stream.Context(), request.BlockRange, func(block *exec.BlockExecution) error {
+		txs := filterTxs(block, qry)
+		if len(txs) > 0 {
+			response := &GetTxsResponse{
+				Height:       block.Height,
+				TxExecutions: txs,
+			}
+			return flush(stream, response)
+		}
+		return nil
+	})
+}
 
-	// Streaming
+func (ees *executionEventsServer) GetEvents(request *BlocksRequest, stream ExecutionEvents_GetEventsServer) error {
+	qry, err := query.NewBuilder(request.Query).Query()
 	if err != nil {
+		return fmt.Errorf("could not parse Event query: %v", err)
+	}
+	return ees.streamBlocks(stream.Context(), request.BlockRange, func(block *exec.BlockExecution) error {
+		evs := filterEvents(block, qry)
+		if len(evs) == 0 {
+			return nil
+		}
+		response := &GetEventsResponse{
+			Height: block.Height,
+			Events: evs,
+		}
+		return flush(stream, response)
+	})
+}
+
+func (ees *executionEventsServer) streamBlocks(ctx context.Context, blockRange *BlockRange,
+	consumer func(*exec.BlockExecution) error) error {
+
+	// Converts the bounds to half-open interval needed
+	start, end, streaming := blockRange.Bounds(ees.tip.LastBlockHeight())
+	ees.logger.TraceMsg("Streaming blocks", "start", start, "end", end, "streaming", streaming)
+
+	// Pull blocks from state and receive the upper bound (exclusive) on the what we were able to send
+	// Set this to start since it will be the start of next streaming batch (if needed)
+	start, err := ees.iterateBlocks(start, end, consumer)
+
+	// If we are not streaming and all blocks requested were retrieved from state then we are done
+	if !streaming && start == end {
 		return err
 	}
 
-	out, err := tendermint.SubscribeNewBlock(context.Background(), ees.emitter)
+	// Otherwise we need to begin streaming blocks as they are produced
+	subID := event.GenSubID()
+	// Subscribe to BlockExecution events
+	out, err := ees.subscribable.Subscribe(ctx, subID, exec.QueryForBlockExecutionFromHeight(end),
+		SubscribeBufferSize)
 	if err != nil {
 		return err
 	}
+	defer ees.subscribable.UnsubscribeAll(context.Background(), subID)
 
-	for newBlock := range out {
-		if newBlock == nil {
-			return fmt.Errorf("received non-new-block event when subscribed with query")
-		}
-		if newBlock.Block == nil {
-			return fmt.Errorf("new block contains no block info: %v", newBlock)
-		}
-		height := uint64(newBlock.Block.Height)
-		start = end
-		end = events.NewKey(height, 0)
-		err := ees.steamEvents(stream, start, end, 1, qry)
-		if err != nil {
-			return err
+	for msg := range out {
+		select {
+		case <-ctx.Done():
+			return ctx.Err()
+		default:
+			block := msg.(*exec.BlockExecution)
+			streamEnd := block.Height
+
+			finished := !streaming && streamEnd >= end
+			if finished {
+				// Truncate streamEnd to final end to get exactly the blocks we want from state
+				streamEnd = end
+			}
+			if start < streamEnd {
+				// This implies there are some blocks between the previous batchEnd (now start) and the current BlockExecution that
+				// we have not emitted so we will pull them from state. This can occur if a block is emitted during/after
+				// the initial streaming but before we have subscribed to block events or if we spill BlockExecutions
+				// when streaming them and need to catch up
+				_, err := ees.iterateBlocks(start, streamEnd, consumer)
+				if err != nil {
+					return err
+				}
+			}
+			if finished {
+				return nil
+			}
+			err = consumer(block)
+			if err != nil {
+				return err
+			}
+			// We've just streamed block so our next start marker is the next block
+			start = block.Height + 1
 		}
 	}
 
 	return nil
 }
 
-func (ees *executionEventsServer) steamEvents(stream pbevents.ExecutionEvents_GetEventsServer, start, end events.Key,
-	batchSize uint64, qry pubsub.Query) error {
-
+// Converts blocks into responses and streams them returning the height one greater than the last seen block
+// that can be used as next start point (half-open interval)
+func (ees *executionEventsServer) iterateBlocks(start, end uint64, consumer func(*exec.BlockExecution) error) (uint64, error) {
 	var streamErr error
-	buf := new(pbevents.GetEventsResponse)
-
-	batchStart := start.Height()
-	_, err := ees.eventsProvider.GetEvents(start, end, func(ev *events.Event) (stop bool) {
-		if qry.Matches(ev) {
-			// Start a new batch, flush the last lot
-			if ev.Header.Index == 0 && (ev.Header.Height-batchStart)%batchSize == 0 {
-				streamErr = flush(stream, buf)
-				if streamErr != nil {
-					return true
-				}
-				batchStart = ev.Header.Height
-				buf = new(pbevents.GetEventsResponse)
+	var lastHeightSeen uint64
+
+	_, err := ees.eventsProvider.GetBlocks(start, end,
+		func(be *exec.BlockExecution) (stop bool) {
+			lastHeightSeen = be.Height
+			streamErr = consumer(be)
+			if streamErr != nil {
+				return true
 			}
-			buf.Events = append(buf.Events, pbevents.GetExecutionEvent(ev))
-		}
-		return false
-	})
+			return false
+		})
+
 	if err != nil {
-		return err
+		return 0, err
 	}
 	if streamErr != nil {
-		return streamErr
+		return 0, streamErr
+	}
+	// Returns the appropriate starting block for the next stream
+	return lastHeightSeen + 1, nil
+}
+
+func filterTxs(be *exec.BlockExecution, qry query.Query) []*exec.TxExecution {
+	var txs []*exec.TxExecution
+	for _, txe := range be.TxExecutions {
+		if qry.Matches(txe.Tagged()) {
+			txs = append(txs, txe)
+		}
+	}
+	return txs
+}
+
+func filterEvents(be *exec.BlockExecution, qry query.Query) []*exec.Event {
+	var evs []*exec.Event
+	for _, txe := range be.TxExecutions {
+		for _, ev := range txe.Events {
+			if qry.Matches(ev.Tagged()) {
+				evs = append(evs, ev)
+			}
+		}
 	}
-	// Flush any remaining events not filling batchSize many blocks
-	return flush(stream, buf)
+	return evs
 }
 
-func flush(stream pbevents.ExecutionEvents_GetEventsServer, buf *pbevents.GetEventsResponse) error {
-	if len(buf.Events) > 0 {
-		err := stream.Send(buf)
+func flush(stream grpc.Stream, buf proto.Message) error {
+	if buf != nil {
+		err := stream.SendMsg(buf)
 		if err != nil {
 			return err
 		}
diff --git a/rpc/rpcevents/integration/events_server_test.go b/rpc/rpcevents/integration/events_server_test.go
deleted file mode 100644
index 0e8aebb14b8259ebdd426e9b51ca2eed9a1e1107..0000000000000000000000000000000000000000
--- a/rpc/rpcevents/integration/events_server_test.go
+++ /dev/null
@@ -1,130 +0,0 @@
-// +build integration
-
-// Space above here matters
-// Copyright 2017 Monax Industries Limited
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//    http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package integration
-
-import (
-	"context"
-	"testing"
-	"time"
-
-	"encoding/json"
-
-	"strings"
-
-	"github.com/hyperledger/burrow/binary"
-	"github.com/hyperledger/burrow/crypto"
-	"github.com/hyperledger/burrow/execution/events"
-	"github.com/hyperledger/burrow/execution/events/pbevents"
-	"github.com/hyperledger/burrow/rpc"
-	"github.com/hyperledger/burrow/rpc/test"
-	"github.com/stretchr/testify/assert"
-	"github.com/stretchr/testify/require"
-	tmTypes "github.com/tendermint/tendermint/types"
-)
-
-const eventWait = 2 * time.Second
-
-func TestEventSubscribeNewBlock(t *testing.T) {
-	testEventSubscribe(t, tmTypes.EventNewBlock, nil, func(evs []*pbevents.Event) {
-		require.True(t, len(evs) > 0, "event poll should return at least 1 event")
-		tendermintEvent := new(rpc.TendermintEvent)
-		tendermintEventJSON := evs[0].GetTendermintEventJSON()
-		require.NoError(t, json.Unmarshal([]byte(tendermintEventJSON), tendermintEvent))
-		newBlock, ok := tendermintEvent.TMEventData.(tmTypes.EventDataNewBlock)
-		require.True(t, ok, "new block event expected")
-		assert.Equal(t, genesisDoc.ChainID(), newBlock.Block.ChainID)
-	})
-}
-
-func TestEventSubscribeCall(t *testing.T) {
-	cli := test.NewTransactorClient(t)
-	create := test.CreateContract(t, cli, inputAccount)
-	address, err := crypto.AddressFromBytes(create.CallData.Callee)
-	require.NoError(t, err)
-	testEventSubscribe(t, events.EventStringAccountCall(address),
-		func() {
-			t.Logf("Calling contract at: %v", address)
-			test.CallContract(t, cli, inputAccount, address.Bytes())
-		},
-		func(evs []*pbevents.Event) {
-			require.Len(t, evs, test.UpsieDownsieCallCount, "should see 30 recursive call events")
-			for i, ev := range evs {
-				assert.Equal(t, uint64(test.UpsieDownsieCallCount-i-1), ev.GetExecutionEvent().GetEventDataCall().GetStackDepth())
-			}
-		})
-}
-
-func TestEventSubscribeLog(t *testing.T) {
-	cli := test.NewTransactorClient(t)
-	create := test.CreateContract(t, cli, inputAccount)
-	address, err := crypto.AddressFromBytes(create.CallData.Callee)
-	require.NoError(t, err)
-	testEventSubscribe(t, events.EventStringLogEvent(address),
-		func() {
-			t.Logf("Calling contract at: %v", address)
-			test.CallContract(t, cli, inputAccount, address.Bytes())
-		},
-		func(evs []*pbevents.Event) {
-			require.Len(t, evs, test.UpsieDownsieCallCount-2)
-			log := evs[0].GetExecutionEvent().GetEventDataLog()
-			depth := binary.Int64FromWord256(binary.LeftPadWord256(log.Topics[2]))
-			direction := strings.TrimRight(string(log.Topics[1]), "\x00")
-			assert.Equal(t, int64(18), depth)
-			assert.Equal(t, "Upsie!", direction)
-		})
-}
-
-func testEventSubscribe(t *testing.T, eventID string, runner func(), eventsCallback func(evs []*pbevents.Event)) {
-	cli := test.NewEventsClient(t)
-	t.Logf("Subscribing to event: %s", eventID)
-	sub, err := cli.EventSubscribe(context.Background(), &pbevents.EventIdParam{
-		EventId: eventID,
-	})
-	require.NoError(t, err)
-	defer cli.EventUnsubscribe(context.Background(), sub)
-
-	if runner != nil {
-		go runner()
-	}
-
-	pollCh := make(chan *pbevents.PollResponse)
-	errCh := make(chan error)
-	// Catch a single block of events
-	go func() {
-		for {
-			time.Sleep(eventWait)
-			poll, err := cli.EventPoll(context.Background(), sub)
-			if err != nil {
-				errCh <- err
-				return
-			}
-			if len(poll.Events) > 0 {
-				pollCh <- poll
-			}
-		}
-	}()
-	//var evs []*pbevents.Event
-	select {
-	case err := <-errCh:
-		require.NoError(t, err, "should be no error from EventPoll")
-	case poll := <-pollCh:
-		eventsCallback(poll.Events)
-	case <-time.After(2 * eventWait):
-		t.Fatal("timed out waiting for poll event")
-	}
-}
diff --git a/rpc/rpcevents/integration/execution_events_server_test.go b/rpc/rpcevents/integration/execution_events_server_test.go
deleted file mode 100644
index cdd80b1df22a6c3e48de046f84dc0fd0a21762c0..0000000000000000000000000000000000000000
--- a/rpc/rpcevents/integration/execution_events_server_test.go
+++ /dev/null
@@ -1,118 +0,0 @@
-// +build integration
-
-// Space above here matters
-// Copyright 2017 Monax Industries Limited
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//    http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package integration
-
-import (
-	"context"
-	"testing"
-
-	"io"
-
-	"github.com/hyperledger/burrow/event"
-	"github.com/hyperledger/burrow/event/query"
-	"github.com/hyperledger/burrow/execution/events"
-	"github.com/hyperledger/burrow/execution/events/pbevents"
-	"github.com/hyperledger/burrow/execution/pbtransactor"
-	"github.com/hyperledger/burrow/rpc/test"
-	"github.com/hyperledger/burrow/txs/payload"
-	"github.com/stretchr/testify/assert"
-	"github.com/stretchr/testify/require"
-)
-
-func TestExecutionEventsSendStream(t *testing.T) {
-	request := &pbevents.GetEventsRequest{
-		BlockRange: pbevents.NewBlockRange(pbevents.LatestBound(), pbevents.StreamBound()),
-	}
-	tcli := test.NewTransactorClient(t)
-	ecli := test.NewExecutionEventsClient(t)
-	stream, err := ecli.GetEvents(context.Background(), request)
-	require.NoError(t, err)
-	numSends := 1
-	for i := 0; i < numSends; i++ {
-		doSends(t, 2, tcli)
-		response, err := stream.Recv()
-		require.NoError(t, err)
-		require.Len(t, response.Events, 4, "expect multiple events")
-		assert.Equal(t, payload.TypeSend.String(), response.Events[0].GetHeader().GetTxType())
-		assert.Equal(t, payload.TypeSend.String(), response.Events[1].GetHeader().GetTxType())
-	}
-	require.NoError(t, stream.CloseSend())
-}
-
-func TestExecutionEventsSend(t *testing.T) {
-	request := &pbevents.GetEventsRequest{
-		BlockRange: pbevents.NewBlockRange(pbevents.AbsoluteBound(kern.Blockchain.LastBlockHeight()),
-			pbevents.AbsoluteBound(300)),
-	}
-	numSends := 1100
-	responses := testExecutionEventsSend(t, numSends, request)
-	assert.Equal(t, numSends*2, totalEvents(responses), "should receive and input and output event per send")
-}
-
-func TestExecutionEventsSendFiltered(t *testing.T) {
-	request := &pbevents.GetEventsRequest{
-		BlockRange: pbevents.NewBlockRange(pbevents.AbsoluteBound(kern.Blockchain.LastBlockHeight()),
-			pbevents.AbsoluteBound(300)),
-		Query: query.NewBuilder().AndEquals(event.EventTypeKey, events.TypeAccountInput.String()).String(),
-	}
-	numSends := 500
-	responses := testExecutionEventsSend(t, numSends, request)
-	assert.Equal(t, numSends, totalEvents(responses), "should receive a single input event per send")
-}
-
-func testExecutionEventsSend(t *testing.T, numSends int, request *pbevents.GetEventsRequest) []*pbevents.GetEventsResponse {
-	doSends(t, numSends, test.NewTransactorClient(t))
-	ecli := test.NewExecutionEventsClient(t)
-
-	evs, err := ecli.GetEvents(context.Background(), request)
-	require.NoError(t, err)
-	var responses []*pbevents.GetEventsResponse
-	for {
-		resp, err := evs.Recv()
-		if err != nil {
-			if err == io.EOF {
-				break
-			}
-			require.NoError(t, err)
-		}
-		responses = append(responses, resp)
-	}
-	return responses
-}
-
-func doSends(t *testing.T, numSends int, cli pbtransactor.TransactorClient) {
-	countCh := test.CommittedTxCount(t, kern.Emitter)
-	for i := 0; i < numSends; i++ {
-		send, err := cli.Send(context.Background(), &pbtransactor.SendParam{
-			InputAccount: inputAccount,
-			Amount:       2003,
-			ToAddress:    privateAccounts[3].Address().Bytes(),
-		})
-		require.NoError(t, err)
-		assert.Equal(t, false, send.CreatesContract)
-	}
-	require.Equal(t, numSends, <-countCh)
-}
-
-func totalEvents(respones []*pbevents.GetEventsResponse) int {
-	i := 0
-	for _, resp := range respones {
-		i += len(resp.Events)
-	}
-	return i
-}
diff --git a/rpc/rpcevents/rpcevents.pb.go b/rpc/rpcevents/rpcevents.pb.go
new file mode 100644
index 0000000000000000000000000000000000000000..d7b9f93685ed61d709ef8114070953cef1447191
--- /dev/null
+++ b/rpc/rpcevents/rpcevents.pb.go
@@ -0,0 +1,1838 @@
+// Code generated by protoc-gen-gogo. DO NOT EDIT.
+// source: rpcevents.proto
+
+/*
+	Package rpcevents is a generated protocol buffer package.
+
+	It is generated from these files:
+		rpcevents.proto
+
+	It has these top-level messages:
+		GetBlockRequest
+		GetTxRequest
+		BlocksRequest
+		GetEventsResponse
+		GetTxsResponse
+		Bound
+		BlockRange
+*/
+package rpcevents
+
+import proto "github.com/gogo/protobuf/proto"
+import golang_proto "github.com/golang/protobuf/proto"
+import fmt "fmt"
+import math "math"
+import _ "github.com/gogo/protobuf/gogoproto"
+import exec "github.com/hyperledger/burrow/execution/exec"
+
+import github_com_hyperledger_burrow_binary "github.com/hyperledger/burrow/binary"
+
+import context "golang.org/x/net/context"
+import grpc "google.golang.org/grpc"
+
+import io "io"
+
+// Reference imports to suppress errors if they are not otherwise used.
+var _ = proto.Marshal
+var _ = golang_proto.Marshal
+var _ = fmt.Errorf
+var _ = math.Inf
+
+// This is a compile-time assertion to ensure that this generated file
+// is compatible with the proto package it is being compiled against.
+// A compilation error at this line likely means your copy of the
+// proto package needs to be updated.
+const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package
+
+type Bound_BoundType int32
+
+const (
+	// Index is absolute index of an item
+	Bound_ABSOLUTE Bound_BoundType = 0
+	// Index is an offset relative to last item
+	Bound_RELATIVE Bound_BoundType = 1
+	// The first block
+	Bound_FIRST Bound_BoundType = 2
+	// Ignore provided index and evaluate to latest index
+	Bound_LATEST Bound_BoundType = 3
+	// Ignore provided index and stream new objects as they are generated
+	Bound_STREAM Bound_BoundType = 4
+)
+
+var Bound_BoundType_name = map[int32]string{
+	0: "ABSOLUTE",
+	1: "RELATIVE",
+	2: "FIRST",
+	3: "LATEST",
+	4: "STREAM",
+}
+var Bound_BoundType_value = map[string]int32{
+	"ABSOLUTE": 0,
+	"RELATIVE": 1,
+	"FIRST":    2,
+	"LATEST":   3,
+	"STREAM":   4,
+}
+
+func (x Bound_BoundType) String() string {
+	return proto.EnumName(Bound_BoundType_name, int32(x))
+}
+func (Bound_BoundType) EnumDescriptor() ([]byte, []int) { return fileDescriptorRpcevents, []int{5, 0} }
+
+type GetBlockRequest struct {
+	// Height of block required
+	Height uint64 `protobuf:"varint,1,opt,name=Height,proto3" json:"Height,omitempty"`
+	// Whether to wait for the block to become available
+	Wait bool `protobuf:"varint,2,opt,name=Wait,proto3" json:"Wait,omitempty"`
+}
+
+func (m *GetBlockRequest) Reset()                    { *m = GetBlockRequest{} }
+func (m *GetBlockRequest) String() string            { return proto.CompactTextString(m) }
+func (*GetBlockRequest) ProtoMessage()               {}
+func (*GetBlockRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpcevents, []int{0} }
+
+func (m *GetBlockRequest) GetHeight() uint64 {
+	if m != nil {
+		return m.Height
+	}
+	return 0
+}
+
+func (m *GetBlockRequest) GetWait() bool {
+	if m != nil {
+		return m.Wait
+	}
+	return false
+}
+
+func (*GetBlockRequest) XXX_MessageName() string {
+	return "rpcevents.GetBlockRequest"
+}
+
+type GetTxRequest struct {
+	// Height of block required
+	TxHash github_com_hyperledger_burrow_binary.HexBytes `protobuf:"bytes,1,opt,name=TxHash,proto3,customtype=github.com/hyperledger/burrow/binary.HexBytes" json:"TxHash"`
+	// Whether to wait for the block to become available
+	Wait bool `protobuf:"varint,2,opt,name=Wait,proto3" json:"Wait,omitempty"`
+}
+
+func (m *GetTxRequest) Reset()                    { *m = GetTxRequest{} }
+func (m *GetTxRequest) String() string            { return proto.CompactTextString(m) }
+func (*GetTxRequest) ProtoMessage()               {}
+func (*GetTxRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpcevents, []int{1} }
+
+func (m *GetTxRequest) GetWait() bool {
+	if m != nil {
+		return m.Wait
+	}
+	return false
+}
+
+func (*GetTxRequest) XXX_MessageName() string {
+	return "rpcevents.GetTxRequest"
+}
+
+type BlocksRequest struct {
+	BlockRange *BlockRange `protobuf:"bytes,1,opt,name=BlockRange" json:"BlockRange,omitempty"`
+	// Specify a query on which to match the tags of events.
+	// Tag        | Match type | Values
+	// -----------------------------------------
+	//   All events
+	// -----------------------------------------
+	// TxType       | String     | "UnknownTx", "SendTx", "CallTx", "NameTx", "BondTx", "UnbondTx", "PermissionsTx", "GovernanceTx"
+	// TxHash       | String     | bytes
+	// EventType    | String     | "CallEvent", "LogEvent", "AccountInputEvent", "AccountOutputEvent"
+	// EventID      | String     | string
+	// Height       | Integer    | uint64
+	// Index        | Integer    | uint64
+	// MessageType  | String     | Go type name
+	// -----------------------------------------
+	//   Log event
+	// -----------------------------------------
+	// Address      | String     | Address (hex)
+	// Log<0-4>     | String     | Word256 (hex)
+	// Log<0-4>Text | String     | string (trimmed)
+	// -----------------------------------------
+	//   Call event
+	// -----------------------------------------
+	// Origin       | String     | Address (hex)
+	// Callee       | String     | Address (hex)
+	// Caller       | String     | Address (hex)
+	// Value        | Integer    | uint64
+	// Gas          | Integer    | uint64
+	// StackDepth   | Integer    | uint64
+	// Exception    | String     | string
+	// -----------------------------------------
+	//   Tx event (input/output)
+	// -----------------------------------------
+	// Exception  | String     | string
+	//
+	// For example:
+	// EventType = 'LogEvent' AND EventID CONTAINS 'bar' AND TxHash = '020304' AND Height >= 34 AND Index < 3 AND Address = 'DEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEF'
+	Query string `protobuf:"bytes,2,opt,name=Query,proto3" json:"Query,omitempty"`
+}
+
+func (m *BlocksRequest) Reset()                    { *m = BlocksRequest{} }
+func (m *BlocksRequest) String() string            { return proto.CompactTextString(m) }
+func (*BlocksRequest) ProtoMessage()               {}
+func (*BlocksRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpcevents, []int{2} }
+
+func (m *BlocksRequest) GetBlockRange() *BlockRange {
+	if m != nil {
+		return m.BlockRange
+	}
+	return nil
+}
+
+func (m *BlocksRequest) GetQuery() string {
+	if m != nil {
+		return m.Query
+	}
+	return ""
+}
+
+func (*BlocksRequest) XXX_MessageName() string {
+	return "rpcevents.BlocksRequest"
+}
+
+type GetEventsResponse struct {
+	Height uint64        `protobuf:"varint,1,opt,name=Height,proto3" json:"Height,omitempty"`
+	Events []*exec.Event `protobuf:"bytes,2,rep,name=Events" json:"Events,omitempty"`
+}
+
+func (m *GetEventsResponse) Reset()                    { *m = GetEventsResponse{} }
+func (m *GetEventsResponse) String() string            { return proto.CompactTextString(m) }
+func (*GetEventsResponse) ProtoMessage()               {}
+func (*GetEventsResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpcevents, []int{3} }
+
+func (m *GetEventsResponse) GetHeight() uint64 {
+	if m != nil {
+		return m.Height
+	}
+	return 0
+}
+
+func (m *GetEventsResponse) GetEvents() []*exec.Event {
+	if m != nil {
+		return m.Events
+	}
+	return nil
+}
+
+func (*GetEventsResponse) XXX_MessageName() string {
+	return "rpcevents.GetEventsResponse"
+}
+
+type GetTxsResponse struct {
+	Height       uint64              `protobuf:"varint,1,opt,name=Height,proto3" json:"Height,omitempty"`
+	TxExecutions []*exec.TxExecution `protobuf:"bytes,2,rep,name=TxExecutions" json:"TxExecutions,omitempty"`
+}
+
+func (m *GetTxsResponse) Reset()                    { *m = GetTxsResponse{} }
+func (m *GetTxsResponse) String() string            { return proto.CompactTextString(m) }
+func (*GetTxsResponse) ProtoMessage()               {}
+func (*GetTxsResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpcevents, []int{4} }
+
+func (m *GetTxsResponse) GetHeight() uint64 {
+	if m != nil {
+		return m.Height
+	}
+	return 0
+}
+
+func (m *GetTxsResponse) GetTxExecutions() []*exec.TxExecution {
+	if m != nil {
+		return m.TxExecutions
+	}
+	return nil
+}
+
+func (*GetTxsResponse) XXX_MessageName() string {
+	return "rpcevents.GetTxsResponse"
+}
+
+type Bound struct {
+	Type  Bound_BoundType `protobuf:"varint,1,opt,name=Type,proto3,enum=rpcevents.Bound_BoundType" json:"Type,omitempty"`
+	Index uint64          `protobuf:"varint,2,opt,name=Index,proto3" json:"Index,omitempty"`
+}
+
+func (m *Bound) Reset()                    { *m = Bound{} }
+func (m *Bound) String() string            { return proto.CompactTextString(m) }
+func (*Bound) ProtoMessage()               {}
+func (*Bound) Descriptor() ([]byte, []int) { return fileDescriptorRpcevents, []int{5} }
+
+func (m *Bound) GetType() Bound_BoundType {
+	if m != nil {
+		return m.Type
+	}
+	return Bound_ABSOLUTE
+}
+
+func (m *Bound) GetIndex() uint64 {
+	if m != nil {
+		return m.Index
+	}
+	return 0
+}
+
+func (*Bound) XXX_MessageName() string {
+	return "rpcevents.Bound"
+}
+
+// An inclusive range of blocks to include in output
+type BlockRange struct {
+	// Bounds can be set to:
+	// absolute: block height
+	// relative: block height counting back from latest
+	// latest: latest block when call is processed
+	// stream: for End keep sending new blocks, for start same as latest
+	Start *Bound `protobuf:"bytes,1,opt,name=Start" json:"Start,omitempty"`
+	End   *Bound `protobuf:"bytes,2,opt,name=End" json:"End,omitempty"`
+}
+
+func (m *BlockRange) Reset()                    { *m = BlockRange{} }
+func (m *BlockRange) String() string            { return proto.CompactTextString(m) }
+func (*BlockRange) ProtoMessage()               {}
+func (*BlockRange) Descriptor() ([]byte, []int) { return fileDescriptorRpcevents, []int{6} }
+
+func (m *BlockRange) GetStart() *Bound {
+	if m != nil {
+		return m.Start
+	}
+	return nil
+}
+
+func (m *BlockRange) GetEnd() *Bound {
+	if m != nil {
+		return m.End
+	}
+	return nil
+}
+
+func (*BlockRange) XXX_MessageName() string {
+	return "rpcevents.BlockRange"
+}
+func init() {
+	proto.RegisterType((*GetBlockRequest)(nil), "rpcevents.GetBlockRequest")
+	golang_proto.RegisterType((*GetBlockRequest)(nil), "rpcevents.GetBlockRequest")
+	proto.RegisterType((*GetTxRequest)(nil), "rpcevents.GetTxRequest")
+	golang_proto.RegisterType((*GetTxRequest)(nil), "rpcevents.GetTxRequest")
+	proto.RegisterType((*BlocksRequest)(nil), "rpcevents.BlocksRequest")
+	golang_proto.RegisterType((*BlocksRequest)(nil), "rpcevents.BlocksRequest")
+	proto.RegisterType((*GetEventsResponse)(nil), "rpcevents.GetEventsResponse")
+	golang_proto.RegisterType((*GetEventsResponse)(nil), "rpcevents.GetEventsResponse")
+	proto.RegisterType((*GetTxsResponse)(nil), "rpcevents.GetTxsResponse")
+	golang_proto.RegisterType((*GetTxsResponse)(nil), "rpcevents.GetTxsResponse")
+	proto.RegisterType((*Bound)(nil), "rpcevents.Bound")
+	golang_proto.RegisterType((*Bound)(nil), "rpcevents.Bound")
+	proto.RegisterType((*BlockRange)(nil), "rpcevents.BlockRange")
+	golang_proto.RegisterType((*BlockRange)(nil), "rpcevents.BlockRange")
+	proto.RegisterEnum("rpcevents.Bound_BoundType", Bound_BoundType_name, Bound_BoundType_value)
+	golang_proto.RegisterEnum("rpcevents.Bound_BoundType", Bound_BoundType_name, Bound_BoundType_value)
+}
+
+// Reference imports to suppress errors if they are not otherwise used.
+var _ context.Context
+var _ grpc.ClientConn
+
+// This is a compile-time assertion to ensure that this generated file
+// is compatible with the grpc package it is being compiled against.
+const _ = grpc.SupportPackageIsVersion4
+
+// Client API for ExecutionEvents service
+
+type ExecutionEventsClient interface {
+	// Get Blockexecution at particular height
+	GetBlock(ctx context.Context, in *GetBlockRequest, opts ...grpc.CallOption) (*exec.BlockExecution, error)
+	// Get BlockExecutions for a range of blocks
+	GetBlocks(ctx context.Context, in *BlocksRequest, opts ...grpc.CallOption) (ExecutionEvents_GetBlocksClient, error)
+	// Get a particular TxExecution
+	GetTx(ctx context.Context, in *GetTxRequest, opts ...grpc.CallOption) (*exec.TxExecution, error)
+	// Get TxExecutions for a range of block
+	GetTxs(ctx context.Context, in *BlocksRequest, opts ...grpc.CallOption) (ExecutionEvents_GetTxsClient, error)
+	// GetEvents provides events streaming one block at a time - that is all events emitted in a particular block
+	// are guaranteed to be delivered in each GetEventsResponse
+	GetEvents(ctx context.Context, in *BlocksRequest, opts ...grpc.CallOption) (ExecutionEvents_GetEventsClient, error)
+}
+
+type executionEventsClient struct {
+	cc *grpc.ClientConn
+}
+
+func NewExecutionEventsClient(cc *grpc.ClientConn) ExecutionEventsClient {
+	return &executionEventsClient{cc}
+}
+
+func (c *executionEventsClient) GetBlock(ctx context.Context, in *GetBlockRequest, opts ...grpc.CallOption) (*exec.BlockExecution, error) {
+	out := new(exec.BlockExecution)
+	err := grpc.Invoke(ctx, "/rpcevents.ExecutionEvents/GetBlock", in, out, c.cc, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *executionEventsClient) GetBlocks(ctx context.Context, in *BlocksRequest, opts ...grpc.CallOption) (ExecutionEvents_GetBlocksClient, error) {
+	stream, err := grpc.NewClientStream(ctx, &_ExecutionEvents_serviceDesc.Streams[0], c.cc, "/rpcevents.ExecutionEvents/GetBlocks", opts...)
+	if err != nil {
+		return nil, err
+	}
+	x := &executionEventsGetBlocksClient{stream}
+	if err := x.ClientStream.SendMsg(in); err != nil {
+		return nil, err
+	}
+	if err := x.ClientStream.CloseSend(); err != nil {
+		return nil, err
+	}
+	return x, nil
+}
+
+type ExecutionEvents_GetBlocksClient interface {
+	Recv() (*exec.BlockExecution, error)
+	grpc.ClientStream
+}
+
+type executionEventsGetBlocksClient struct {
+	grpc.ClientStream
+}
+
+func (x *executionEventsGetBlocksClient) Recv() (*exec.BlockExecution, error) {
+	m := new(exec.BlockExecution)
+	if err := x.ClientStream.RecvMsg(m); err != nil {
+		return nil, err
+	}
+	return m, nil
+}
+
+func (c *executionEventsClient) GetTx(ctx context.Context, in *GetTxRequest, opts ...grpc.CallOption) (*exec.TxExecution, error) {
+	out := new(exec.TxExecution)
+	err := grpc.Invoke(ctx, "/rpcevents.ExecutionEvents/GetTx", in, out, c.cc, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *executionEventsClient) GetTxs(ctx context.Context, in *BlocksRequest, opts ...grpc.CallOption) (ExecutionEvents_GetTxsClient, error) {
+	stream, err := grpc.NewClientStream(ctx, &_ExecutionEvents_serviceDesc.Streams[1], c.cc, "/rpcevents.ExecutionEvents/GetTxs", opts...)
+	if err != nil {
+		return nil, err
+	}
+	x := &executionEventsGetTxsClient{stream}
+	if err := x.ClientStream.SendMsg(in); err != nil {
+		return nil, err
+	}
+	if err := x.ClientStream.CloseSend(); err != nil {
+		return nil, err
+	}
+	return x, nil
+}
+
+type ExecutionEvents_GetTxsClient interface {
+	Recv() (*GetTxsResponse, error)
+	grpc.ClientStream
+}
+
+type executionEventsGetTxsClient struct {
+	grpc.ClientStream
+}
+
+func (x *executionEventsGetTxsClient) Recv() (*GetTxsResponse, error) {
+	m := new(GetTxsResponse)
+	if err := x.ClientStream.RecvMsg(m); err != nil {
+		return nil, err
+	}
+	return m, nil
+}
+
+func (c *executionEventsClient) GetEvents(ctx context.Context, in *BlocksRequest, opts ...grpc.CallOption) (ExecutionEvents_GetEventsClient, error) {
+	stream, err := grpc.NewClientStream(ctx, &_ExecutionEvents_serviceDesc.Streams[2], c.cc, "/rpcevents.ExecutionEvents/GetEvents", opts...)
+	if err != nil {
+		return nil, err
+	}
+	x := &executionEventsGetEventsClient{stream}
+	if err := x.ClientStream.SendMsg(in); err != nil {
+		return nil, err
+	}
+	if err := x.ClientStream.CloseSend(); err != nil {
+		return nil, err
+	}
+	return x, nil
+}
+
+type ExecutionEvents_GetEventsClient interface {
+	Recv() (*GetEventsResponse, error)
+	grpc.ClientStream
+}
+
+type executionEventsGetEventsClient struct {
+	grpc.ClientStream
+}
+
+func (x *executionEventsGetEventsClient) Recv() (*GetEventsResponse, error) {
+	m := new(GetEventsResponse)
+	if err := x.ClientStream.RecvMsg(m); err != nil {
+		return nil, err
+	}
+	return m, nil
+}
+
+// Server API for ExecutionEvents service
+
+type ExecutionEventsServer interface {
+	// Get Blockexecution at particular height
+	GetBlock(context.Context, *GetBlockRequest) (*exec.BlockExecution, error)
+	// Get BlockExecutions for a range of blocks
+	GetBlocks(*BlocksRequest, ExecutionEvents_GetBlocksServer) error
+	// Get a particular TxExecution
+	GetTx(context.Context, *GetTxRequest) (*exec.TxExecution, error)
+	// Get TxExecutions for a range of block
+	GetTxs(*BlocksRequest, ExecutionEvents_GetTxsServer) error
+	// GetEvents provides events streaming one block at a time - that is all events emitted in a particular block
+	// are guaranteed to be delivered in each GetEventsResponse
+	GetEvents(*BlocksRequest, ExecutionEvents_GetEventsServer) error
+}
+
+func RegisterExecutionEventsServer(s *grpc.Server, srv ExecutionEventsServer) {
+	s.RegisterService(&_ExecutionEvents_serviceDesc, srv)
+}
+
+func _ExecutionEvents_GetBlock_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(GetBlockRequest)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(ExecutionEventsServer).GetBlock(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/rpcevents.ExecutionEvents/GetBlock",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(ExecutionEventsServer).GetBlock(ctx, req.(*GetBlockRequest))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _ExecutionEvents_GetBlocks_Handler(srv interface{}, stream grpc.ServerStream) error {
+	m := new(BlocksRequest)
+	if err := stream.RecvMsg(m); err != nil {
+		return err
+	}
+	return srv.(ExecutionEventsServer).GetBlocks(m, &executionEventsGetBlocksServer{stream})
+}
+
+type ExecutionEvents_GetBlocksServer interface {
+	Send(*exec.BlockExecution) error
+	grpc.ServerStream
+}
+
+type executionEventsGetBlocksServer struct {
+	grpc.ServerStream
+}
+
+func (x *executionEventsGetBlocksServer) Send(m *exec.BlockExecution) error {
+	return x.ServerStream.SendMsg(m)
+}
+
+func _ExecutionEvents_GetTx_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(GetTxRequest)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(ExecutionEventsServer).GetTx(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/rpcevents.ExecutionEvents/GetTx",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(ExecutionEventsServer).GetTx(ctx, req.(*GetTxRequest))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _ExecutionEvents_GetTxs_Handler(srv interface{}, stream grpc.ServerStream) error {
+	m := new(BlocksRequest)
+	if err := stream.RecvMsg(m); err != nil {
+		return err
+	}
+	return srv.(ExecutionEventsServer).GetTxs(m, &executionEventsGetTxsServer{stream})
+}
+
+type ExecutionEvents_GetTxsServer interface {
+	Send(*GetTxsResponse) error
+	grpc.ServerStream
+}
+
+type executionEventsGetTxsServer struct {
+	grpc.ServerStream
+}
+
+func (x *executionEventsGetTxsServer) Send(m *GetTxsResponse) error {
+	return x.ServerStream.SendMsg(m)
+}
+
+func _ExecutionEvents_GetEvents_Handler(srv interface{}, stream grpc.ServerStream) error {
+	m := new(BlocksRequest)
+	if err := stream.RecvMsg(m); err != nil {
+		return err
+	}
+	return srv.(ExecutionEventsServer).GetEvents(m, &executionEventsGetEventsServer{stream})
+}
+
+type ExecutionEvents_GetEventsServer interface {
+	Send(*GetEventsResponse) error
+	grpc.ServerStream
+}
+
+type executionEventsGetEventsServer struct {
+	grpc.ServerStream
+}
+
+func (x *executionEventsGetEventsServer) Send(m *GetEventsResponse) error {
+	return x.ServerStream.SendMsg(m)
+}
+
+var _ExecutionEvents_serviceDesc = grpc.ServiceDesc{
+	ServiceName: "rpcevents.ExecutionEvents",
+	HandlerType: (*ExecutionEventsServer)(nil),
+	Methods: []grpc.MethodDesc{
+		{
+			MethodName: "GetBlock",
+			Handler:    _ExecutionEvents_GetBlock_Handler,
+		},
+		{
+			MethodName: "GetTx",
+			Handler:    _ExecutionEvents_GetTx_Handler,
+		},
+	},
+	Streams: []grpc.StreamDesc{
+		{
+			StreamName:    "GetBlocks",
+			Handler:       _ExecutionEvents_GetBlocks_Handler,
+			ServerStreams: true,
+		},
+		{
+			StreamName:    "GetTxs",
+			Handler:       _ExecutionEvents_GetTxs_Handler,
+			ServerStreams: true,
+		},
+		{
+			StreamName:    "GetEvents",
+			Handler:       _ExecutionEvents_GetEvents_Handler,
+			ServerStreams: true,
+		},
+	},
+	Metadata: "rpcevents.proto",
+}
+
+func (m *GetBlockRequest) Marshal() (dAtA []byte, err error) {
+	size := m.Size()
+	dAtA = make([]byte, size)
+	n, err := m.MarshalTo(dAtA)
+	if err != nil {
+		return nil, err
+	}
+	return dAtA[:n], nil
+}
+
+func (m *GetBlockRequest) MarshalTo(dAtA []byte) (int, error) {
+	var i int
+	_ = i
+	var l int
+	_ = l
+	if m.Height != 0 {
+		dAtA[i] = 0x8
+		i++
+		i = encodeVarintRpcevents(dAtA, i, uint64(m.Height))
+	}
+	if m.Wait {
+		dAtA[i] = 0x10
+		i++
+		if m.Wait {
+			dAtA[i] = 1
+		} else {
+			dAtA[i] = 0
+		}
+		i++
+	}
+	return i, nil
+}
+
+func (m *GetTxRequest) Marshal() (dAtA []byte, err error) {
+	size := m.Size()
+	dAtA = make([]byte, size)
+	n, err := m.MarshalTo(dAtA)
+	if err != nil {
+		return nil, err
+	}
+	return dAtA[:n], nil
+}
+
+func (m *GetTxRequest) MarshalTo(dAtA []byte) (int, error) {
+	var i int
+	_ = i
+	var l int
+	_ = l
+	dAtA[i] = 0xa
+	i++
+	i = encodeVarintRpcevents(dAtA, i, uint64(m.TxHash.Size()))
+	n1, err := m.TxHash.MarshalTo(dAtA[i:])
+	if err != nil {
+		return 0, err
+	}
+	i += n1
+	if m.Wait {
+		dAtA[i] = 0x10
+		i++
+		if m.Wait {
+			dAtA[i] = 1
+		} else {
+			dAtA[i] = 0
+		}
+		i++
+	}
+	return i, nil
+}
+
+func (m *BlocksRequest) Marshal() (dAtA []byte, err error) {
+	size := m.Size()
+	dAtA = make([]byte, size)
+	n, err := m.MarshalTo(dAtA)
+	if err != nil {
+		return nil, err
+	}
+	return dAtA[:n], nil
+}
+
+func (m *BlocksRequest) MarshalTo(dAtA []byte) (int, error) {
+	var i int
+	_ = i
+	var l int
+	_ = l
+	if m.BlockRange != nil {
+		dAtA[i] = 0xa
+		i++
+		i = encodeVarintRpcevents(dAtA, i, uint64(m.BlockRange.Size()))
+		n2, err := m.BlockRange.MarshalTo(dAtA[i:])
+		if err != nil {
+			return 0, err
+		}
+		i += n2
+	}
+	if len(m.Query) > 0 {
+		dAtA[i] = 0x12
+		i++
+		i = encodeVarintRpcevents(dAtA, i, uint64(len(m.Query)))
+		i += copy(dAtA[i:], m.Query)
+	}
+	return i, nil
+}
+
+func (m *GetEventsResponse) Marshal() (dAtA []byte, err error) {
+	size := m.Size()
+	dAtA = make([]byte, size)
+	n, err := m.MarshalTo(dAtA)
+	if err != nil {
+		return nil, err
+	}
+	return dAtA[:n], nil
+}
+
+func (m *GetEventsResponse) MarshalTo(dAtA []byte) (int, error) {
+	var i int
+	_ = i
+	var l int
+	_ = l
+	if m.Height != 0 {
+		dAtA[i] = 0x8
+		i++
+		i = encodeVarintRpcevents(dAtA, i, uint64(m.Height))
+	}
+	if len(m.Events) > 0 {
+		for _, msg := range m.Events {
+			dAtA[i] = 0x12
+			i++
+			i = encodeVarintRpcevents(dAtA, i, uint64(msg.Size()))
+			n, err := msg.MarshalTo(dAtA[i:])
+			if err != nil {
+				return 0, err
+			}
+			i += n
+		}
+	}
+	return i, nil
+}
+
+func (m *GetTxsResponse) Marshal() (dAtA []byte, err error) {
+	size := m.Size()
+	dAtA = make([]byte, size)
+	n, err := m.MarshalTo(dAtA)
+	if err != nil {
+		return nil, err
+	}
+	return dAtA[:n], nil
+}
+
+func (m *GetTxsResponse) MarshalTo(dAtA []byte) (int, error) {
+	var i int
+	_ = i
+	var l int
+	_ = l
+	if m.Height != 0 {
+		dAtA[i] = 0x8
+		i++
+		i = encodeVarintRpcevents(dAtA, i, uint64(m.Height))
+	}
+	if len(m.TxExecutions) > 0 {
+		for _, msg := range m.TxExecutions {
+			dAtA[i] = 0x12
+			i++
+			i = encodeVarintRpcevents(dAtA, i, uint64(msg.Size()))
+			n, err := msg.MarshalTo(dAtA[i:])
+			if err != nil {
+				return 0, err
+			}
+			i += n
+		}
+	}
+	return i, nil
+}
+
+func (m *Bound) Marshal() (dAtA []byte, err error) {
+	size := m.Size()
+	dAtA = make([]byte, size)
+	n, err := m.MarshalTo(dAtA)
+	if err != nil {
+		return nil, err
+	}
+	return dAtA[:n], nil
+}
+
+func (m *Bound) MarshalTo(dAtA []byte) (int, error) {
+	var i int
+	_ = i
+	var l int
+	_ = l
+	if m.Type != 0 {
+		dAtA[i] = 0x8
+		i++
+		i = encodeVarintRpcevents(dAtA, i, uint64(m.Type))
+	}
+	if m.Index != 0 {
+		dAtA[i] = 0x10
+		i++
+		i = encodeVarintRpcevents(dAtA, i, uint64(m.Index))
+	}
+	return i, nil
+}
+
+func (m *BlockRange) Marshal() (dAtA []byte, err error) {
+	size := m.Size()
+	dAtA = make([]byte, size)
+	n, err := m.MarshalTo(dAtA)
+	if err != nil {
+		return nil, err
+	}
+	return dAtA[:n], nil
+}
+
+func (m *BlockRange) MarshalTo(dAtA []byte) (int, error) {
+	var i int
+	_ = i
+	var l int
+	_ = l
+	if m.Start != nil {
+		dAtA[i] = 0xa
+		i++
+		i = encodeVarintRpcevents(dAtA, i, uint64(m.Start.Size()))
+		n3, err := m.Start.MarshalTo(dAtA[i:])
+		if err != nil {
+			return 0, err
+		}
+		i += n3
+	}
+	if m.End != nil {
+		dAtA[i] = 0x12
+		i++
+		i = encodeVarintRpcevents(dAtA, i, uint64(m.End.Size()))
+		n4, err := m.End.MarshalTo(dAtA[i:])
+		if err != nil {
+			return 0, err
+		}
+		i += n4
+	}
+	return i, nil
+}
+
+func encodeVarintRpcevents(dAtA []byte, offset int, v uint64) int {
+	for v >= 1<<7 {
+		dAtA[offset] = uint8(v&0x7f | 0x80)
+		v >>= 7
+		offset++
+	}
+	dAtA[offset] = uint8(v)
+	return offset + 1
+}
+func (m *GetBlockRequest) Size() (n int) {
+	var l int
+	_ = l
+	if m.Height != 0 {
+		n += 1 + sovRpcevents(uint64(m.Height))
+	}
+	if m.Wait {
+		n += 2
+	}
+	return n
+}
+
+func (m *GetTxRequest) Size() (n int) {
+	var l int
+	_ = l
+	l = m.TxHash.Size()
+	n += 1 + l + sovRpcevents(uint64(l))
+	if m.Wait {
+		n += 2
+	}
+	return n
+}
+
+func (m *BlocksRequest) Size() (n int) {
+	var l int
+	_ = l
+	if m.BlockRange != nil {
+		l = m.BlockRange.Size()
+		n += 1 + l + sovRpcevents(uint64(l))
+	}
+	l = len(m.Query)
+	if l > 0 {
+		n += 1 + l + sovRpcevents(uint64(l))
+	}
+	return n
+}
+
+func (m *GetEventsResponse) Size() (n int) {
+	var l int
+	_ = l
+	if m.Height != 0 {
+		n += 1 + sovRpcevents(uint64(m.Height))
+	}
+	if len(m.Events) > 0 {
+		for _, e := range m.Events {
+			l = e.Size()
+			n += 1 + l + sovRpcevents(uint64(l))
+		}
+	}
+	return n
+}
+
+func (m *GetTxsResponse) Size() (n int) {
+	var l int
+	_ = l
+	if m.Height != 0 {
+		n += 1 + sovRpcevents(uint64(m.Height))
+	}
+	if len(m.TxExecutions) > 0 {
+		for _, e := range m.TxExecutions {
+			l = e.Size()
+			n += 1 + l + sovRpcevents(uint64(l))
+		}
+	}
+	return n
+}
+
+func (m *Bound) Size() (n int) {
+	var l int
+	_ = l
+	if m.Type != 0 {
+		n += 1 + sovRpcevents(uint64(m.Type))
+	}
+	if m.Index != 0 {
+		n += 1 + sovRpcevents(uint64(m.Index))
+	}
+	return n
+}
+
+func (m *BlockRange) Size() (n int) {
+	var l int
+	_ = l
+	if m.Start != nil {
+		l = m.Start.Size()
+		n += 1 + l + sovRpcevents(uint64(l))
+	}
+	if m.End != nil {
+		l = m.End.Size()
+		n += 1 + l + sovRpcevents(uint64(l))
+	}
+	return n
+}
+
+func sovRpcevents(x uint64) (n int) {
+	for {
+		n++
+		x >>= 7
+		if x == 0 {
+			break
+		}
+	}
+	return n
+}
+func sozRpcevents(x uint64) (n int) {
+	return sovRpcevents(uint64((x << 1) ^ uint64((int64(x) >> 63))))
+}
+func (m *GetBlockRequest) Unmarshal(dAtA []byte) error {
+	l := len(dAtA)
+	iNdEx := 0
+	for iNdEx < l {
+		preIndex := iNdEx
+		var wire uint64
+		for shift := uint(0); ; shift += 7 {
+			if shift >= 64 {
+				return ErrIntOverflowRpcevents
+			}
+			if iNdEx >= l {
+				return io.ErrUnexpectedEOF
+			}
+			b := dAtA[iNdEx]
+			iNdEx++
+			wire |= (uint64(b) & 0x7F) << shift
+			if b < 0x80 {
+				break
+			}
+		}
+		fieldNum := int32(wire >> 3)
+		wireType := int(wire & 0x7)
+		if wireType == 4 {
+			return fmt.Errorf("proto: GetBlockRequest: wiretype end group for non-group")
+		}
+		if fieldNum <= 0 {
+			return fmt.Errorf("proto: GetBlockRequest: illegal tag %d (wire type %d)", fieldNum, wire)
+		}
+		switch fieldNum {
+		case 1:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Height", wireType)
+			}
+			m.Height = 0
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowRpcevents
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				m.Height |= (uint64(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+		case 2:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Wait", wireType)
+			}
+			var v int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowRpcevents
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				v |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			m.Wait = bool(v != 0)
+		default:
+			iNdEx = preIndex
+			skippy, err := skipRpcevents(dAtA[iNdEx:])
+			if err != nil {
+				return err
+			}
+			if skippy < 0 {
+				return ErrInvalidLengthRpcevents
+			}
+			if (iNdEx + skippy) > l {
+				return io.ErrUnexpectedEOF
+			}
+			iNdEx += skippy
+		}
+	}
+
+	if iNdEx > l {
+		return io.ErrUnexpectedEOF
+	}
+	return nil
+}
+func (m *GetTxRequest) Unmarshal(dAtA []byte) error {
+	l := len(dAtA)
+	iNdEx := 0
+	for iNdEx < l {
+		preIndex := iNdEx
+		var wire uint64
+		for shift := uint(0); ; shift += 7 {
+			if shift >= 64 {
+				return ErrIntOverflowRpcevents
+			}
+			if iNdEx >= l {
+				return io.ErrUnexpectedEOF
+			}
+			b := dAtA[iNdEx]
+			iNdEx++
+			wire |= (uint64(b) & 0x7F) << shift
+			if b < 0x80 {
+				break
+			}
+		}
+		fieldNum := int32(wire >> 3)
+		wireType := int(wire & 0x7)
+		if wireType == 4 {
+			return fmt.Errorf("proto: GetTxRequest: wiretype end group for non-group")
+		}
+		if fieldNum <= 0 {
+			return fmt.Errorf("proto: GetTxRequest: illegal tag %d (wire type %d)", fieldNum, wire)
+		}
+		switch fieldNum {
+		case 1:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field TxHash", wireType)
+			}
+			var byteLen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowRpcevents
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				byteLen |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if byteLen < 0 {
+				return ErrInvalidLengthRpcevents
+			}
+			postIndex := iNdEx + byteLen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			if err := m.TxHash.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+				return err
+			}
+			iNdEx = postIndex
+		case 2:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Wait", wireType)
+			}
+			var v int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowRpcevents
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				v |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			m.Wait = bool(v != 0)
+		default:
+			iNdEx = preIndex
+			skippy, err := skipRpcevents(dAtA[iNdEx:])
+			if err != nil {
+				return err
+			}
+			if skippy < 0 {
+				return ErrInvalidLengthRpcevents
+			}
+			if (iNdEx + skippy) > l {
+				return io.ErrUnexpectedEOF
+			}
+			iNdEx += skippy
+		}
+	}
+
+	if iNdEx > l {
+		return io.ErrUnexpectedEOF
+	}
+	return nil
+}
+func (m *BlocksRequest) Unmarshal(dAtA []byte) error {
+	l := len(dAtA)
+	iNdEx := 0
+	for iNdEx < l {
+		preIndex := iNdEx
+		var wire uint64
+		for shift := uint(0); ; shift += 7 {
+			if shift >= 64 {
+				return ErrIntOverflowRpcevents
+			}
+			if iNdEx >= l {
+				return io.ErrUnexpectedEOF
+			}
+			b := dAtA[iNdEx]
+			iNdEx++
+			wire |= (uint64(b) & 0x7F) << shift
+			if b < 0x80 {
+				break
+			}
+		}
+		fieldNum := int32(wire >> 3)
+		wireType := int(wire & 0x7)
+		if wireType == 4 {
+			return fmt.Errorf("proto: BlocksRequest: wiretype end group for non-group")
+		}
+		if fieldNum <= 0 {
+			return fmt.Errorf("proto: BlocksRequest: illegal tag %d (wire type %d)", fieldNum, wire)
+		}
+		switch fieldNum {
+		case 1:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field BlockRange", wireType)
+			}
+			var msglen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowRpcevents
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				msglen |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if msglen < 0 {
+				return ErrInvalidLengthRpcevents
+			}
+			postIndex := iNdEx + msglen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			if m.BlockRange == nil {
+				m.BlockRange = &BlockRange{}
+			}
+			if err := m.BlockRange.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+				return err
+			}
+			iNdEx = postIndex
+		case 2:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Query", wireType)
+			}
+			var stringLen uint64
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowRpcevents
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				stringLen |= (uint64(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			intStringLen := int(stringLen)
+			if intStringLen < 0 {
+				return ErrInvalidLengthRpcevents
+			}
+			postIndex := iNdEx + intStringLen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			m.Query = string(dAtA[iNdEx:postIndex])
+			iNdEx = postIndex
+		default:
+			iNdEx = preIndex
+			skippy, err := skipRpcevents(dAtA[iNdEx:])
+			if err != nil {
+				return err
+			}
+			if skippy < 0 {
+				return ErrInvalidLengthRpcevents
+			}
+			if (iNdEx + skippy) > l {
+				return io.ErrUnexpectedEOF
+			}
+			iNdEx += skippy
+		}
+	}
+
+	if iNdEx > l {
+		return io.ErrUnexpectedEOF
+	}
+	return nil
+}
+func (m *GetEventsResponse) Unmarshal(dAtA []byte) error {
+	l := len(dAtA)
+	iNdEx := 0
+	for iNdEx < l {
+		preIndex := iNdEx
+		var wire uint64
+		for shift := uint(0); ; shift += 7 {
+			if shift >= 64 {
+				return ErrIntOverflowRpcevents
+			}
+			if iNdEx >= l {
+				return io.ErrUnexpectedEOF
+			}
+			b := dAtA[iNdEx]
+			iNdEx++
+			wire |= (uint64(b) & 0x7F) << shift
+			if b < 0x80 {
+				break
+			}
+		}
+		fieldNum := int32(wire >> 3)
+		wireType := int(wire & 0x7)
+		if wireType == 4 {
+			return fmt.Errorf("proto: GetEventsResponse: wiretype end group for non-group")
+		}
+		if fieldNum <= 0 {
+			return fmt.Errorf("proto: GetEventsResponse: illegal tag %d (wire type %d)", fieldNum, wire)
+		}
+		switch fieldNum {
+		case 1:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Height", wireType)
+			}
+			m.Height = 0
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowRpcevents
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				m.Height |= (uint64(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+		case 2:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Events", wireType)
+			}
+			var msglen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowRpcevents
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				msglen |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if msglen < 0 {
+				return ErrInvalidLengthRpcevents
+			}
+			postIndex := iNdEx + msglen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			m.Events = append(m.Events, &exec.Event{})
+			if err := m.Events[len(m.Events)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+				return err
+			}
+			iNdEx = postIndex
+		default:
+			iNdEx = preIndex
+			skippy, err := skipRpcevents(dAtA[iNdEx:])
+			if err != nil {
+				return err
+			}
+			if skippy < 0 {
+				return ErrInvalidLengthRpcevents
+			}
+			if (iNdEx + skippy) > l {
+				return io.ErrUnexpectedEOF
+			}
+			iNdEx += skippy
+		}
+	}
+
+	if iNdEx > l {
+		return io.ErrUnexpectedEOF
+	}
+	return nil
+}
+func (m *GetTxsResponse) Unmarshal(dAtA []byte) error {
+	l := len(dAtA)
+	iNdEx := 0
+	for iNdEx < l {
+		preIndex := iNdEx
+		var wire uint64
+		for shift := uint(0); ; shift += 7 {
+			if shift >= 64 {
+				return ErrIntOverflowRpcevents
+			}
+			if iNdEx >= l {
+				return io.ErrUnexpectedEOF
+			}
+			b := dAtA[iNdEx]
+			iNdEx++
+			wire |= (uint64(b) & 0x7F) << shift
+			if b < 0x80 {
+				break
+			}
+		}
+		fieldNum := int32(wire >> 3)
+		wireType := int(wire & 0x7)
+		if wireType == 4 {
+			return fmt.Errorf("proto: GetTxsResponse: wiretype end group for non-group")
+		}
+		if fieldNum <= 0 {
+			return fmt.Errorf("proto: GetTxsResponse: illegal tag %d (wire type %d)", fieldNum, wire)
+		}
+		switch fieldNum {
+		case 1:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Height", wireType)
+			}
+			m.Height = 0
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowRpcevents
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				m.Height |= (uint64(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+		case 2:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field TxExecutions", wireType)
+			}
+			var msglen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowRpcevents
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				msglen |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if msglen < 0 {
+				return ErrInvalidLengthRpcevents
+			}
+			postIndex := iNdEx + msglen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			m.TxExecutions = append(m.TxExecutions, &exec.TxExecution{})
+			if err := m.TxExecutions[len(m.TxExecutions)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+				return err
+			}
+			iNdEx = postIndex
+		default:
+			iNdEx = preIndex
+			skippy, err := skipRpcevents(dAtA[iNdEx:])
+			if err != nil {
+				return err
+			}
+			if skippy < 0 {
+				return ErrInvalidLengthRpcevents
+			}
+			if (iNdEx + skippy) > l {
+				return io.ErrUnexpectedEOF
+			}
+			iNdEx += skippy
+		}
+	}
+
+	if iNdEx > l {
+		return io.ErrUnexpectedEOF
+	}
+	return nil
+}
+func (m *Bound) Unmarshal(dAtA []byte) error {
+	l := len(dAtA)
+	iNdEx := 0
+	for iNdEx < l {
+		preIndex := iNdEx
+		var wire uint64
+		for shift := uint(0); ; shift += 7 {
+			if shift >= 64 {
+				return ErrIntOverflowRpcevents
+			}
+			if iNdEx >= l {
+				return io.ErrUnexpectedEOF
+			}
+			b := dAtA[iNdEx]
+			iNdEx++
+			wire |= (uint64(b) & 0x7F) << shift
+			if b < 0x80 {
+				break
+			}
+		}
+		fieldNum := int32(wire >> 3)
+		wireType := int(wire & 0x7)
+		if wireType == 4 {
+			return fmt.Errorf("proto: Bound: wiretype end group for non-group")
+		}
+		if fieldNum <= 0 {
+			return fmt.Errorf("proto: Bound: illegal tag %d (wire type %d)", fieldNum, wire)
+		}
+		switch fieldNum {
+		case 1:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Type", wireType)
+			}
+			m.Type = 0
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowRpcevents
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				m.Type |= (Bound_BoundType(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+		case 2:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Index", wireType)
+			}
+			m.Index = 0
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowRpcevents
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				m.Index |= (uint64(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+		default:
+			iNdEx = preIndex
+			skippy, err := skipRpcevents(dAtA[iNdEx:])
+			if err != nil {
+				return err
+			}
+			if skippy < 0 {
+				return ErrInvalidLengthRpcevents
+			}
+			if (iNdEx + skippy) > l {
+				return io.ErrUnexpectedEOF
+			}
+			iNdEx += skippy
+		}
+	}
+
+	if iNdEx > l {
+		return io.ErrUnexpectedEOF
+	}
+	return nil
+}
+func (m *BlockRange) Unmarshal(dAtA []byte) error {
+	l := len(dAtA)
+	iNdEx := 0
+	for iNdEx < l {
+		preIndex := iNdEx
+		var wire uint64
+		for shift := uint(0); ; shift += 7 {
+			if shift >= 64 {
+				return ErrIntOverflowRpcevents
+			}
+			if iNdEx >= l {
+				return io.ErrUnexpectedEOF
+			}
+			b := dAtA[iNdEx]
+			iNdEx++
+			wire |= (uint64(b) & 0x7F) << shift
+			if b < 0x80 {
+				break
+			}
+		}
+		fieldNum := int32(wire >> 3)
+		wireType := int(wire & 0x7)
+		if wireType == 4 {
+			return fmt.Errorf("proto: BlockRange: wiretype end group for non-group")
+		}
+		if fieldNum <= 0 {
+			return fmt.Errorf("proto: BlockRange: illegal tag %d (wire type %d)", fieldNum, wire)
+		}
+		switch fieldNum {
+		case 1:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Start", wireType)
+			}
+			var msglen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowRpcevents
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				msglen |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if msglen < 0 {
+				return ErrInvalidLengthRpcevents
+			}
+			postIndex := iNdEx + msglen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			if m.Start == nil {
+				m.Start = &Bound{}
+			}
+			if err := m.Start.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+				return err
+			}
+			iNdEx = postIndex
+		case 2:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field End", wireType)
+			}
+			var msglen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowRpcevents
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				msglen |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if msglen < 0 {
+				return ErrInvalidLengthRpcevents
+			}
+			postIndex := iNdEx + msglen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			if m.End == nil {
+				m.End = &Bound{}
+			}
+			if err := m.End.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+				return err
+			}
+			iNdEx = postIndex
+		default:
+			iNdEx = preIndex
+			skippy, err := skipRpcevents(dAtA[iNdEx:])
+			if err != nil {
+				return err
+			}
+			if skippy < 0 {
+				return ErrInvalidLengthRpcevents
+			}
+			if (iNdEx + skippy) > l {
+				return io.ErrUnexpectedEOF
+			}
+			iNdEx += skippy
+		}
+	}
+
+	if iNdEx > l {
+		return io.ErrUnexpectedEOF
+	}
+	return nil
+}
+func skipRpcevents(dAtA []byte) (n int, err error) {
+	l := len(dAtA)
+	iNdEx := 0
+	for iNdEx < l {
+		var wire uint64
+		for shift := uint(0); ; shift += 7 {
+			if shift >= 64 {
+				return 0, ErrIntOverflowRpcevents
+			}
+			if iNdEx >= l {
+				return 0, io.ErrUnexpectedEOF
+			}
+			b := dAtA[iNdEx]
+			iNdEx++
+			wire |= (uint64(b) & 0x7F) << shift
+			if b < 0x80 {
+				break
+			}
+		}
+		wireType := int(wire & 0x7)
+		switch wireType {
+		case 0:
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return 0, ErrIntOverflowRpcevents
+				}
+				if iNdEx >= l {
+					return 0, io.ErrUnexpectedEOF
+				}
+				iNdEx++
+				if dAtA[iNdEx-1] < 0x80 {
+					break
+				}
+			}
+			return iNdEx, nil
+		case 1:
+			iNdEx += 8
+			return iNdEx, nil
+		case 2:
+			var length int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return 0, ErrIntOverflowRpcevents
+				}
+				if iNdEx >= l {
+					return 0, io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				length |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			iNdEx += length
+			if length < 0 {
+				return 0, ErrInvalidLengthRpcevents
+			}
+			return iNdEx, nil
+		case 3:
+			for {
+				var innerWire uint64
+				var start int = iNdEx
+				for shift := uint(0); ; shift += 7 {
+					if shift >= 64 {
+						return 0, ErrIntOverflowRpcevents
+					}
+					if iNdEx >= l {
+						return 0, io.ErrUnexpectedEOF
+					}
+					b := dAtA[iNdEx]
+					iNdEx++
+					innerWire |= (uint64(b) & 0x7F) << shift
+					if b < 0x80 {
+						break
+					}
+				}
+				innerWireType := int(innerWire & 0x7)
+				if innerWireType == 4 {
+					break
+				}
+				next, err := skipRpcevents(dAtA[start:])
+				if err != nil {
+					return 0, err
+				}
+				iNdEx = start + next
+			}
+			return iNdEx, nil
+		case 4:
+			return iNdEx, nil
+		case 5:
+			iNdEx += 4
+			return iNdEx, nil
+		default:
+			return 0, fmt.Errorf("proto: illegal wireType %d", wireType)
+		}
+	}
+	panic("unreachable")
+}
+
+var (
+	ErrInvalidLengthRpcevents = fmt.Errorf("proto: negative length found during unmarshaling")
+	ErrIntOverflowRpcevents   = fmt.Errorf("proto: integer overflow")
+)
+
+func init() { proto.RegisterFile("rpcevents.proto", fileDescriptorRpcevents) }
+func init() { golang_proto.RegisterFile("rpcevents.proto", fileDescriptorRpcevents) }
+
+var fileDescriptorRpcevents = []byte{
+	// 584 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x84, 0x54, 0x5f, 0x8f, 0xd2, 0x40,
+	0x10, 0xbf, 0xe5, 0x4f, 0x03, 0x03, 0x1e, 0xbd, 0xcd, 0xa9, 0x48, 0x0c, 0x47, 0x6a, 0x62, 0x48,
+	0x8c, 0x85, 0x70, 0xe1, 0xcd, 0x8b, 0xa1, 0x49, 0x05, 0x0c, 0x17, 0x75, 0xa9, 0x7f, 0x62, 0x4c,
+	0x0c, 0x94, 0xb5, 0x10, 0xcf, 0xb6, 0xd7, 0x6e, 0xb5, 0x7c, 0x14, 0xbf, 0x8d, 0x8f, 0x24, 0xbe,
+	0xf8, 0xec, 0xc3, 0xc5, 0x70, 0x5f, 0xc4, 0x74, 0x17, 0x7a, 0x05, 0xef, 0xf0, 0xa5, 0x99, 0xd9,
+	0xf9, 0xcd, 0x6f, 0x66, 0x7f, 0x33, 0x5b, 0x28, 0x79, 0xae, 0x49, 0xbf, 0x52, 0x9b, 0xf9, 0xaa,
+	0xeb, 0x39, 0xcc, 0xc1, 0xf9, 0xf8, 0xa0, 0xf2, 0xd8, 0x9a, 0xb1, 0x69, 0x30, 0x56, 0x4d, 0xe7,
+	0x4b, 0xc3, 0x72, 0x2c, 0xa7, 0xc1, 0x11, 0xe3, 0xe0, 0x13, 0xf7, 0xb8, 0xc3, 0x2d, 0x91, 0x59,
+	0x01, 0x1a, 0x52, 0x53, 0xd8, 0xca, 0x09, 0x94, 0xba, 0x94, 0x69, 0x67, 0x8e, 0xf9, 0x99, 0xd0,
+	0xf3, 0x80, 0xfa, 0x0c, 0xdf, 0x01, 0xa9, 0x47, 0x67, 0xd6, 0x94, 0x95, 0x51, 0x0d, 0xd5, 0x33,
+	0x64, 0xe5, 0x61, 0x0c, 0x99, 0xb7, 0xa3, 0x19, 0x2b, 0xa7, 0x6a, 0xa8, 0x9e, 0x23, 0xdc, 0x56,
+	0xce, 0xa1, 0xd8, 0xa5, 0xcc, 0x08, 0xd7, 0xb9, 0xa7, 0x20, 0x19, 0x61, 0x6f, 0xe4, 0x4f, 0x79,
+	0x6e, 0x51, 0x6b, 0x2f, 0x2e, 0x8e, 0xf6, 0x7e, 0x5f, 0x1c, 0x25, 0x3b, 0x9c, 0xce, 0x5d, 0xea,
+	0x9d, 0xd1, 0x89, 0x45, 0xbd, 0xc6, 0x38, 0xf0, 0x3c, 0xe7, 0x5b, 0x63, 0x3c, 0xb3, 0x47, 0xde,
+	0x5c, 0xed, 0xd1, 0x50, 0x9b, 0x33, 0xea, 0x93, 0x15, 0xc9, 0xb5, 0x25, 0x3f, 0xc0, 0x2d, 0xde,
+	0xae, 0xbf, 0xae, 0xd9, 0x06, 0x10, 0xfd, 0x8f, 0x6c, 0x8b, 0xf2, 0xba, 0x85, 0xd6, 0x6d, 0xf5,
+	0x4a, 0xae, 0xab, 0x20, 0x49, 0x00, 0xf1, 0x21, 0x64, 0x5f, 0x05, 0xd4, 0x9b, 0x73, 0xf2, 0x3c,
+	0x11, 0x8e, 0xf2, 0x12, 0x0e, 0xba, 0x94, 0xe9, 0x3c, 0x93, 0x50, 0xdf, 0x75, 0x6c, 0x9f, 0xde,
+	0xa8, 0xc8, 0x03, 0x90, 0x04, 0xb2, 0x9c, 0xaa, 0xa5, 0xeb, 0x85, 0x56, 0x41, 0xe5, 0xca, 0xf2,
+	0x33, 0xb2, 0x0a, 0x29, 0x1f, 0x61, 0x9f, 0x4b, 0xf4, 0x7f, 0xba, 0x36, 0x14, 0x8d, 0x50, 0x0f,
+	0xa9, 0x19, 0xb0, 0x99, 0x63, 0xaf, 0x49, 0x0f, 0x04, 0x69, 0x22, 0x42, 0x36, 0x60, 0xca, 0x77,
+	0x04, 0x59, 0xcd, 0x09, 0xec, 0x09, 0x56, 0x21, 0x63, 0xcc, 0x5d, 0xa1, 0xc1, 0x7e, 0xab, 0x92,
+	0xd4, 0x20, 0x8a, 0x8b, 0x6f, 0x84, 0x20, 0x1c, 0x17, 0x49, 0xd0, 0xb7, 0x27, 0x34, 0xe4, 0x12,
+	0x64, 0x88, 0x70, 0x94, 0xe7, 0x90, 0x8f, 0x81, 0xb8, 0x08, 0xb9, 0x8e, 0x36, 0x7c, 0x31, 0x78,
+	0x6d, 0xe8, 0xf2, 0x5e, 0xe4, 0x11, 0x7d, 0xd0, 0x31, 0xfa, 0x6f, 0x74, 0x19, 0xe1, 0x3c, 0x64,
+	0x9f, 0xf5, 0xc9, 0xd0, 0x90, 0x53, 0x18, 0x40, 0x1a, 0x74, 0x0c, 0x7d, 0x68, 0xc8, 0xe9, 0xc8,
+	0x1e, 0x1a, 0x44, 0xef, 0x9c, 0xca, 0x19, 0xe5, 0x5d, 0x72, 0x36, 0xf8, 0x21, 0x64, 0x87, 0x6c,
+	0xe4, 0xb1, 0xd5, 0x90, 0xe4, 0xed, 0x06, 0x89, 0x08, 0x63, 0x05, 0xd2, 0xba, 0x3d, 0xe1, 0x5d,
+	0x5d, 0x87, 0x8a, 0x82, 0xad, 0x9f, 0x29, 0x28, 0xc5, 0x22, 0x08, 0xa9, 0xf1, 0x13, 0xc8, 0xad,
+	0x97, 0x19, 0x27, 0x6f, 0xbf, 0xb5, 0xe1, 0x95, 0x43, 0x21, 0x29, 0x3f, 0x8b, 0x39, 0xf0, 0x09,
+	0xe4, 0xd7, 0x40, 0x1f, 0x97, 0xb7, 0x17, 0xc8, 0xdf, 0x99, 0xdc, 0x44, 0xf8, 0x18, 0xb2, 0x7c,
+	0xce, 0xf8, 0xee, 0x66, 0xe5, 0xf8, 0x71, 0x54, 0xfe, 0x9d, 0x24, 0x7e, 0x0a, 0x92, 0x58, 0x8e,
+	0x1d, 0x05, 0xef, 0x6d, 0xf3, 0xc5, 0x9b, 0xd4, 0x44, 0x58, 0xe7, 0x4d, 0xaf, 0xee, 0x7f, 0x33,
+	0xc7, 0xfd, 0x4d, 0x8e, 0xcd, 0xfd, 0x6e, 0x22, 0xad, 0xb3, 0x58, 0x56, 0xd1, 0xaf, 0x65, 0x15,
+	0xfd, 0x59, 0x56, 0xd1, 0x8f, 0xcb, 0x2a, 0x5a, 0x5c, 0x56, 0xd1, 0xfb, 0x47, 0xbb, 0x5f, 0xad,
+	0xe7, 0x9a, 0x8d, 0x98, 0x76, 0x2c, 0xf1, 0x1f, 0xca, 0xf1, 0xdf, 0x00, 0x00, 0x00, 0xff, 0xff,
+	0x5d, 0x9d, 0x65, 0x82, 0xa9, 0x04, 0x00, 0x00,
+}
diff --git a/rpc/rpcquery/query_server.go b/rpc/rpcquery/query_server.go
new file mode 100644
index 0000000000000000000000000000000000000000..edcb968b6b1810329395acfb90bb5d1d8b11c97e
--- /dev/null
+++ b/rpc/rpcquery/query_server.go
@@ -0,0 +1,76 @@
+package rpcquery
+
+import (
+	"context"
+
+	"github.com/hyperledger/burrow/acm"
+	"github.com/hyperledger/burrow/acm/state"
+	"github.com/hyperledger/burrow/event/query"
+	"github.com/hyperledger/burrow/execution/names"
+)
+
+type queryServer struct {
+	accounts state.IterableReader
+	nameReg  names.IterableReader
+}
+
+var _ QueryServer = &queryServer{}
+
+func NewQueryServer(state state.IterableReader, nameReg names.IterableReader) *queryServer {
+	return &queryServer{
+		accounts: state,
+		nameReg:  nameReg,
+	}
+}
+
+func (qs *queryServer) GetAccount(ctx context.Context, param *GetAccountParam) (*acm.ConcreteAccount, error) {
+	acc, err := qs.accounts.GetAccount(param.Address)
+	if err != nil {
+		return nil, err
+	}
+	return acm.AsConcreteAccount(acc), nil
+}
+
+func (qs *queryServer) ListAccounts(param *ListAccountsParam, stream Query_ListAccountsServer) error {
+	qry, err := query.NewBuilder(param.Query).Query()
+	var streamErr error
+	_, err = qs.accounts.IterateAccounts(func(acc acm.Account) (stop bool) {
+		if qry.Matches(acc.Tagged()) {
+			streamErr = stream.Send(acm.AsConcreteAccount(acc))
+			if streamErr != nil {
+				return true
+			}
+		}
+		return
+	})
+	if err != nil {
+		return err
+	}
+	return streamErr
+}
+
+// Name registry
+func (qs *queryServer) GetName(ctx context.Context, param *GetNameParam) (*names.Entry, error) {
+	return qs.nameReg.GetName(param.Name)
+}
+
+func (qs *queryServer) ListNames(param *ListNamesParam, stream Query_ListNamesServer) error {
+	qry, err := query.NewBuilder(param.Query).Query()
+	if err != nil {
+		return err
+	}
+	var streamErr error
+	_, err = qs.nameReg.IterateNames(func(entry *names.Entry) (stop bool) {
+		if qry.Matches(entry.Tagged()) {
+			streamErr = stream.Send(entry)
+			if streamErr != nil {
+				return true
+			}
+		}
+		return
+	})
+	if err != nil {
+		return err
+	}
+	return streamErr
+}
diff --git a/rpc/rpcquery/rpcquery.pb.go b/rpc/rpcquery/rpcquery.pb.go
new file mode 100644
index 0000000000000000000000000000000000000000..ce9b9f17d5a7fc89e4b3eb2efbe19c953b6dc72a
--- /dev/null
+++ b/rpc/rpcquery/rpcquery.pb.go
@@ -0,0 +1,961 @@
+// Code generated by protoc-gen-gogo. DO NOT EDIT.
+// source: rpcquery.proto
+
+/*
+	Package rpcquery is a generated protocol buffer package.
+
+	It is generated from these files:
+		rpcquery.proto
+
+	It has these top-level messages:
+		GetAccountParam
+		ListAccountsParam
+		GetNameParam
+		ListNamesParam
+*/
+package rpcquery
+
+import proto "github.com/gogo/protobuf/proto"
+import golang_proto "github.com/golang/protobuf/proto"
+import fmt "fmt"
+import math "math"
+import _ "github.com/gogo/protobuf/gogoproto"
+import names "github.com/hyperledger/burrow/execution/names"
+import acm "github.com/hyperledger/burrow/acm"
+
+import github_com_hyperledger_burrow_crypto "github.com/hyperledger/burrow/crypto"
+
+import context "golang.org/x/net/context"
+import grpc "google.golang.org/grpc"
+
+import io "io"
+
+// Reference imports to suppress errors if they are not otherwise used.
+var _ = proto.Marshal
+var _ = golang_proto.Marshal
+var _ = fmt.Errorf
+var _ = math.Inf
+
+// This is a compile-time assertion to ensure that this generated file
+// is compatible with the proto package it is being compiled against.
+// A compilation error at this line likely means your copy of the
+// proto package needs to be updated.
+const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package
+
+type GetAccountParam struct {
+	Address github_com_hyperledger_burrow_crypto.Address `protobuf:"bytes,1,opt,name=Address,proto3,customtype=github.com/hyperledger/burrow/crypto.Address" json:"Address"`
+}
+
+func (m *GetAccountParam) Reset()                    { *m = GetAccountParam{} }
+func (m *GetAccountParam) String() string            { return proto.CompactTextString(m) }
+func (*GetAccountParam) ProtoMessage()               {}
+func (*GetAccountParam) Descriptor() ([]byte, []int) { return fileDescriptorRpcquery, []int{0} }
+
+func (*GetAccountParam) XXX_MessageName() string {
+	return "rpcquery.GetAccountParam"
+}
+
+type ListAccountsParam struct {
+	Query string `protobuf:"bytes,1,opt,name=Query,proto3" json:"Query,omitempty"`
+}
+
+func (m *ListAccountsParam) Reset()                    { *m = ListAccountsParam{} }
+func (m *ListAccountsParam) String() string            { return proto.CompactTextString(m) }
+func (*ListAccountsParam) ProtoMessage()               {}
+func (*ListAccountsParam) Descriptor() ([]byte, []int) { return fileDescriptorRpcquery, []int{1} }
+
+func (m *ListAccountsParam) GetQuery() string {
+	if m != nil {
+		return m.Query
+	}
+	return ""
+}
+
+func (*ListAccountsParam) XXX_MessageName() string {
+	return "rpcquery.ListAccountsParam"
+}
+
+type GetNameParam struct {
+	Name string `protobuf:"bytes,1,opt,name=Name,proto3" json:"Name,omitempty"`
+}
+
+func (m *GetNameParam) Reset()                    { *m = GetNameParam{} }
+func (m *GetNameParam) String() string            { return proto.CompactTextString(m) }
+func (*GetNameParam) ProtoMessage()               {}
+func (*GetNameParam) Descriptor() ([]byte, []int) { return fileDescriptorRpcquery, []int{2} }
+
+func (m *GetNameParam) GetName() string {
+	if m != nil {
+		return m.Name
+	}
+	return ""
+}
+
+func (*GetNameParam) XXX_MessageName() string {
+	return "rpcquery.GetNameParam"
+}
+
+type ListNamesParam struct {
+	Query string `protobuf:"bytes,1,opt,name=Query,proto3" json:"Query,omitempty"`
+}
+
+func (m *ListNamesParam) Reset()                    { *m = ListNamesParam{} }
+func (m *ListNamesParam) String() string            { return proto.CompactTextString(m) }
+func (*ListNamesParam) ProtoMessage()               {}
+func (*ListNamesParam) Descriptor() ([]byte, []int) { return fileDescriptorRpcquery, []int{3} }
+
+func (m *ListNamesParam) GetQuery() string {
+	if m != nil {
+		return m.Query
+	}
+	return ""
+}
+
+func (*ListNamesParam) XXX_MessageName() string {
+	return "rpcquery.ListNamesParam"
+}
+func init() {
+	proto.RegisterType((*GetAccountParam)(nil), "rpcquery.GetAccountParam")
+	golang_proto.RegisterType((*GetAccountParam)(nil), "rpcquery.GetAccountParam")
+	proto.RegisterType((*ListAccountsParam)(nil), "rpcquery.ListAccountsParam")
+	golang_proto.RegisterType((*ListAccountsParam)(nil), "rpcquery.ListAccountsParam")
+	proto.RegisterType((*GetNameParam)(nil), "rpcquery.GetNameParam")
+	golang_proto.RegisterType((*GetNameParam)(nil), "rpcquery.GetNameParam")
+	proto.RegisterType((*ListNamesParam)(nil), "rpcquery.ListNamesParam")
+	golang_proto.RegisterType((*ListNamesParam)(nil), "rpcquery.ListNamesParam")
+}
+
+// Reference imports to suppress errors if they are not otherwise used.
+var _ context.Context
+var _ grpc.ClientConn
+
+// This is a compile-time assertion to ensure that this generated file
+// is compatible with the grpc package it is being compiled against.
+const _ = grpc.SupportPackageIsVersion4
+
+// Client API for Query service
+
+type QueryClient interface {
+	GetAccount(ctx context.Context, in *GetAccountParam, opts ...grpc.CallOption) (*acm.ConcreteAccount, error)
+	ListAccounts(ctx context.Context, in *ListAccountsParam, opts ...grpc.CallOption) (Query_ListAccountsClient, error)
+	GetName(ctx context.Context, in *GetNameParam, opts ...grpc.CallOption) (*names.Entry, error)
+	ListNames(ctx context.Context, in *ListNamesParam, opts ...grpc.CallOption) (Query_ListNamesClient, error)
+}
+
+type queryClient struct {
+	cc *grpc.ClientConn
+}
+
+func NewQueryClient(cc *grpc.ClientConn) QueryClient {
+	return &queryClient{cc}
+}
+
+func (c *queryClient) GetAccount(ctx context.Context, in *GetAccountParam, opts ...grpc.CallOption) (*acm.ConcreteAccount, error) {
+	out := new(acm.ConcreteAccount)
+	err := grpc.Invoke(ctx, "/rpcquery.Query/GetAccount", in, out, c.cc, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *queryClient) ListAccounts(ctx context.Context, in *ListAccountsParam, opts ...grpc.CallOption) (Query_ListAccountsClient, error) {
+	stream, err := grpc.NewClientStream(ctx, &_Query_serviceDesc.Streams[0], c.cc, "/rpcquery.Query/ListAccounts", opts...)
+	if err != nil {
+		return nil, err
+	}
+	x := &queryListAccountsClient{stream}
+	if err := x.ClientStream.SendMsg(in); err != nil {
+		return nil, err
+	}
+	if err := x.ClientStream.CloseSend(); err != nil {
+		return nil, err
+	}
+	return x, nil
+}
+
+type Query_ListAccountsClient interface {
+	Recv() (*acm.ConcreteAccount, error)
+	grpc.ClientStream
+}
+
+type queryListAccountsClient struct {
+	grpc.ClientStream
+}
+
+func (x *queryListAccountsClient) Recv() (*acm.ConcreteAccount, error) {
+	m := new(acm.ConcreteAccount)
+	if err := x.ClientStream.RecvMsg(m); err != nil {
+		return nil, err
+	}
+	return m, nil
+}
+
+func (c *queryClient) GetName(ctx context.Context, in *GetNameParam, opts ...grpc.CallOption) (*names.Entry, error) {
+	out := new(names.Entry)
+	err := grpc.Invoke(ctx, "/rpcquery.Query/GetName", in, out, c.cc, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *queryClient) ListNames(ctx context.Context, in *ListNamesParam, opts ...grpc.CallOption) (Query_ListNamesClient, error) {
+	stream, err := grpc.NewClientStream(ctx, &_Query_serviceDesc.Streams[1], c.cc, "/rpcquery.Query/ListNames", opts...)
+	if err != nil {
+		return nil, err
+	}
+	x := &queryListNamesClient{stream}
+	if err := x.ClientStream.SendMsg(in); err != nil {
+		return nil, err
+	}
+	if err := x.ClientStream.CloseSend(); err != nil {
+		return nil, err
+	}
+	return x, nil
+}
+
+type Query_ListNamesClient interface {
+	Recv() (*names.Entry, error)
+	grpc.ClientStream
+}
+
+type queryListNamesClient struct {
+	grpc.ClientStream
+}
+
+func (x *queryListNamesClient) Recv() (*names.Entry, error) {
+	m := new(names.Entry)
+	if err := x.ClientStream.RecvMsg(m); err != nil {
+		return nil, err
+	}
+	return m, nil
+}
+
+// Server API for Query service
+
+type QueryServer interface {
+	GetAccount(context.Context, *GetAccountParam) (*acm.ConcreteAccount, error)
+	ListAccounts(*ListAccountsParam, Query_ListAccountsServer) error
+	GetName(context.Context, *GetNameParam) (*names.Entry, error)
+	ListNames(*ListNamesParam, Query_ListNamesServer) error
+}
+
+func RegisterQueryServer(s *grpc.Server, srv QueryServer) {
+	s.RegisterService(&_Query_serviceDesc, srv)
+}
+
+func _Query_GetAccount_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(GetAccountParam)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(QueryServer).GetAccount(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/rpcquery.Query/GetAccount",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(QueryServer).GetAccount(ctx, req.(*GetAccountParam))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _Query_ListAccounts_Handler(srv interface{}, stream grpc.ServerStream) error {
+	m := new(ListAccountsParam)
+	if err := stream.RecvMsg(m); err != nil {
+		return err
+	}
+	return srv.(QueryServer).ListAccounts(m, &queryListAccountsServer{stream})
+}
+
+type Query_ListAccountsServer interface {
+	Send(*acm.ConcreteAccount) error
+	grpc.ServerStream
+}
+
+type queryListAccountsServer struct {
+	grpc.ServerStream
+}
+
+func (x *queryListAccountsServer) Send(m *acm.ConcreteAccount) error {
+	return x.ServerStream.SendMsg(m)
+}
+
+func _Query_GetName_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(GetNameParam)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(QueryServer).GetName(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/rpcquery.Query/GetName",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(QueryServer).GetName(ctx, req.(*GetNameParam))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _Query_ListNames_Handler(srv interface{}, stream grpc.ServerStream) error {
+	m := new(ListNamesParam)
+	if err := stream.RecvMsg(m); err != nil {
+		return err
+	}
+	return srv.(QueryServer).ListNames(m, &queryListNamesServer{stream})
+}
+
+type Query_ListNamesServer interface {
+	Send(*names.Entry) error
+	grpc.ServerStream
+}
+
+type queryListNamesServer struct {
+	grpc.ServerStream
+}
+
+func (x *queryListNamesServer) Send(m *names.Entry) error {
+	return x.ServerStream.SendMsg(m)
+}
+
+var _Query_serviceDesc = grpc.ServiceDesc{
+	ServiceName: "rpcquery.Query",
+	HandlerType: (*QueryServer)(nil),
+	Methods: []grpc.MethodDesc{
+		{
+			MethodName: "GetAccount",
+			Handler:    _Query_GetAccount_Handler,
+		},
+		{
+			MethodName: "GetName",
+			Handler:    _Query_GetName_Handler,
+		},
+	},
+	Streams: []grpc.StreamDesc{
+		{
+			StreamName:    "ListAccounts",
+			Handler:       _Query_ListAccounts_Handler,
+			ServerStreams: true,
+		},
+		{
+			StreamName:    "ListNames",
+			Handler:       _Query_ListNames_Handler,
+			ServerStreams: true,
+		},
+	},
+	Metadata: "rpcquery.proto",
+}
+
+func (m *GetAccountParam) Marshal() (dAtA []byte, err error) {
+	size := m.Size()
+	dAtA = make([]byte, size)
+	n, err := m.MarshalTo(dAtA)
+	if err != nil {
+		return nil, err
+	}
+	return dAtA[:n], nil
+}
+
+func (m *GetAccountParam) MarshalTo(dAtA []byte) (int, error) {
+	var i int
+	_ = i
+	var l int
+	_ = l
+	dAtA[i] = 0xa
+	i++
+	i = encodeVarintRpcquery(dAtA, i, uint64(m.Address.Size()))
+	n1, err := m.Address.MarshalTo(dAtA[i:])
+	if err != nil {
+		return 0, err
+	}
+	i += n1
+	return i, nil
+}
+
+func (m *ListAccountsParam) Marshal() (dAtA []byte, err error) {
+	size := m.Size()
+	dAtA = make([]byte, size)
+	n, err := m.MarshalTo(dAtA)
+	if err != nil {
+		return nil, err
+	}
+	return dAtA[:n], nil
+}
+
+func (m *ListAccountsParam) MarshalTo(dAtA []byte) (int, error) {
+	var i int
+	_ = i
+	var l int
+	_ = l
+	if len(m.Query) > 0 {
+		dAtA[i] = 0xa
+		i++
+		i = encodeVarintRpcquery(dAtA, i, uint64(len(m.Query)))
+		i += copy(dAtA[i:], m.Query)
+	}
+	return i, nil
+}
+
+func (m *GetNameParam) Marshal() (dAtA []byte, err error) {
+	size := m.Size()
+	dAtA = make([]byte, size)
+	n, err := m.MarshalTo(dAtA)
+	if err != nil {
+		return nil, err
+	}
+	return dAtA[:n], nil
+}
+
+func (m *GetNameParam) MarshalTo(dAtA []byte) (int, error) {
+	var i int
+	_ = i
+	var l int
+	_ = l
+	if len(m.Name) > 0 {
+		dAtA[i] = 0xa
+		i++
+		i = encodeVarintRpcquery(dAtA, i, uint64(len(m.Name)))
+		i += copy(dAtA[i:], m.Name)
+	}
+	return i, nil
+}
+
+func (m *ListNamesParam) Marshal() (dAtA []byte, err error) {
+	size := m.Size()
+	dAtA = make([]byte, size)
+	n, err := m.MarshalTo(dAtA)
+	if err != nil {
+		return nil, err
+	}
+	return dAtA[:n], nil
+}
+
+func (m *ListNamesParam) MarshalTo(dAtA []byte) (int, error) {
+	var i int
+	_ = i
+	var l int
+	_ = l
+	if len(m.Query) > 0 {
+		dAtA[i] = 0xa
+		i++
+		i = encodeVarintRpcquery(dAtA, i, uint64(len(m.Query)))
+		i += copy(dAtA[i:], m.Query)
+	}
+	return i, nil
+}
+
+func encodeVarintRpcquery(dAtA []byte, offset int, v uint64) int {
+	for v >= 1<<7 {
+		dAtA[offset] = uint8(v&0x7f | 0x80)
+		v >>= 7
+		offset++
+	}
+	dAtA[offset] = uint8(v)
+	return offset + 1
+}
+func (m *GetAccountParam) Size() (n int) {
+	var l int
+	_ = l
+	l = m.Address.Size()
+	n += 1 + l + sovRpcquery(uint64(l))
+	return n
+}
+
+func (m *ListAccountsParam) Size() (n int) {
+	var l int
+	_ = l
+	l = len(m.Query)
+	if l > 0 {
+		n += 1 + l + sovRpcquery(uint64(l))
+	}
+	return n
+}
+
+func (m *GetNameParam) Size() (n int) {
+	var l int
+	_ = l
+	l = len(m.Name)
+	if l > 0 {
+		n += 1 + l + sovRpcquery(uint64(l))
+	}
+	return n
+}
+
+func (m *ListNamesParam) Size() (n int) {
+	var l int
+	_ = l
+	l = len(m.Query)
+	if l > 0 {
+		n += 1 + l + sovRpcquery(uint64(l))
+	}
+	return n
+}
+
+func sovRpcquery(x uint64) (n int) {
+	for {
+		n++
+		x >>= 7
+		if x == 0 {
+			break
+		}
+	}
+	return n
+}
+func sozRpcquery(x uint64) (n int) {
+	return sovRpcquery(uint64((x << 1) ^ uint64((int64(x) >> 63))))
+}
+func (m *GetAccountParam) Unmarshal(dAtA []byte) error {
+	l := len(dAtA)
+	iNdEx := 0
+	for iNdEx < l {
+		preIndex := iNdEx
+		var wire uint64
+		for shift := uint(0); ; shift += 7 {
+			if shift >= 64 {
+				return ErrIntOverflowRpcquery
+			}
+			if iNdEx >= l {
+				return io.ErrUnexpectedEOF
+			}
+			b := dAtA[iNdEx]
+			iNdEx++
+			wire |= (uint64(b) & 0x7F) << shift
+			if b < 0x80 {
+				break
+			}
+		}
+		fieldNum := int32(wire >> 3)
+		wireType := int(wire & 0x7)
+		if wireType == 4 {
+			return fmt.Errorf("proto: GetAccountParam: wiretype end group for non-group")
+		}
+		if fieldNum <= 0 {
+			return fmt.Errorf("proto: GetAccountParam: illegal tag %d (wire type %d)", fieldNum, wire)
+		}
+		switch fieldNum {
+		case 1:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Address", wireType)
+			}
+			var byteLen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowRpcquery
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				byteLen |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if byteLen < 0 {
+				return ErrInvalidLengthRpcquery
+			}
+			postIndex := iNdEx + byteLen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			if err := m.Address.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+				return err
+			}
+			iNdEx = postIndex
+		default:
+			iNdEx = preIndex
+			skippy, err := skipRpcquery(dAtA[iNdEx:])
+			if err != nil {
+				return err
+			}
+			if skippy < 0 {
+				return ErrInvalidLengthRpcquery
+			}
+			if (iNdEx + skippy) > l {
+				return io.ErrUnexpectedEOF
+			}
+			iNdEx += skippy
+		}
+	}
+
+	if iNdEx > l {
+		return io.ErrUnexpectedEOF
+	}
+	return nil
+}
+func (m *ListAccountsParam) Unmarshal(dAtA []byte) error {
+	l := len(dAtA)
+	iNdEx := 0
+	for iNdEx < l {
+		preIndex := iNdEx
+		var wire uint64
+		for shift := uint(0); ; shift += 7 {
+			if shift >= 64 {
+				return ErrIntOverflowRpcquery
+			}
+			if iNdEx >= l {
+				return io.ErrUnexpectedEOF
+			}
+			b := dAtA[iNdEx]
+			iNdEx++
+			wire |= (uint64(b) & 0x7F) << shift
+			if b < 0x80 {
+				break
+			}
+		}
+		fieldNum := int32(wire >> 3)
+		wireType := int(wire & 0x7)
+		if wireType == 4 {
+			return fmt.Errorf("proto: ListAccountsParam: wiretype end group for non-group")
+		}
+		if fieldNum <= 0 {
+			return fmt.Errorf("proto: ListAccountsParam: illegal tag %d (wire type %d)", fieldNum, wire)
+		}
+		switch fieldNum {
+		case 1:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Query", wireType)
+			}
+			var stringLen uint64
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowRpcquery
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				stringLen |= (uint64(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			intStringLen := int(stringLen)
+			if intStringLen < 0 {
+				return ErrInvalidLengthRpcquery
+			}
+			postIndex := iNdEx + intStringLen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			m.Query = string(dAtA[iNdEx:postIndex])
+			iNdEx = postIndex
+		default:
+			iNdEx = preIndex
+			skippy, err := skipRpcquery(dAtA[iNdEx:])
+			if err != nil {
+				return err
+			}
+			if skippy < 0 {
+				return ErrInvalidLengthRpcquery
+			}
+			if (iNdEx + skippy) > l {
+				return io.ErrUnexpectedEOF
+			}
+			iNdEx += skippy
+		}
+	}
+
+	if iNdEx > l {
+		return io.ErrUnexpectedEOF
+	}
+	return nil
+}
+func (m *GetNameParam) Unmarshal(dAtA []byte) error {
+	l := len(dAtA)
+	iNdEx := 0
+	for iNdEx < l {
+		preIndex := iNdEx
+		var wire uint64
+		for shift := uint(0); ; shift += 7 {
+			if shift >= 64 {
+				return ErrIntOverflowRpcquery
+			}
+			if iNdEx >= l {
+				return io.ErrUnexpectedEOF
+			}
+			b := dAtA[iNdEx]
+			iNdEx++
+			wire |= (uint64(b) & 0x7F) << shift
+			if b < 0x80 {
+				break
+			}
+		}
+		fieldNum := int32(wire >> 3)
+		wireType := int(wire & 0x7)
+		if wireType == 4 {
+			return fmt.Errorf("proto: GetNameParam: wiretype end group for non-group")
+		}
+		if fieldNum <= 0 {
+			return fmt.Errorf("proto: GetNameParam: illegal tag %d (wire type %d)", fieldNum, wire)
+		}
+		switch fieldNum {
+		case 1:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType)
+			}
+			var stringLen uint64
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowRpcquery
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				stringLen |= (uint64(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			intStringLen := int(stringLen)
+			if intStringLen < 0 {
+				return ErrInvalidLengthRpcquery
+			}
+			postIndex := iNdEx + intStringLen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			m.Name = string(dAtA[iNdEx:postIndex])
+			iNdEx = postIndex
+		default:
+			iNdEx = preIndex
+			skippy, err := skipRpcquery(dAtA[iNdEx:])
+			if err != nil {
+				return err
+			}
+			if skippy < 0 {
+				return ErrInvalidLengthRpcquery
+			}
+			if (iNdEx + skippy) > l {
+				return io.ErrUnexpectedEOF
+			}
+			iNdEx += skippy
+		}
+	}
+
+	if iNdEx > l {
+		return io.ErrUnexpectedEOF
+	}
+	return nil
+}
+func (m *ListNamesParam) Unmarshal(dAtA []byte) error {
+	l := len(dAtA)
+	iNdEx := 0
+	for iNdEx < l {
+		preIndex := iNdEx
+		var wire uint64
+		for shift := uint(0); ; shift += 7 {
+			if shift >= 64 {
+				return ErrIntOverflowRpcquery
+			}
+			if iNdEx >= l {
+				return io.ErrUnexpectedEOF
+			}
+			b := dAtA[iNdEx]
+			iNdEx++
+			wire |= (uint64(b) & 0x7F) << shift
+			if b < 0x80 {
+				break
+			}
+		}
+		fieldNum := int32(wire >> 3)
+		wireType := int(wire & 0x7)
+		if wireType == 4 {
+			return fmt.Errorf("proto: ListNamesParam: wiretype end group for non-group")
+		}
+		if fieldNum <= 0 {
+			return fmt.Errorf("proto: ListNamesParam: illegal tag %d (wire type %d)", fieldNum, wire)
+		}
+		switch fieldNum {
+		case 1:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Query", wireType)
+			}
+			var stringLen uint64
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowRpcquery
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				stringLen |= (uint64(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			intStringLen := int(stringLen)
+			if intStringLen < 0 {
+				return ErrInvalidLengthRpcquery
+			}
+			postIndex := iNdEx + intStringLen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			m.Query = string(dAtA[iNdEx:postIndex])
+			iNdEx = postIndex
+		default:
+			iNdEx = preIndex
+			skippy, err := skipRpcquery(dAtA[iNdEx:])
+			if err != nil {
+				return err
+			}
+			if skippy < 0 {
+				return ErrInvalidLengthRpcquery
+			}
+			if (iNdEx + skippy) > l {
+				return io.ErrUnexpectedEOF
+			}
+			iNdEx += skippy
+		}
+	}
+
+	if iNdEx > l {
+		return io.ErrUnexpectedEOF
+	}
+	return nil
+}
+func skipRpcquery(dAtA []byte) (n int, err error) {
+	l := len(dAtA)
+	iNdEx := 0
+	for iNdEx < l {
+		var wire uint64
+		for shift := uint(0); ; shift += 7 {
+			if shift >= 64 {
+				return 0, ErrIntOverflowRpcquery
+			}
+			if iNdEx >= l {
+				return 0, io.ErrUnexpectedEOF
+			}
+			b := dAtA[iNdEx]
+			iNdEx++
+			wire |= (uint64(b) & 0x7F) << shift
+			if b < 0x80 {
+				break
+			}
+		}
+		wireType := int(wire & 0x7)
+		switch wireType {
+		case 0:
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return 0, ErrIntOverflowRpcquery
+				}
+				if iNdEx >= l {
+					return 0, io.ErrUnexpectedEOF
+				}
+				iNdEx++
+				if dAtA[iNdEx-1] < 0x80 {
+					break
+				}
+			}
+			return iNdEx, nil
+		case 1:
+			iNdEx += 8
+			return iNdEx, nil
+		case 2:
+			var length int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return 0, ErrIntOverflowRpcquery
+				}
+				if iNdEx >= l {
+					return 0, io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				length |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			iNdEx += length
+			if length < 0 {
+				return 0, ErrInvalidLengthRpcquery
+			}
+			return iNdEx, nil
+		case 3:
+			for {
+				var innerWire uint64
+				var start int = iNdEx
+				for shift := uint(0); ; shift += 7 {
+					if shift >= 64 {
+						return 0, ErrIntOverflowRpcquery
+					}
+					if iNdEx >= l {
+						return 0, io.ErrUnexpectedEOF
+					}
+					b := dAtA[iNdEx]
+					iNdEx++
+					innerWire |= (uint64(b) & 0x7F) << shift
+					if b < 0x80 {
+						break
+					}
+				}
+				innerWireType := int(innerWire & 0x7)
+				if innerWireType == 4 {
+					break
+				}
+				next, err := skipRpcquery(dAtA[start:])
+				if err != nil {
+					return 0, err
+				}
+				iNdEx = start + next
+			}
+			return iNdEx, nil
+		case 4:
+			return iNdEx, nil
+		case 5:
+			iNdEx += 4
+			return iNdEx, nil
+		default:
+			return 0, fmt.Errorf("proto: illegal wireType %d", wireType)
+		}
+	}
+	panic("unreachable")
+}
+
+var (
+	ErrInvalidLengthRpcquery = fmt.Errorf("proto: negative length found during unmarshaling")
+	ErrIntOverflowRpcquery   = fmt.Errorf("proto: integer overflow")
+)
+
+func init() { proto.RegisterFile("rpcquery.proto", fileDescriptorRpcquery) }
+func init() { golang_proto.RegisterFile("rpcquery.proto", fileDescriptorRpcquery) }
+
+var fileDescriptorRpcquery = []byte{
+	// 349 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x7c, 0x92, 0xcd, 0x4a, 0xc3, 0x40,
+	0x14, 0x85, 0x1d, 0x50, 0x6b, 0xaf, 0xa1, 0xe2, 0x50, 0xa4, 0x46, 0x48, 0x25, 0x0b, 0x51, 0xd1,
+	0xa4, 0xf8, 0xb3, 0x14, 0x6c, 0x8b, 0x74, 0x23, 0x45, 0xbb, 0x74, 0x97, 0x4c, 0xc7, 0xb4, 0x60,
+	0x32, 0xf1, 0x66, 0x82, 0xe4, 0xed, 0x5c, 0x76, 0xe9, 0xda, 0x45, 0x91, 0xf6, 0x11, 0x7c, 0x01,
+	0xc9, 0x24, 0xe9, 0x8f, 0x4a, 0x77, 0xf7, 0x84, 0x7b, 0xce, 0x99, 0x6f, 0x26, 0x50, 0xc1, 0x90,
+	0xbd, 0xc6, 0x1c, 0x13, 0x2b, 0x44, 0x21, 0x05, 0xdd, 0x2a, 0xb4, 0x7e, 0xee, 0x0d, 0xe5, 0x20,
+	0x76, 0x2d, 0x26, 0x7c, 0xdb, 0x13, 0x9e, 0xb0, 0xd5, 0x82, 0x1b, 0x3f, 0x2b, 0xa5, 0x84, 0x9a,
+	0x32, 0xa3, 0xbe, 0x1d, 0x38, 0x3e, 0x8f, 0x72, 0x51, 0x76, 0x98, 0x9f, 0x8d, 0xa6, 0x03, 0x3b,
+	0x1d, 0x2e, 0x9b, 0x8c, 0x89, 0x38, 0x90, 0x0f, 0x0e, 0x3a, 0x3e, 0xed, 0x42, 0xa9, 0xd9, 0xef,
+	0x23, 0x8f, 0xa2, 0x1a, 0x39, 0x24, 0xc7, 0x5a, 0xeb, 0x6a, 0x34, 0xae, 0xaf, 0x7d, 0x8e, 0xeb,
+	0x67, 0x0b, 0x95, 0x83, 0x24, 0xe4, 0xf8, 0xc2, 0xfb, 0x1e, 0x47, 0xdb, 0x8d, 0x11, 0xc5, 0x9b,
+	0xcd, 0x30, 0x09, 0xa5, 0xb0, 0x72, 0x6f, 0xaf, 0x08, 0x31, 0x4f, 0x60, 0xf7, 0x7e, 0x18, 0x15,
+	0x1d, 0x51, 0x56, 0x52, 0x85, 0x8d, 0xc7, 0x94, 0x43, 0x55, 0x94, 0x7b, 0x99, 0x30, 0x4d, 0xd0,
+	0x3a, 0x5c, 0x76, 0x1d, 0x9f, 0x67, 0x5b, 0x14, 0xd6, 0x53, 0x91, 0x2f, 0xa9, 0xd9, 0x3c, 0x82,
+	0x4a, 0x1a, 0x97, 0xce, 0xab, 0xb2, 0x2e, 0xbe, 0x49, 0xfe, 0x99, 0xde, 0x00, 0xcc, 0x19, 0xe9,
+	0xbe, 0x35, 0xbb, 0xd3, 0x5f, 0xe4, 0x7a, 0xd5, 0x4a, 0x2f, 0xa6, 0x2d, 0x02, 0x86, 0x5c, 0xf2,
+	0xc2, 0xd0, 0x06, 0x6d, 0xf1, 0xfc, 0xf4, 0x60, 0x1e, 0xf0, 0x87, 0xeb, 0xff, 0x88, 0x06, 0xa1,
+	0x36, 0x94, 0x72, 0x32, 0xba, 0xb7, 0x74, 0x80, 0x19, 0xac, 0xae, 0x59, 0xd9, 0x1b, 0xdd, 0x05,
+	0x12, 0x13, 0x7a, 0x0d, 0xe5, 0x19, 0x26, 0xad, 0x2d, 0x57, 0xce, 0xd9, 0x97, 0x4d, 0x0d, 0xd2,
+	0xba, 0x1d, 0x4d, 0x0c, 0xf2, 0x31, 0x31, 0xc8, 0xd7, 0xc4, 0x20, 0xef, 0x53, 0x83, 0x8c, 0xa6,
+	0x06, 0x79, 0x3a, 0x5d, 0xfd, 0x72, 0x18, 0x32, 0xbb, 0x28, 0x70, 0x37, 0xd5, 0x8f, 0x71, 0xf9,
+	0x13, 0x00, 0x00, 0xff, 0xff, 0xfa, 0xef, 0x21, 0x21, 0x7b, 0x02, 0x00, 0x00,
+}
diff --git a/rpc/rpctransact/rpctransact.pb.go b/rpc/rpctransact/rpctransact.pb.go
new file mode 100644
index 0000000000000000000000000000000000000000..903e977b455a69b1ca70085ad713b1995aac5134
--- /dev/null
+++ b/rpc/rpctransact/rpctransact.pb.go
@@ -0,0 +1,1488 @@
+// Code generated by protoc-gen-gogo. DO NOT EDIT.
+// source: rpctransact.proto
+
+/*
+	Package rpctransact is a generated protocol buffer package.
+
+	It is generated from these files:
+		rpctransact.proto
+
+	It has these top-level messages:
+		CallCodeParam
+		PayloadParam
+		TxEnvelope
+		TxEnvelopeParam
+*/
+package rpctransact
+
+import proto "github.com/gogo/protobuf/proto"
+import golang_proto "github.com/golang/protobuf/proto"
+import fmt "fmt"
+import math "math"
+import _ "github.com/gogo/protobuf/gogoproto"
+import exec "github.com/hyperledger/burrow/execution/exec"
+import payload "github.com/hyperledger/burrow/txs/payload"
+import txs "github.com/hyperledger/burrow/txs"
+
+import github_com_hyperledger_burrow_crypto "github.com/hyperledger/burrow/crypto"
+import github_com_hyperledger_burrow_txs "github.com/hyperledger/burrow/txs"
+
+import context "golang.org/x/net/context"
+import grpc "google.golang.org/grpc"
+
+import io "io"
+
+// Reference imports to suppress errors if they are not otherwise used.
+var _ = proto.Marshal
+var _ = golang_proto.Marshal
+var _ = fmt.Errorf
+var _ = math.Inf
+
+// This is a compile-time assertion to ensure that this generated file
+// is compatible with the proto package it is being compiled against.
+// A compilation error at this line likely means your copy of the
+// proto package needs to be updated.
+const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package
+
+type CallCodeParam struct {
+	FromAddress github_com_hyperledger_burrow_crypto.Address `protobuf:"bytes,1,opt,name=FromAddress,proto3,customtype=github.com/hyperledger/burrow/crypto.Address" json:"FromAddress"`
+	Code        []byte                                       `protobuf:"bytes,2,opt,name=Code,proto3" json:"Code,omitempty"`
+	Data        []byte                                       `protobuf:"bytes,3,opt,name=Data,proto3" json:"Data,omitempty"`
+}
+
+func (m *CallCodeParam) Reset()                    { *m = CallCodeParam{} }
+func (m *CallCodeParam) String() string            { return proto.CompactTextString(m) }
+func (*CallCodeParam) ProtoMessage()               {}
+func (*CallCodeParam) Descriptor() ([]byte, []int) { return fileDescriptorRpctransact, []int{0} }
+
+func (m *CallCodeParam) GetCode() []byte {
+	if m != nil {
+		return m.Code
+	}
+	return nil
+}
+
+func (m *CallCodeParam) GetData() []byte {
+	if m != nil {
+		return m.Data
+	}
+	return nil
+}
+
+func (*CallCodeParam) XXX_MessageName() string {
+	return "rpctransact.CallCodeParam"
+}
+
+type PayloadParam struct {
+	CallTx *payload.CallTx `protobuf:"bytes,1,opt,name=CallTx" json:"CallTx,omitempty"`
+	SendTx *payload.SendTx `protobuf:"bytes,2,opt,name=SendTx" json:"SendTx,omitempty"`
+	NameTx *payload.NameTx `protobuf:"bytes,3,opt,name=NameTx" json:"NameTx,omitempty"`
+}
+
+func (m *PayloadParam) Reset()                    { *m = PayloadParam{} }
+func (m *PayloadParam) String() string            { return proto.CompactTextString(m) }
+func (*PayloadParam) ProtoMessage()               {}
+func (*PayloadParam) Descriptor() ([]byte, []int) { return fileDescriptorRpctransact, []int{1} }
+
+func (m *PayloadParam) GetCallTx() *payload.CallTx {
+	if m != nil {
+		return m.CallTx
+	}
+	return nil
+}
+
+func (m *PayloadParam) GetSendTx() *payload.SendTx {
+	if m != nil {
+		return m.SendTx
+	}
+	return nil
+}
+
+func (m *PayloadParam) GetNameTx() *payload.NameTx {
+	if m != nil {
+		return m.NameTx
+	}
+	return nil
+}
+
+func (*PayloadParam) XXX_MessageName() string {
+	return "rpctransact.PayloadParam"
+}
+
+type TxEnvelope struct {
+	Envelope *github_com_hyperledger_burrow_txs.Envelope `protobuf:"bytes,1,opt,name=Envelope,customtype=github.com/hyperledger/burrow/txs.Envelope" json:"Envelope,omitempty"`
+}
+
+func (m *TxEnvelope) Reset()                    { *m = TxEnvelope{} }
+func (m *TxEnvelope) String() string            { return proto.CompactTextString(m) }
+func (*TxEnvelope) ProtoMessage()               {}
+func (*TxEnvelope) Descriptor() ([]byte, []int) { return fileDescriptorRpctransact, []int{2} }
+
+func (*TxEnvelope) XXX_MessageName() string {
+	return "rpctransact.TxEnvelope"
+}
+
+type TxEnvelopeParam struct {
+	// An existing Envelope - either signed or unsigned - if the latter will be signed server-side
+	Envelope *github_com_hyperledger_burrow_txs.Envelope `protobuf:"bytes,1,opt,name=Envelope,customtype=github.com/hyperledger/burrow/txs.Envelope" json:"Envelope,omitempty"`
+	// If no Envelope provided then one will be generated from the provided payload and signed server-side
+	Payload *PayloadParam `protobuf:"bytes,2,opt,name=Payload" json:"Payload,omitempty"`
+}
+
+func (m *TxEnvelopeParam) Reset()                    { *m = TxEnvelopeParam{} }
+func (m *TxEnvelopeParam) String() string            { return proto.CompactTextString(m) }
+func (*TxEnvelopeParam) ProtoMessage()               {}
+func (*TxEnvelopeParam) Descriptor() ([]byte, []int) { return fileDescriptorRpctransact, []int{3} }
+
+func (m *TxEnvelopeParam) GetPayload() *PayloadParam {
+	if m != nil {
+		return m.Payload
+	}
+	return nil
+}
+
+func (*TxEnvelopeParam) XXX_MessageName() string {
+	return "rpctransact.TxEnvelopeParam"
+}
+func init() {
+	proto.RegisterType((*CallCodeParam)(nil), "rpctransact.CallCodeParam")
+	golang_proto.RegisterType((*CallCodeParam)(nil), "rpctransact.CallCodeParam")
+	proto.RegisterType((*PayloadParam)(nil), "rpctransact.PayloadParam")
+	golang_proto.RegisterType((*PayloadParam)(nil), "rpctransact.PayloadParam")
+	proto.RegisterType((*TxEnvelope)(nil), "rpctransact.TxEnvelope")
+	golang_proto.RegisterType((*TxEnvelope)(nil), "rpctransact.TxEnvelope")
+	proto.RegisterType((*TxEnvelopeParam)(nil), "rpctransact.TxEnvelopeParam")
+	golang_proto.RegisterType((*TxEnvelopeParam)(nil), "rpctransact.TxEnvelopeParam")
+}
+
+// Reference imports to suppress errors if they are not otherwise used.
+var _ context.Context
+var _ grpc.ClientConn
+
+// This is a compile-time assertion to ensure that this generated file
+// is compatible with the grpc package it is being compiled against.
+const _ = grpc.SupportPackageIsVersion4
+
+// Client API for Transact service
+
+type TransactClient interface {
+	// Broadcast a transaction to the mempool - if the transaction is not signed signing will be attempted server-side
+	// and wait for it to be included in block
+	BroadcastTxSync(ctx context.Context, in *TxEnvelopeParam, opts ...grpc.CallOption) (*exec.TxExecution, error)
+	// Broadcast a transaction to the mempool - if the transaction is not signed signing will be attempted server-side
+	BroadcastTxAsync(ctx context.Context, in *TxEnvelopeParam, opts ...grpc.CallOption) (*txs.Receipt, error)
+	// Sign transaction server-side
+	SignTx(ctx context.Context, in *TxEnvelopeParam, opts ...grpc.CallOption) (*TxEnvelope, error)
+	// Formulate a transaction from a Payload and retrun the envelop with the Tx bytes ready to sign
+	FormulateTx(ctx context.Context, in *PayloadParam, opts ...grpc.CallOption) (*TxEnvelope, error)
+	// Formulate and sign a CallTx transaction signed server-side and wait for it to be included in a block, retrieving response
+	CallTxSync(ctx context.Context, in *payload.CallTx, opts ...grpc.CallOption) (*exec.TxExecution, error)
+	// Formulate and sign a CallTx transaction signed server-side
+	CallTxAsync(ctx context.Context, in *payload.CallTx, opts ...grpc.CallOption) (*txs.Receipt, error)
+	// Perform a 'simulated' call of a contract against the current committed EVM state without any changes been saved
+	// and wait for the transaction to be included in a block
+	CallTxSim(ctx context.Context, in *payload.CallTx, opts ...grpc.CallOption) (*exec.TxExecution, error)
+	// Perform a 'simulated' execution of provided code against the current committed EVM state without any changes been saved
+	CallCodeSim(ctx context.Context, in *CallCodeParam, opts ...grpc.CallOption) (*exec.TxExecution, error)
+	// Formulate a SendTx transaction signed server-side and wait for it to be included in a block, retrieving response
+	SendTxSync(ctx context.Context, in *payload.SendTx, opts ...grpc.CallOption) (*exec.TxExecution, error)
+	// Formulate and  SendTx transaction signed server-side
+	SendTxAsync(ctx context.Context, in *payload.SendTx, opts ...grpc.CallOption) (*txs.Receipt, error)
+	// Formualte a NameTx signed server-side and wait for it to be included in a block returning the registered name
+	NameTxSync(ctx context.Context, in *payload.NameTx, opts ...grpc.CallOption) (*exec.TxExecution, error)
+	// Formulate a NameTx signed server-side
+	NameTxAsync(ctx context.Context, in *payload.NameTx, opts ...grpc.CallOption) (*txs.Receipt, error)
+}
+
+type transactClient struct {
+	cc *grpc.ClientConn
+}
+
+func NewTransactClient(cc *grpc.ClientConn) TransactClient {
+	return &transactClient{cc}
+}
+
+func (c *transactClient) BroadcastTxSync(ctx context.Context, in *TxEnvelopeParam, opts ...grpc.CallOption) (*exec.TxExecution, error) {
+	out := new(exec.TxExecution)
+	err := grpc.Invoke(ctx, "/rpctransact.Transact/BroadcastTxSync", in, out, c.cc, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *transactClient) BroadcastTxAsync(ctx context.Context, in *TxEnvelopeParam, opts ...grpc.CallOption) (*txs.Receipt, error) {
+	out := new(txs.Receipt)
+	err := grpc.Invoke(ctx, "/rpctransact.Transact/BroadcastTxAsync", in, out, c.cc, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *transactClient) SignTx(ctx context.Context, in *TxEnvelopeParam, opts ...grpc.CallOption) (*TxEnvelope, error) {
+	out := new(TxEnvelope)
+	err := grpc.Invoke(ctx, "/rpctransact.Transact/SignTx", in, out, c.cc, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *transactClient) FormulateTx(ctx context.Context, in *PayloadParam, opts ...grpc.CallOption) (*TxEnvelope, error) {
+	out := new(TxEnvelope)
+	err := grpc.Invoke(ctx, "/rpctransact.Transact/FormulateTx", in, out, c.cc, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *transactClient) CallTxSync(ctx context.Context, in *payload.CallTx, opts ...grpc.CallOption) (*exec.TxExecution, error) {
+	out := new(exec.TxExecution)
+	err := grpc.Invoke(ctx, "/rpctransact.Transact/CallTxSync", in, out, c.cc, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *transactClient) CallTxAsync(ctx context.Context, in *payload.CallTx, opts ...grpc.CallOption) (*txs.Receipt, error) {
+	out := new(txs.Receipt)
+	err := grpc.Invoke(ctx, "/rpctransact.Transact/CallTxAsync", in, out, c.cc, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *transactClient) CallTxSim(ctx context.Context, in *payload.CallTx, opts ...grpc.CallOption) (*exec.TxExecution, error) {
+	out := new(exec.TxExecution)
+	err := grpc.Invoke(ctx, "/rpctransact.Transact/CallTxSim", in, out, c.cc, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *transactClient) CallCodeSim(ctx context.Context, in *CallCodeParam, opts ...grpc.CallOption) (*exec.TxExecution, error) {
+	out := new(exec.TxExecution)
+	err := grpc.Invoke(ctx, "/rpctransact.Transact/CallCodeSim", in, out, c.cc, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *transactClient) SendTxSync(ctx context.Context, in *payload.SendTx, opts ...grpc.CallOption) (*exec.TxExecution, error) {
+	out := new(exec.TxExecution)
+	err := grpc.Invoke(ctx, "/rpctransact.Transact/SendTxSync", in, out, c.cc, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *transactClient) SendTxAsync(ctx context.Context, in *payload.SendTx, opts ...grpc.CallOption) (*txs.Receipt, error) {
+	out := new(txs.Receipt)
+	err := grpc.Invoke(ctx, "/rpctransact.Transact/SendTxAsync", in, out, c.cc, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *transactClient) NameTxSync(ctx context.Context, in *payload.NameTx, opts ...grpc.CallOption) (*exec.TxExecution, error) {
+	out := new(exec.TxExecution)
+	err := grpc.Invoke(ctx, "/rpctransact.Transact/NameTxSync", in, out, c.cc, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *transactClient) NameTxAsync(ctx context.Context, in *payload.NameTx, opts ...grpc.CallOption) (*txs.Receipt, error) {
+	out := new(txs.Receipt)
+	err := grpc.Invoke(ctx, "/rpctransact.Transact/NameTxAsync", in, out, c.cc, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+// Server API for Transact service
+
+type TransactServer interface {
+	// Broadcast a transaction to the mempool - if the transaction is not signed signing will be attempted server-side
+	// and wait for it to be included in block
+	BroadcastTxSync(context.Context, *TxEnvelopeParam) (*exec.TxExecution, error)
+	// Broadcast a transaction to the mempool - if the transaction is not signed signing will be attempted server-side
+	BroadcastTxAsync(context.Context, *TxEnvelopeParam) (*txs.Receipt, error)
+	// Sign transaction server-side
+	SignTx(context.Context, *TxEnvelopeParam) (*TxEnvelope, error)
+	// Formulate a transaction from a Payload and retrun the envelop with the Tx bytes ready to sign
+	FormulateTx(context.Context, *PayloadParam) (*TxEnvelope, error)
+	// Formulate and sign a CallTx transaction signed server-side and wait for it to be included in a block, retrieving response
+	CallTxSync(context.Context, *payload.CallTx) (*exec.TxExecution, error)
+	// Formulate and sign a CallTx transaction signed server-side
+	CallTxAsync(context.Context, *payload.CallTx) (*txs.Receipt, error)
+	// Perform a 'simulated' call of a contract against the current committed EVM state without any changes been saved
+	// and wait for the transaction to be included in a block
+	CallTxSim(context.Context, *payload.CallTx) (*exec.TxExecution, error)
+	// Perform a 'simulated' execution of provided code against the current committed EVM state without any changes been saved
+	CallCodeSim(context.Context, *CallCodeParam) (*exec.TxExecution, error)
+	// Formulate a SendTx transaction signed server-side and wait for it to be included in a block, retrieving response
+	SendTxSync(context.Context, *payload.SendTx) (*exec.TxExecution, error)
+	// Formulate and  SendTx transaction signed server-side
+	SendTxAsync(context.Context, *payload.SendTx) (*txs.Receipt, error)
+	// Formualte a NameTx signed server-side and wait for it to be included in a block returning the registered name
+	NameTxSync(context.Context, *payload.NameTx) (*exec.TxExecution, error)
+	// Formulate a NameTx signed server-side
+	NameTxAsync(context.Context, *payload.NameTx) (*txs.Receipt, error)
+}
+
+func RegisterTransactServer(s *grpc.Server, srv TransactServer) {
+	s.RegisterService(&_Transact_serviceDesc, srv)
+}
+
+func _Transact_BroadcastTxSync_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(TxEnvelopeParam)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(TransactServer).BroadcastTxSync(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/rpctransact.Transact/BroadcastTxSync",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(TransactServer).BroadcastTxSync(ctx, req.(*TxEnvelopeParam))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _Transact_BroadcastTxAsync_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(TxEnvelopeParam)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(TransactServer).BroadcastTxAsync(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/rpctransact.Transact/BroadcastTxAsync",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(TransactServer).BroadcastTxAsync(ctx, req.(*TxEnvelopeParam))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _Transact_SignTx_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(TxEnvelopeParam)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(TransactServer).SignTx(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/rpctransact.Transact/SignTx",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(TransactServer).SignTx(ctx, req.(*TxEnvelopeParam))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _Transact_FormulateTx_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(PayloadParam)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(TransactServer).FormulateTx(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/rpctransact.Transact/FormulateTx",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(TransactServer).FormulateTx(ctx, req.(*PayloadParam))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _Transact_CallTxSync_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(payload.CallTx)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(TransactServer).CallTxSync(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/rpctransact.Transact/CallTxSync",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(TransactServer).CallTxSync(ctx, req.(*payload.CallTx))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _Transact_CallTxAsync_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(payload.CallTx)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(TransactServer).CallTxAsync(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/rpctransact.Transact/CallTxAsync",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(TransactServer).CallTxAsync(ctx, req.(*payload.CallTx))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _Transact_CallTxSim_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(payload.CallTx)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(TransactServer).CallTxSim(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/rpctransact.Transact/CallTxSim",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(TransactServer).CallTxSim(ctx, req.(*payload.CallTx))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _Transact_CallCodeSim_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(CallCodeParam)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(TransactServer).CallCodeSim(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/rpctransact.Transact/CallCodeSim",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(TransactServer).CallCodeSim(ctx, req.(*CallCodeParam))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _Transact_SendTxSync_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(payload.SendTx)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(TransactServer).SendTxSync(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/rpctransact.Transact/SendTxSync",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(TransactServer).SendTxSync(ctx, req.(*payload.SendTx))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _Transact_SendTxAsync_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(payload.SendTx)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(TransactServer).SendTxAsync(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/rpctransact.Transact/SendTxAsync",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(TransactServer).SendTxAsync(ctx, req.(*payload.SendTx))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _Transact_NameTxSync_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(payload.NameTx)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(TransactServer).NameTxSync(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/rpctransact.Transact/NameTxSync",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(TransactServer).NameTxSync(ctx, req.(*payload.NameTx))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _Transact_NameTxAsync_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(payload.NameTx)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(TransactServer).NameTxAsync(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/rpctransact.Transact/NameTxAsync",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(TransactServer).NameTxAsync(ctx, req.(*payload.NameTx))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+var _Transact_serviceDesc = grpc.ServiceDesc{
+	ServiceName: "rpctransact.Transact",
+	HandlerType: (*TransactServer)(nil),
+	Methods: []grpc.MethodDesc{
+		{
+			MethodName: "BroadcastTxSync",
+			Handler:    _Transact_BroadcastTxSync_Handler,
+		},
+		{
+			MethodName: "BroadcastTxAsync",
+			Handler:    _Transact_BroadcastTxAsync_Handler,
+		},
+		{
+			MethodName: "SignTx",
+			Handler:    _Transact_SignTx_Handler,
+		},
+		{
+			MethodName: "FormulateTx",
+			Handler:    _Transact_FormulateTx_Handler,
+		},
+		{
+			MethodName: "CallTxSync",
+			Handler:    _Transact_CallTxSync_Handler,
+		},
+		{
+			MethodName: "CallTxAsync",
+			Handler:    _Transact_CallTxAsync_Handler,
+		},
+		{
+			MethodName: "CallTxSim",
+			Handler:    _Transact_CallTxSim_Handler,
+		},
+		{
+			MethodName: "CallCodeSim",
+			Handler:    _Transact_CallCodeSim_Handler,
+		},
+		{
+			MethodName: "SendTxSync",
+			Handler:    _Transact_SendTxSync_Handler,
+		},
+		{
+			MethodName: "SendTxAsync",
+			Handler:    _Transact_SendTxAsync_Handler,
+		},
+		{
+			MethodName: "NameTxSync",
+			Handler:    _Transact_NameTxSync_Handler,
+		},
+		{
+			MethodName: "NameTxAsync",
+			Handler:    _Transact_NameTxAsync_Handler,
+		},
+	},
+	Streams:  []grpc.StreamDesc{},
+	Metadata: "rpctransact.proto",
+}
+
+func (m *CallCodeParam) Marshal() (dAtA []byte, err error) {
+	size := m.Size()
+	dAtA = make([]byte, size)
+	n, err := m.MarshalTo(dAtA)
+	if err != nil {
+		return nil, err
+	}
+	return dAtA[:n], nil
+}
+
+func (m *CallCodeParam) MarshalTo(dAtA []byte) (int, error) {
+	var i int
+	_ = i
+	var l int
+	_ = l
+	dAtA[i] = 0xa
+	i++
+	i = encodeVarintRpctransact(dAtA, i, uint64(m.FromAddress.Size()))
+	n1, err := m.FromAddress.MarshalTo(dAtA[i:])
+	if err != nil {
+		return 0, err
+	}
+	i += n1
+	if len(m.Code) > 0 {
+		dAtA[i] = 0x12
+		i++
+		i = encodeVarintRpctransact(dAtA, i, uint64(len(m.Code)))
+		i += copy(dAtA[i:], m.Code)
+	}
+	if len(m.Data) > 0 {
+		dAtA[i] = 0x1a
+		i++
+		i = encodeVarintRpctransact(dAtA, i, uint64(len(m.Data)))
+		i += copy(dAtA[i:], m.Data)
+	}
+	return i, nil
+}
+
+func (m *PayloadParam) Marshal() (dAtA []byte, err error) {
+	size := m.Size()
+	dAtA = make([]byte, size)
+	n, err := m.MarshalTo(dAtA)
+	if err != nil {
+		return nil, err
+	}
+	return dAtA[:n], nil
+}
+
+func (m *PayloadParam) MarshalTo(dAtA []byte) (int, error) {
+	var i int
+	_ = i
+	var l int
+	_ = l
+	if m.CallTx != nil {
+		dAtA[i] = 0xa
+		i++
+		i = encodeVarintRpctransact(dAtA, i, uint64(m.CallTx.Size()))
+		n2, err := m.CallTx.MarshalTo(dAtA[i:])
+		if err != nil {
+			return 0, err
+		}
+		i += n2
+	}
+	if m.SendTx != nil {
+		dAtA[i] = 0x12
+		i++
+		i = encodeVarintRpctransact(dAtA, i, uint64(m.SendTx.Size()))
+		n3, err := m.SendTx.MarshalTo(dAtA[i:])
+		if err != nil {
+			return 0, err
+		}
+		i += n3
+	}
+	if m.NameTx != nil {
+		dAtA[i] = 0x1a
+		i++
+		i = encodeVarintRpctransact(dAtA, i, uint64(m.NameTx.Size()))
+		n4, err := m.NameTx.MarshalTo(dAtA[i:])
+		if err != nil {
+			return 0, err
+		}
+		i += n4
+	}
+	return i, nil
+}
+
+func (m *TxEnvelope) Marshal() (dAtA []byte, err error) {
+	size := m.Size()
+	dAtA = make([]byte, size)
+	n, err := m.MarshalTo(dAtA)
+	if err != nil {
+		return nil, err
+	}
+	return dAtA[:n], nil
+}
+
+func (m *TxEnvelope) MarshalTo(dAtA []byte) (int, error) {
+	var i int
+	_ = i
+	var l int
+	_ = l
+	if m.Envelope != nil {
+		dAtA[i] = 0xa
+		i++
+		i = encodeVarintRpctransact(dAtA, i, uint64(m.Envelope.Size()))
+		n5, err := m.Envelope.MarshalTo(dAtA[i:])
+		if err != nil {
+			return 0, err
+		}
+		i += n5
+	}
+	return i, nil
+}
+
+func (m *TxEnvelopeParam) Marshal() (dAtA []byte, err error) {
+	size := m.Size()
+	dAtA = make([]byte, size)
+	n, err := m.MarshalTo(dAtA)
+	if err != nil {
+		return nil, err
+	}
+	return dAtA[:n], nil
+}
+
+func (m *TxEnvelopeParam) MarshalTo(dAtA []byte) (int, error) {
+	var i int
+	_ = i
+	var l int
+	_ = l
+	if m.Envelope != nil {
+		dAtA[i] = 0xa
+		i++
+		i = encodeVarintRpctransact(dAtA, i, uint64(m.Envelope.Size()))
+		n6, err := m.Envelope.MarshalTo(dAtA[i:])
+		if err != nil {
+			return 0, err
+		}
+		i += n6
+	}
+	if m.Payload != nil {
+		dAtA[i] = 0x12
+		i++
+		i = encodeVarintRpctransact(dAtA, i, uint64(m.Payload.Size()))
+		n7, err := m.Payload.MarshalTo(dAtA[i:])
+		if err != nil {
+			return 0, err
+		}
+		i += n7
+	}
+	return i, nil
+}
+
+func encodeVarintRpctransact(dAtA []byte, offset int, v uint64) int {
+	for v >= 1<<7 {
+		dAtA[offset] = uint8(v&0x7f | 0x80)
+		v >>= 7
+		offset++
+	}
+	dAtA[offset] = uint8(v)
+	return offset + 1
+}
+func (m *CallCodeParam) Size() (n int) {
+	var l int
+	_ = l
+	l = m.FromAddress.Size()
+	n += 1 + l + sovRpctransact(uint64(l))
+	l = len(m.Code)
+	if l > 0 {
+		n += 1 + l + sovRpctransact(uint64(l))
+	}
+	l = len(m.Data)
+	if l > 0 {
+		n += 1 + l + sovRpctransact(uint64(l))
+	}
+	return n
+}
+
+func (m *PayloadParam) Size() (n int) {
+	var l int
+	_ = l
+	if m.CallTx != nil {
+		l = m.CallTx.Size()
+		n += 1 + l + sovRpctransact(uint64(l))
+	}
+	if m.SendTx != nil {
+		l = m.SendTx.Size()
+		n += 1 + l + sovRpctransact(uint64(l))
+	}
+	if m.NameTx != nil {
+		l = m.NameTx.Size()
+		n += 1 + l + sovRpctransact(uint64(l))
+	}
+	return n
+}
+
+func (m *TxEnvelope) Size() (n int) {
+	var l int
+	_ = l
+	if m.Envelope != nil {
+		l = m.Envelope.Size()
+		n += 1 + l + sovRpctransact(uint64(l))
+	}
+	return n
+}
+
+func (m *TxEnvelopeParam) Size() (n int) {
+	var l int
+	_ = l
+	if m.Envelope != nil {
+		l = m.Envelope.Size()
+		n += 1 + l + sovRpctransact(uint64(l))
+	}
+	if m.Payload != nil {
+		l = m.Payload.Size()
+		n += 1 + l + sovRpctransact(uint64(l))
+	}
+	return n
+}
+
+func sovRpctransact(x uint64) (n int) {
+	for {
+		n++
+		x >>= 7
+		if x == 0 {
+			break
+		}
+	}
+	return n
+}
+func sozRpctransact(x uint64) (n int) {
+	return sovRpctransact(uint64((x << 1) ^ uint64((int64(x) >> 63))))
+}
+func (m *CallCodeParam) Unmarshal(dAtA []byte) error {
+	l := len(dAtA)
+	iNdEx := 0
+	for iNdEx < l {
+		preIndex := iNdEx
+		var wire uint64
+		for shift := uint(0); ; shift += 7 {
+			if shift >= 64 {
+				return ErrIntOverflowRpctransact
+			}
+			if iNdEx >= l {
+				return io.ErrUnexpectedEOF
+			}
+			b := dAtA[iNdEx]
+			iNdEx++
+			wire |= (uint64(b) & 0x7F) << shift
+			if b < 0x80 {
+				break
+			}
+		}
+		fieldNum := int32(wire >> 3)
+		wireType := int(wire & 0x7)
+		if wireType == 4 {
+			return fmt.Errorf("proto: CallCodeParam: wiretype end group for non-group")
+		}
+		if fieldNum <= 0 {
+			return fmt.Errorf("proto: CallCodeParam: illegal tag %d (wire type %d)", fieldNum, wire)
+		}
+		switch fieldNum {
+		case 1:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field FromAddress", wireType)
+			}
+			var byteLen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowRpctransact
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				byteLen |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if byteLen < 0 {
+				return ErrInvalidLengthRpctransact
+			}
+			postIndex := iNdEx + byteLen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			if err := m.FromAddress.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+				return err
+			}
+			iNdEx = postIndex
+		case 2:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Code", wireType)
+			}
+			var byteLen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowRpctransact
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				byteLen |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if byteLen < 0 {
+				return ErrInvalidLengthRpctransact
+			}
+			postIndex := iNdEx + byteLen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			m.Code = append(m.Code[:0], dAtA[iNdEx:postIndex]...)
+			if m.Code == nil {
+				m.Code = []byte{}
+			}
+			iNdEx = postIndex
+		case 3:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Data", wireType)
+			}
+			var byteLen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowRpctransact
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				byteLen |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if byteLen < 0 {
+				return ErrInvalidLengthRpctransact
+			}
+			postIndex := iNdEx + byteLen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			m.Data = append(m.Data[:0], dAtA[iNdEx:postIndex]...)
+			if m.Data == nil {
+				m.Data = []byte{}
+			}
+			iNdEx = postIndex
+		default:
+			iNdEx = preIndex
+			skippy, err := skipRpctransact(dAtA[iNdEx:])
+			if err != nil {
+				return err
+			}
+			if skippy < 0 {
+				return ErrInvalidLengthRpctransact
+			}
+			if (iNdEx + skippy) > l {
+				return io.ErrUnexpectedEOF
+			}
+			iNdEx += skippy
+		}
+	}
+
+	if iNdEx > l {
+		return io.ErrUnexpectedEOF
+	}
+	return nil
+}
+func (m *PayloadParam) Unmarshal(dAtA []byte) error {
+	l := len(dAtA)
+	iNdEx := 0
+	for iNdEx < l {
+		preIndex := iNdEx
+		var wire uint64
+		for shift := uint(0); ; shift += 7 {
+			if shift >= 64 {
+				return ErrIntOverflowRpctransact
+			}
+			if iNdEx >= l {
+				return io.ErrUnexpectedEOF
+			}
+			b := dAtA[iNdEx]
+			iNdEx++
+			wire |= (uint64(b) & 0x7F) << shift
+			if b < 0x80 {
+				break
+			}
+		}
+		fieldNum := int32(wire >> 3)
+		wireType := int(wire & 0x7)
+		if wireType == 4 {
+			return fmt.Errorf("proto: PayloadParam: wiretype end group for non-group")
+		}
+		if fieldNum <= 0 {
+			return fmt.Errorf("proto: PayloadParam: illegal tag %d (wire type %d)", fieldNum, wire)
+		}
+		switch fieldNum {
+		case 1:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field CallTx", wireType)
+			}
+			var msglen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowRpctransact
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				msglen |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if msglen < 0 {
+				return ErrInvalidLengthRpctransact
+			}
+			postIndex := iNdEx + msglen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			if m.CallTx == nil {
+				m.CallTx = &payload.CallTx{}
+			}
+			if err := m.CallTx.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+				return err
+			}
+			iNdEx = postIndex
+		case 2:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field SendTx", wireType)
+			}
+			var msglen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowRpctransact
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				msglen |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if msglen < 0 {
+				return ErrInvalidLengthRpctransact
+			}
+			postIndex := iNdEx + msglen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			if m.SendTx == nil {
+				m.SendTx = &payload.SendTx{}
+			}
+			if err := m.SendTx.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+				return err
+			}
+			iNdEx = postIndex
+		case 3:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field NameTx", wireType)
+			}
+			var msglen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowRpctransact
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				msglen |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if msglen < 0 {
+				return ErrInvalidLengthRpctransact
+			}
+			postIndex := iNdEx + msglen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			if m.NameTx == nil {
+				m.NameTx = &payload.NameTx{}
+			}
+			if err := m.NameTx.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+				return err
+			}
+			iNdEx = postIndex
+		default:
+			iNdEx = preIndex
+			skippy, err := skipRpctransact(dAtA[iNdEx:])
+			if err != nil {
+				return err
+			}
+			if skippy < 0 {
+				return ErrInvalidLengthRpctransact
+			}
+			if (iNdEx + skippy) > l {
+				return io.ErrUnexpectedEOF
+			}
+			iNdEx += skippy
+		}
+	}
+
+	if iNdEx > l {
+		return io.ErrUnexpectedEOF
+	}
+	return nil
+}
+func (m *TxEnvelope) Unmarshal(dAtA []byte) error {
+	l := len(dAtA)
+	iNdEx := 0
+	for iNdEx < l {
+		preIndex := iNdEx
+		var wire uint64
+		for shift := uint(0); ; shift += 7 {
+			if shift >= 64 {
+				return ErrIntOverflowRpctransact
+			}
+			if iNdEx >= l {
+				return io.ErrUnexpectedEOF
+			}
+			b := dAtA[iNdEx]
+			iNdEx++
+			wire |= (uint64(b) & 0x7F) << shift
+			if b < 0x80 {
+				break
+			}
+		}
+		fieldNum := int32(wire >> 3)
+		wireType := int(wire & 0x7)
+		if wireType == 4 {
+			return fmt.Errorf("proto: TxEnvelope: wiretype end group for non-group")
+		}
+		if fieldNum <= 0 {
+			return fmt.Errorf("proto: TxEnvelope: illegal tag %d (wire type %d)", fieldNum, wire)
+		}
+		switch fieldNum {
+		case 1:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Envelope", wireType)
+			}
+			var msglen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowRpctransact
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				msglen |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if msglen < 0 {
+				return ErrInvalidLengthRpctransact
+			}
+			postIndex := iNdEx + msglen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			if m.Envelope == nil {
+				m.Envelope = &github_com_hyperledger_burrow_txs.Envelope{}
+			}
+			if err := m.Envelope.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+				return err
+			}
+			iNdEx = postIndex
+		default:
+			iNdEx = preIndex
+			skippy, err := skipRpctransact(dAtA[iNdEx:])
+			if err != nil {
+				return err
+			}
+			if skippy < 0 {
+				return ErrInvalidLengthRpctransact
+			}
+			if (iNdEx + skippy) > l {
+				return io.ErrUnexpectedEOF
+			}
+			iNdEx += skippy
+		}
+	}
+
+	if iNdEx > l {
+		return io.ErrUnexpectedEOF
+	}
+	return nil
+}
+func (m *TxEnvelopeParam) Unmarshal(dAtA []byte) error {
+	l := len(dAtA)
+	iNdEx := 0
+	for iNdEx < l {
+		preIndex := iNdEx
+		var wire uint64
+		for shift := uint(0); ; shift += 7 {
+			if shift >= 64 {
+				return ErrIntOverflowRpctransact
+			}
+			if iNdEx >= l {
+				return io.ErrUnexpectedEOF
+			}
+			b := dAtA[iNdEx]
+			iNdEx++
+			wire |= (uint64(b) & 0x7F) << shift
+			if b < 0x80 {
+				break
+			}
+		}
+		fieldNum := int32(wire >> 3)
+		wireType := int(wire & 0x7)
+		if wireType == 4 {
+			return fmt.Errorf("proto: TxEnvelopeParam: wiretype end group for non-group")
+		}
+		if fieldNum <= 0 {
+			return fmt.Errorf("proto: TxEnvelopeParam: illegal tag %d (wire type %d)", fieldNum, wire)
+		}
+		switch fieldNum {
+		case 1:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Envelope", wireType)
+			}
+			var msglen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowRpctransact
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				msglen |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if msglen < 0 {
+				return ErrInvalidLengthRpctransact
+			}
+			postIndex := iNdEx + msglen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			if m.Envelope == nil {
+				m.Envelope = &github_com_hyperledger_burrow_txs.Envelope{}
+			}
+			if err := m.Envelope.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+				return err
+			}
+			iNdEx = postIndex
+		case 2:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Payload", wireType)
+			}
+			var msglen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowRpctransact
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				msglen |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if msglen < 0 {
+				return ErrInvalidLengthRpctransact
+			}
+			postIndex := iNdEx + msglen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			if m.Payload == nil {
+				m.Payload = &PayloadParam{}
+			}
+			if err := m.Payload.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+				return err
+			}
+			iNdEx = postIndex
+		default:
+			iNdEx = preIndex
+			skippy, err := skipRpctransact(dAtA[iNdEx:])
+			if err != nil {
+				return err
+			}
+			if skippy < 0 {
+				return ErrInvalidLengthRpctransact
+			}
+			if (iNdEx + skippy) > l {
+				return io.ErrUnexpectedEOF
+			}
+			iNdEx += skippy
+		}
+	}
+
+	if iNdEx > l {
+		return io.ErrUnexpectedEOF
+	}
+	return nil
+}
+func skipRpctransact(dAtA []byte) (n int, err error) {
+	l := len(dAtA)
+	iNdEx := 0
+	for iNdEx < l {
+		var wire uint64
+		for shift := uint(0); ; shift += 7 {
+			if shift >= 64 {
+				return 0, ErrIntOverflowRpctransact
+			}
+			if iNdEx >= l {
+				return 0, io.ErrUnexpectedEOF
+			}
+			b := dAtA[iNdEx]
+			iNdEx++
+			wire |= (uint64(b) & 0x7F) << shift
+			if b < 0x80 {
+				break
+			}
+		}
+		wireType := int(wire & 0x7)
+		switch wireType {
+		case 0:
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return 0, ErrIntOverflowRpctransact
+				}
+				if iNdEx >= l {
+					return 0, io.ErrUnexpectedEOF
+				}
+				iNdEx++
+				if dAtA[iNdEx-1] < 0x80 {
+					break
+				}
+			}
+			return iNdEx, nil
+		case 1:
+			iNdEx += 8
+			return iNdEx, nil
+		case 2:
+			var length int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return 0, ErrIntOverflowRpctransact
+				}
+				if iNdEx >= l {
+					return 0, io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				length |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			iNdEx += length
+			if length < 0 {
+				return 0, ErrInvalidLengthRpctransact
+			}
+			return iNdEx, nil
+		case 3:
+			for {
+				var innerWire uint64
+				var start int = iNdEx
+				for shift := uint(0); ; shift += 7 {
+					if shift >= 64 {
+						return 0, ErrIntOverflowRpctransact
+					}
+					if iNdEx >= l {
+						return 0, io.ErrUnexpectedEOF
+					}
+					b := dAtA[iNdEx]
+					iNdEx++
+					innerWire |= (uint64(b) & 0x7F) << shift
+					if b < 0x80 {
+						break
+					}
+				}
+				innerWireType := int(innerWire & 0x7)
+				if innerWireType == 4 {
+					break
+				}
+				next, err := skipRpctransact(dAtA[start:])
+				if err != nil {
+					return 0, err
+				}
+				iNdEx = start + next
+			}
+			return iNdEx, nil
+		case 4:
+			return iNdEx, nil
+		case 5:
+			iNdEx += 4
+			return iNdEx, nil
+		default:
+			return 0, fmt.Errorf("proto: illegal wireType %d", wireType)
+		}
+	}
+	panic("unreachable")
+}
+
+var (
+	ErrInvalidLengthRpctransact = fmt.Errorf("proto: negative length found during unmarshaling")
+	ErrIntOverflowRpctransact   = fmt.Errorf("proto: integer overflow")
+)
+
+func init() { proto.RegisterFile("rpctransact.proto", fileDescriptorRpctransact) }
+func init() { golang_proto.RegisterFile("rpctransact.proto", fileDescriptorRpctransact) }
+
+var fileDescriptorRpctransact = []byte{
+	// 552 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x54, 0xcd, 0x6e, 0xd3, 0x40,
+	0x10, 0xc6, 0xfc, 0x84, 0x76, 0x92, 0x28, 0x74, 0x2f, 0x84, 0x08, 0x25, 0x28, 0x17, 0x10, 0x6a,
+	0xed, 0xa8, 0xe5, 0x88, 0x40, 0x49, 0x68, 0x8f, 0xa8, 0x72, 0x2c, 0x24, 0xb8, 0x6d, 0xec, 0xc5,
+	0x8d, 0x64, 0x7b, 0xad, 0xf5, 0x06, 0x36, 0x8f, 0xc0, 0x89, 0x67, 0xe8, 0x9b, 0x70, 0xcc, 0x91,
+	0x73, 0x0f, 0x11, 0x4a, 0x5f, 0x04, 0xed, 0x4f, 0x60, 0x6d, 0x9a, 0x96, 0x4b, 0x6f, 0xe3, 0x6f,
+	0x66, 0xbe, 0x99, 0xef, 0xd3, 0x8e, 0x61, 0x8f, 0xe5, 0x21, 0x67, 0x38, 0x2b, 0x70, 0xc8, 0xdd,
+	0x9c, 0x51, 0x4e, 0x51, 0xdd, 0x82, 0x3a, 0x07, 0xf1, 0x8c, 0x9f, 0xcd, 0xa7, 0x6e, 0x48, 0x53,
+	0x2f, 0xa6, 0x31, 0xf5, 0x54, 0xcd, 0x74, 0xfe, 0x59, 0x7d, 0xa9, 0x0f, 0x15, 0xe9, 0xde, 0x0e,
+	0x10, 0x41, 0x42, 0x13, 0x37, 0x73, 0xbc, 0x48, 0x28, 0x8e, 0xcc, 0xe7, 0x2e, 0x17, 0x85, 0x0e,
+	0xfb, 0xdf, 0x1d, 0x68, 0x8e, 0x71, 0x92, 0x8c, 0x69, 0x44, 0x4e, 0x31, 0xc3, 0x29, 0xfa, 0x00,
+	0xf5, 0x13, 0x46, 0xd3, 0x61, 0x14, 0x31, 0x52, 0x14, 0x6d, 0xe7, 0x99, 0xf3, 0xa2, 0x31, 0x7a,
+	0xb5, 0x5c, 0xf5, 0xee, 0x5c, 0xac, 0x7a, 0xfb, 0xd6, 0x0e, 0x67, 0x8b, 0x9c, 0xb0, 0x84, 0x44,
+	0x31, 0x61, 0xde, 0x74, 0xce, 0x18, 0xfd, 0xea, 0x85, 0x6c, 0x91, 0x73, 0xea, 0x9a, 0x5e, 0xdf,
+	0x26, 0x42, 0x08, 0xee, 0xcb, 0x21, 0xed, 0xbb, 0x92, 0xd0, 0x57, 0xb1, 0xc4, 0xde, 0x61, 0x8e,
+	0xdb, 0xf7, 0x34, 0x26, 0xe3, 0xfe, 0x37, 0x07, 0x1a, 0xa7, 0x7a, 0x5d, 0xbd, 0xd0, 0x73, 0xa8,
+	0xc9, 0x0d, 0x03, 0xa1, 0x76, 0xa9, 0x1f, 0xb6, 0xdc, 0x8d, 0x1a, 0x0d, 0xfb, 0x26, 0x2d, 0x0b,
+	0x27, 0x24, 0x8b, 0x02, 0xa1, 0x66, 0xd8, 0x85, 0x1a, 0xf6, 0x4d, 0x5a, 0x16, 0xbe, 0xc7, 0x29,
+	0x09, 0x84, 0x1a, 0x6c, 0x17, 0x6a, 0xd8, 0x37, 0xe9, 0x7e, 0x0c, 0x10, 0x88, 0xe3, 0xec, 0x0b,
+	0x49, 0x68, 0x4e, 0xd0, 0x47, 0xd8, 0xd9, 0xc4, 0x66, 0x95, 0xa6, 0x2b, 0x9d, 0xdc, 0x80, 0x23,
+	0xf7, 0x62, 0xd5, 0x7b, 0x79, 0xbd, 0x43, 0x76, 0xbd, 0xff, 0x87, 0xae, 0x7f, 0xee, 0x40, 0xeb,
+	0xef, 0x24, 0xad, 0xfb, 0xf6, 0xc6, 0xa1, 0x23, 0x78, 0x68, 0x2c, 0x36, 0x56, 0x3d, 0x71, 0xed,
+	0xc7, 0x67, 0xdb, 0xef, 0x6f, 0x2a, 0x0f, 0xcf, 0x1f, 0xc0, 0x4e, 0x60, 0x4a, 0xd0, 0x08, 0x5a,
+	0x23, 0x46, 0x71, 0x14, 0xe2, 0x82, 0x07, 0x62, 0xb2, 0xc8, 0x42, 0xf4, 0xb4, 0xc4, 0x51, 0x51,
+	0xd3, 0xd9, 0x73, 0xd5, 0x7b, 0x0c, 0xc4, 0xb1, 0x20, 0xe1, 0x9c, 0xcf, 0x68, 0x86, 0xde, 0xc0,
+	0x23, 0x8b, 0x63, 0x58, 0xdc, 0x4c, 0xd2, 0x50, 0x06, 0xf8, 0x24, 0x24, 0xb3, 0x9c, 0xa3, 0xb7,
+	0x50, 0x9b, 0xcc, 0xe2, 0x2c, 0x10, 0x37, 0x74, 0x3d, 0xde, 0x92, 0x45, 0x43, 0xa8, 0x9f, 0x50,
+	0x96, 0xce, 0x13, 0xcc, 0x49, 0x20, 0xd0, 0x76, 0x13, 0xb6, 0x53, 0x0c, 0x00, 0xf4, 0xeb, 0x53,
+	0x16, 0x54, 0x9f, 0xe6, 0x55, 0xaa, 0xf7, 0xa1, 0xae, 0x93, 0x5a, 0xf0, 0x3f, 0x2d, 0x65, 0x8d,
+	0x1e, 0xec, 0x1a, 0xfe, 0x59, 0xfa, 0x5f, 0xf4, 0xaf, 0x35, 0xbd, 0x3c, 0x2f, 0xd9, 0xd2, 0x29,
+	0x2d, 0x5e, 0xba, 0xf4, 0xab, 0xba, 0x07, 0x00, 0xfa, 0x46, 0x2a, 0x72, 0x34, 0xb8, 0x45, 0x8e,
+	0x4e, 0x56, 0xe5, 0x98, 0x96, 0xb2, 0x9c, 0x01, 0x80, 0x3e, 0xad, 0x0a, 0xbf, 0x06, 0xb7, 0xf0,
+	0xeb, 0x64, 0x95, 0xdf, 0xb4, 0x94, 0xf8, 0x47, 0xe3, 0xe5, 0xba, 0xeb, 0xfc, 0x5c, 0x77, 0x9d,
+	0x5f, 0xeb, 0xae, 0xf3, 0xe3, 0xb2, 0xeb, 0x2c, 0x2f, 0xbb, 0xce, 0xa7, 0x83, 0xeb, 0x8f, 0x84,
+	0xe5, 0xa1, 0x67, 0xb9, 0x34, 0xad, 0xa9, 0x5f, 0xe3, 0xd1, 0xef, 0x00, 0x00, 0x00, 0xff, 0xff,
+	0x0f, 0x15, 0x24, 0xfe, 0x91, 0x05, 0x00, 0x00,
+}
diff --git a/rpc/rpctransact/transact_server.go b/rpc/rpctransact/transact_server.go
new file mode 100644
index 0000000000000000000000000000000000000000..ab3a8c6ea712dfebd4d81f08345b3b5070ef98d2
--- /dev/null
+++ b/rpc/rpctransact/transact_server.go
@@ -0,0 +1,148 @@
+package rpctransact
+
+import (
+	"fmt"
+
+	"github.com/hyperledger/burrow/execution"
+	"github.com/hyperledger/burrow/execution/exec"
+	"github.com/hyperledger/burrow/txs"
+	"github.com/hyperledger/burrow/txs/payload"
+	"golang.org/x/net/context"
+)
+
+type transactServer struct {
+	transactor *execution.Transactor
+	txCodec    txs.Codec
+}
+
+func NewTransactServer(transactor *execution.Transactor, txCodec txs.Codec) TransactServer {
+	return &transactServer{
+		transactor: transactor,
+		txCodec:    txCodec,
+	}
+}
+
+func (ts *transactServer) BroadcastTxSync(ctx context.Context, param *TxEnvelopeParam) (*exec.TxExecution, error) {
+	txEnv := param.GetEnvelope(ts.transactor.Tip.ChainID())
+	if txEnv == nil {
+		return nil, fmt.Errorf("no transaction envelope or payload provided")
+	}
+	return ts.transactor.BroadcastTxSync(ctx, txEnv)
+}
+
+func (ts *transactServer) BroadcastTxAsync(ctx context.Context, param *TxEnvelopeParam) (*txs.Receipt, error) {
+	txEnv := param.GetEnvelope(ts.transactor.Tip.ChainID())
+	if txEnv == nil {
+		return nil, fmt.Errorf("no transaction envelope or payload provided")
+	}
+	return ts.transactor.BroadcastTxAsync(txEnv)
+}
+
+func (ts *transactServer) SignTx(ctx context.Context, param *TxEnvelopeParam) (*TxEnvelope, error) {
+	txEnv := param.GetEnvelope(ts.transactor.Tip.ChainID())
+	if txEnv == nil {
+		return nil, fmt.Errorf("no transaction envelope or payload provided")
+	}
+	txEnv, err := ts.transactor.SignTx(txEnv)
+	if err != nil {
+		return nil, err
+	}
+	return &TxEnvelope{
+		Envelope: txEnv,
+	}, nil
+}
+
+func (ts *transactServer) FormulateTx(ctx context.Context, param *PayloadParam) (*TxEnvelope, error) {
+	txEnv := param.Envelope(ts.transactor.Tip.ChainID())
+	if txEnv == nil {
+		return nil, fmt.Errorf("no payload provided to FormulateTx")
+	}
+	return &TxEnvelope{
+		Envelope: txEnv,
+	}, nil
+}
+
+func (ts *transactServer) CallTxSync(ctx context.Context, param *payload.CallTx) (*exec.TxExecution, error) {
+	return ts.BroadcastTxSync(ctx, txEnvelopeParam(param))
+}
+
+func (ts *transactServer) CallTxAsync(ctx context.Context, param *payload.CallTx) (*txs.Receipt, error) {
+	return ts.BroadcastTxAsync(ctx, txEnvelopeParam(param))
+}
+
+func (ts *transactServer) CallTxSim(ctx context.Context, param *payload.CallTx) (*exec.TxExecution, error) {
+	if param.Address == nil {
+		return nil, fmt.Errorf("CallSim requires a non-nil address from which to retrieve code")
+	}
+	return ts.transactor.CallSim(param.Input.Address, *param.Address, param.Data)
+}
+
+func (ts *transactServer) CallCodeSim(ctx context.Context, param *CallCodeParam) (*exec.TxExecution, error) {
+	return ts.transactor.CallCodeSim(param.FromAddress, param.Code, param.Data)
+}
+
+func (ts *transactServer) SendTxSync(ctx context.Context, param *payload.SendTx) (*exec.TxExecution, error) {
+	return ts.BroadcastTxSync(ctx, txEnvelopeParam(param))
+}
+
+func (ts *transactServer) SendTxAsync(ctx context.Context, param *payload.SendTx) (*txs.Receipt, error) {
+	return ts.BroadcastTxAsync(ctx, txEnvelopeParam(param))
+}
+
+func (ts *transactServer) NameTxSync(ctx context.Context, param *payload.NameTx) (*exec.TxExecution, error) {
+	return ts.BroadcastTxSync(ctx, txEnvelopeParam(param))
+}
+
+func (ts *transactServer) NameTxAsync(ctx context.Context, param *payload.NameTx) (*txs.Receipt, error) {
+	return ts.BroadcastTxAsync(ctx, txEnvelopeParam(param))
+}
+
+func (te *TxEnvelopeParam) GetEnvelope(chainID string) *txs.Envelope {
+	if te == nil {
+		return nil
+	}
+	if te.Envelope != nil {
+		return te.Envelope
+	}
+	if te.Payload != nil {
+		return te.Payload.Envelope(chainID)
+	}
+	return nil
+}
+
+func (pp *PayloadParam) Envelope(chainID string) *txs.Envelope {
+	if pp.CallTx != nil {
+		return txs.Enclose(chainID, pp.CallTx)
+	}
+	if pp.SendTx != nil {
+		return txs.Enclose(chainID, pp.SendTx)
+	}
+	if pp.NameTx != nil {
+		return txs.Enclose(chainID, pp.NameTx)
+	}
+	return nil
+}
+
+func txEnvelopeParam(pl payload.Payload) *TxEnvelopeParam {
+	switch tx := pl.(type) {
+	case *payload.CallTx:
+		return &TxEnvelopeParam{
+			Payload: &PayloadParam{
+				CallTx: tx,
+			},
+		}
+	case *payload.SendTx:
+		return &TxEnvelopeParam{
+			Payload: &PayloadParam{
+				SendTx: tx,
+			},
+		}
+	case *payload.NameTx:
+		return &TxEnvelopeParam{
+			Payload: &PayloadParam{
+				NameTx: tx,
+			},
+		}
+	}
+	return nil
+}
diff --git a/rpc/rpctransactor/integration/transactor_server_test.go b/rpc/rpctransactor/integration/transactor_server_test.go
deleted file mode 100644
index cbb1a1c7556ee52f14070d099145334ae8a631ab..0000000000000000000000000000000000000000
--- a/rpc/rpctransactor/integration/transactor_server_test.go
+++ /dev/null
@@ -1,168 +0,0 @@
-// +build integration
-
-// Space above here matters
-// Copyright 2017 Monax Industries Limited
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//    http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package integration
-
-import (
-	"context"
-	"sync"
-	"testing"
-
-	"github.com/hyperledger/burrow/binary"
-	"github.com/hyperledger/burrow/execution/pbtransactor"
-	"github.com/hyperledger/burrow/rpc"
-	"github.com/hyperledger/burrow/rpc/test"
-	"github.com/stretchr/testify/assert"
-	"github.com/stretchr/testify/require"
-	"google.golang.org/grpc"
-)
-
-func TestTransactCallNoCode(t *testing.T) {
-	cli := newClient(t)
-
-	// Flip flops between sending private key and input address to test private key and address based signing
-	toAddress := privateAccounts[2].Address()
-
-	numCreates := 1000
-	countCh := test.CommittedTxCount(t, kern.Emitter)
-	for i := 0; i < numCreates; i++ {
-		receipt, err := cli.Transact(context.Background(), &pbtransactor.TransactParam{
-			InputAccount: inputAccount(i),
-			Address:      toAddress.Bytes(),
-			Data:         []byte{},
-			Value:        0,
-			Fee:          2,
-			GasLimit:     10000 + uint64(i),
-		})
-		require.NoError(t, err)
-		assert.False(t, receipt.CreatesContract)
-		assert.Equal(t, toAddress.Bytes(), receipt.ContractAddress)
-	}
-	require.Equal(t, numCreates, <-countCh)
-}
-
-func TestTransactCreate(t *testing.T) {
-	cli := newClient(t)
-	numGoroutines := 100
-	numCreates := 50
-	wg := new(sync.WaitGroup)
-	wg.Add(numGoroutines)
-	countCh := test.CommittedTxCount(t, kern.Emitter)
-	for i := 0; i < numGoroutines; i++ {
-		go func() {
-			for j := 0; j < numCreates; j++ {
-				create, err := cli.Transact(context.Background(), &pbtransactor.TransactParam{
-					InputAccount: inputAccount(i),
-					Address:      nil,
-					Data:         test.Bytecode_strange_loop,
-					Value:        0,
-					Fee:          2,
-					GasLimit:     10000,
-				})
-				if assert.NoError(t, err) {
-					assert.True(t, create.CreatesContract)
-				}
-			}
-			wg.Done()
-		}()
-	}
-	wg.Wait()
-
-	require.Equal(t, numGoroutines*numCreates, <-countCh)
-}
-
-func BenchmarkTransactCreateContract(b *testing.B) {
-	cli := newClient(b)
-	for i := 0; i < b.N; i++ {
-		create, err := cli.Transact(context.Background(), &pbtransactor.TransactParam{
-			InputAccount: inputAccount(i),
-			Address:      nil,
-			Data:         test.Bytecode_strange_loop,
-			Value:        0,
-			Fee:          2,
-			GasLimit:     10000,
-		})
-		require.NoError(b, err)
-		assert.True(b, create.CreatesContract)
-	}
-}
-
-func TestTransactAndHold(t *testing.T) {
-	cli := newClient(t)
-	numGoroutines := 5
-	numRuns := 2
-	countCh := test.CommittedTxCount(t, kern.Emitter)
-	for i := 0; i < numGoroutines; i++ {
-		for j := 0; j < numRuns; j++ {
-			create := test.CreateContract(t, cli, inputAccount(i))
-			call := test.CallContract(t, cli, inputAccount(i), create.CallData.Callee)
-			depth := binary.Uint64FromWord256(binary.LeftPadWord256(call.Return))
-			// Would give 23 if taken from wrong frame
-			assert.Equal(t, 18, int(depth))
-		}
-	}
-	require.Equal(t, numGoroutines*numRuns*2, <-countCh)
-}
-
-func TestSend(t *testing.T) {
-	cli := newClient(t)
-	numSends := 1000
-	countCh := test.CommittedTxCount(t, kern.Emitter)
-	for i := 0; i < numSends; i++ {
-		send, err := cli.Send(context.Background(), &pbtransactor.SendParam{
-			InputAccount: inputAccount(i),
-			Amount:       2003,
-			ToAddress:    privateAccounts[3].Address().Bytes(),
-		})
-		require.NoError(t, err)
-		assert.Equal(t, false, send.CreatesContract)
-	}
-	require.Equal(t, numSends, <-countCh)
-}
-
-func TestSendAndHold(t *testing.T) {
-	cli := newClient(t)
-	for i := 0; i < 2; i++ {
-		send, err := cli.SendAndHold(context.Background(), &pbtransactor.SendParam{
-			InputAccount: inputAccount(i),
-			Amount:       2003,
-			ToAddress:    privateAccounts[3].Address().Bytes(),
-		})
-		require.NoError(t, err)
-		assert.Equal(t, false, send.CreatesContract)
-	}
-}
-
-// Helpers
-func newClient(t testing.TB) pbtransactor.TransactorClient {
-	conn, err := grpc.Dial(rpc.DefaultGRPCConfig().ListenAddress, grpc.WithInsecure())
-	require.NoError(t, err)
-	return pbtransactor.NewTransactorClient(conn)
-}
-
-var inputPrivateKey = privateAccounts[0].PrivateKey().RawBytes()
-var inputAddress = privateAccounts[0].Address().Bytes()
-
-func inputAccount(i int) *pbtransactor.InputAccount {
-	ia := new(pbtransactor.InputAccount)
-	if i%2 == 0 {
-		ia.PrivateKey = inputPrivateKey
-	} else {
-		ia.Address = inputAddress
-	}
-	return ia
-}
diff --git a/rpc/rpctransactor/transactor_server.go b/rpc/rpctransactor/transactor_server.go
deleted file mode 100644
index aeed1c4b011a96604d073c34609370e41543f513..0000000000000000000000000000000000000000
--- a/rpc/rpctransactor/transactor_server.go
+++ /dev/null
@@ -1,190 +0,0 @@
-package rpctransactor
-
-import (
-	acm "github.com/hyperledger/burrow/account"
-	"github.com/hyperledger/burrow/account/state"
-	"github.com/hyperledger/burrow/crypto"
-	"github.com/hyperledger/burrow/execution"
-	"github.com/hyperledger/burrow/execution/events/pbevents"
-	"github.com/hyperledger/burrow/execution/pbtransactor"
-	"github.com/hyperledger/burrow/txs"
-	"golang.org/x/net/context"
-)
-
-type transactorServer struct {
-	transactor *execution.Transactor
-	accounts   *execution.Accounts
-	txCodec    txs.Codec
-	reader     state.Reader
-}
-
-func NewTransactorServer(transactor *execution.Transactor, accounts *execution.Accounts, reader state.Reader,
-	txCodec txs.Codec) pbtransactor.TransactorServer {
-	return &transactorServer{
-		transactor: transactor,
-		accounts:   accounts,
-		reader:     reader,
-		txCodec:    txCodec,
-	}
-}
-
-func (ts *transactorServer) BroadcastTx(ctx context.Context, param *pbtransactor.TxParam) (*pbtransactor.TxReceipt, error) {
-	receipt, err := ts.transactor.BroadcastTxRaw(param.GetTx())
-	if err != nil {
-		return nil, err
-	}
-	return txReceipt(receipt), nil
-}
-
-func (ts *transactorServer) Call(ctx context.Context, param *pbtransactor.CallParam) (*pbtransactor.CallResult, error) {
-	fromAddress, err := crypto.AddressFromBytes(param.GetFrom())
-	if err != nil {
-		return nil, err
-	}
-	address, err := crypto.AddressFromBytes(param.GetAddress())
-	if err != nil {
-		return nil, err
-	}
-	call, err := ts.transactor.Call(ts.reader, fromAddress, address, param.GetData())
-	return &pbtransactor.CallResult{
-		Return:  call.Return,
-		GasUsed: call.GasUsed,
-	}, nil
-}
-
-func (ts *transactorServer) CallCode(ctx context.Context, param *pbtransactor.CallCodeParam) (*pbtransactor.CallResult, error) {
-	fromAddress, err := crypto.AddressFromBytes(param.GetFrom())
-	if err != nil {
-		return nil, err
-	}
-	call, err := ts.transactor.CallCode(ts.reader, fromAddress, param.GetCode(), param.GetData())
-	return &pbtransactor.CallResult{
-		Return:  call.Return,
-		GasUsed: call.GasUsed,
-	}, nil
-}
-
-func (ts *transactorServer) Transact(ctx context.Context, param *pbtransactor.TransactParam) (*pbtransactor.TxReceipt, error) {
-	inputAccount, err := ts.inputAccount(param.GetInputAccount())
-	if err != nil {
-		return nil, err
-	}
-	address, err := crypto.MaybeAddressFromBytes(param.GetAddress())
-	if err != nil {
-		return nil, err
-	}
-	receipt, err := ts.transactor.Transact(inputAccount, address, param.GetData(), param.GetGasLimit(), param.GetValue(),
-		param.GetFee())
-	if err != nil {
-		return nil, err
-	}
-	return txReceipt(receipt), nil
-}
-
-func (ts *transactorServer) TransactAndHold(ctx context.Context, param *pbtransactor.TransactParam) (*pbevents.EventDataCall, error) {
-	inputAccount, err := ts.inputAccount(param.GetInputAccount())
-	if err != nil {
-		return nil, err
-	}
-	address, err := crypto.MaybeAddressFromBytes(param.GetAddress())
-	if err != nil {
-		return nil, err
-	}
-	edt, err := ts.transactor.TransactAndHold(ctx, inputAccount, address, param.GetData(), param.GetGasLimit(),
-		param.GetValue(), param.GetFee())
-	if err != nil {
-		return nil, err
-	}
-	return pbevents.GetEventDataCall(edt), nil
-}
-
-func (ts *transactorServer) Send(ctx context.Context, param *pbtransactor.SendParam) (*pbtransactor.TxReceipt, error) {
-	inputAccount, err := ts.inputAccount(param.GetInputAccount())
-	if err != nil {
-		return nil, err
-	}
-	toAddress, err := crypto.AddressFromBytes(param.GetToAddress())
-	if err != nil {
-		return nil, err
-	}
-	receipt, err := ts.transactor.Send(inputAccount, toAddress, param.GetAmount())
-	if err != nil {
-		return nil, err
-	}
-	return txReceipt(receipt), nil
-}
-
-func (ts *transactorServer) SendAndHold(ctx context.Context, param *pbtransactor.SendParam) (*pbtransactor.TxReceipt, error) {
-	inputAccount, err := ts.inputAccount(param.GetInputAccount())
-	if err != nil {
-		return nil, err
-	}
-	toAddress, err := crypto.AddressFromBytes(param.GetToAddress())
-	if err != nil {
-		return nil, err
-	}
-	receipt, err := ts.transactor.SendAndHold(ctx, inputAccount, toAddress, param.GetAmount())
-	if err != nil {
-		return nil, err
-	}
-	return txReceipt(receipt), nil
-}
-
-func (ts *transactorServer) SignTx(ctx context.Context, param *pbtransactor.SignTxParam) (*pbtransactor.SignedTx, error) {
-	txEnv, err := ts.txCodec.DecodeTx(param.GetTx())
-	if err != nil {
-		return nil, err
-	}
-	signers, err := signersFromPrivateAccounts(param.GetPrivateAccounts())
-	if err != nil {
-		return nil, err
-	}
-	txEnvSigned, err := ts.transactor.SignTx(txEnv, signers)
-	if err != nil {
-		return nil, err
-	}
-	bs, err := ts.txCodec.EncodeTx(txEnvSigned)
-	if err != nil {
-		return nil, err
-	}
-	return &pbtransactor.SignedTx{
-		Tx: bs,
-	}, nil
-}
-
-func (ts *transactorServer) inputAccount(inAcc *pbtransactor.InputAccount) (*execution.SequentialSigningAccount, error) {
-	return ts.accounts.GetSequentialSigningAccount(inAcc.GetAddress(), inAcc.GetPrivateKey())
-}
-
-func txReceipt(receipt *txs.Receipt) *pbtransactor.TxReceipt {
-	return &pbtransactor.TxReceipt{
-		ContractAddress: receipt.ContractAddress.Bytes(),
-		CreatesContract: receipt.CreatesContract,
-		TxHash:          receipt.TxHash,
-	}
-}
-
-func signersFromPrivateAccounts(privateAccounts []*pbtransactor.PrivateAccount) ([]acm.AddressableSigner, error) {
-	signers := make([]acm.AddressableSigner, len(privateAccounts))
-	var err error
-	for i, pa := range privateAccounts {
-		signers[i], err = privateAccount(pa)
-		if err != nil {
-			return nil, err
-		}
-	}
-	return signers, nil
-}
-
-func privateAccount(privateAccount *pbtransactor.PrivateAccount) (acm.PrivateAccount, error) {
-	privateKey, err := crypto.PrivateKeyFromRawBytes(privateAccount.PrivateKey, crypto.CurveTypeEd25519)
-	if err != nil {
-		return nil, err
-	}
-	publicKey := privateKey.GetPublicKey()
-	return acm.ConcretePrivateAccount{
-		Address:    publicKey.Address(),
-		PrivateKey: privateKey,
-		PublicKey:  publicKey,
-	}.PrivateAccount(), nil
-}
diff --git a/rpc/service.go b/rpc/service.go
index 0863a65a4e4678ecd2d9aff64a25ad37d2a10422..098dd150386500ea623adbdb9cf31aff8a2d27a8 100644
--- a/rpc/service.go
+++ b/rpc/service.go
@@ -15,73 +15,51 @@
 package rpc
 
 import (
-	"context"
+	"encoding/json"
 	"fmt"
-
 	"time"
 
-	"encoding/json"
-
-	acm "github.com/hyperledger/burrow/account"
-	"github.com/hyperledger/burrow/account/state"
+	"github.com/hyperledger/burrow/acm"
+	"github.com/hyperledger/burrow/acm/state"
 	"github.com/hyperledger/burrow/binary"
 	bcm "github.com/hyperledger/burrow/blockchain"
 	"github.com/hyperledger/burrow/consensus/tendermint/query"
 	"github.com/hyperledger/burrow/crypto"
-	"github.com/hyperledger/burrow/event"
 	"github.com/hyperledger/burrow/execution"
 	"github.com/hyperledger/burrow/execution/names"
-	"github.com/hyperledger/burrow/keys"
 	"github.com/hyperledger/burrow/logging"
 	"github.com/hyperledger/burrow/logging/structure"
 	"github.com/hyperledger/burrow/permission"
 	"github.com/hyperledger/burrow/project"
 	"github.com/hyperledger/burrow/txs"
-	tm_types "github.com/tendermint/tendermint/types"
-	"github.com/tmthrgd/go-hex"
+	tmTypes "github.com/tendermint/tendermint/types"
 )
 
 // Magic! Should probably be configurable, but not shouldn't be so huge we
 // end up DoSing ourselves.
 const MaxBlockLookback = 1000
-const AccountsRingMutexCount = 100
 
 // Base service that provides implementation for all underlying RPC methods
 type Service struct {
-	ctx             context.Context
-	state           state.IterableReader
-	nameReg         names.IterableReader
-	mempoolAccounts *execution.Accounts
-	subscribable    event.Subscribable
-	blockchain      bcm.BlockchainInfo
-	transactor      *execution.Transactor
-	nodeView        *query.NodeView
-	logger          *logging.Logger
+	state      state.IterableReader
+	nameReg    names.IterableReader
+	blockchain bcm.BlockchainInfo
+	transactor *execution.Transactor
+	nodeView   *query.NodeView
+	logger     *logging.Logger
 }
 
-func NewService(ctx context.Context, state state.IterableReader, nameReg names.IterableReader,
-	checker state.Reader, subscribable event.Subscribable, blockchain bcm.BlockchainInfo, keyClient keys.KeyClient,
-	transactor *execution.Transactor, nodeView *query.NodeView, logger *logging.Logger) *Service {
-
-	return &Service{
-		ctx:             ctx,
-		state:           state,
-		mempoolAccounts: execution.NewAccounts(checker, keyClient, AccountsRingMutexCount),
-		nameReg:         nameReg,
-		subscribable:    subscribable,
-		blockchain:      blockchain,
-		transactor:      transactor,
-		nodeView:        nodeView,
-		logger:          logger.With(structure.ComponentKey, "Service"),
-	}
-}
+func NewService(state state.IterableReader, nameReg names.IterableReader,
+	blockchain bcm.BlockchainInfo, transactor *execution.Transactor, nodeView *query.NodeView,
+	logger *logging.Logger) *Service {
 
-// Provides a sub-service with only the subscriptions methods
-func NewSubscribableService(subscribable event.Subscribable, logger *logging.Logger) *Service {
 	return &Service{
-		ctx:          context.Background(),
-		subscribable: subscribable,
-		logger:       logger.With(structure.ComponentKey, "Service"),
+		state:      state,
+		nameReg:    nameReg,
+		blockchain: blockchain,
+		transactor: transactor,
+		nodeView:   nodeView,
+		logger:     logger.With(structure.ComponentKey, "Service"),
 	}
 }
 
@@ -91,18 +69,6 @@ func (s *Service) Transactor() *execution.Transactor {
 	return s.transactor
 }
 
-// By providing certain methods on the Transactor (such as Transact, Send, etc) with the (non-final) MempoolAccounts
-// rather than the committed (final) Accounts state the transactor can assign a sequence number based on all of the txs
-// it has seen since the last block - provided these transactions are successfully committed (via DeliverTx) then
-// subsequent transactions will have valid sequence numbers. This allows Burrow to coordinate sequencing and signing
-// for a key it holds or is provided - it is down to the key-holder to manage the mutual information between transactions
-// concurrent within a new block window.
-
-// Get pending account state residing in the mempool
-func (s *Service) MempoolAccounts() *execution.Accounts {
-	return s.mempoolAccounts
-}
-
 func (s *Service) State() state.Reader {
 	return s.state
 }
@@ -111,6 +77,10 @@ func (s *Service) BlockchainInfo() bcm.BlockchainInfo {
 	return s.blockchain
 }
 
+func (s *Service) ChainID() string {
+	return s.blockchain.ChainID()
+}
+
 func (s *Service) ListUnconfirmedTxs(maxTxs int) (*ResultListUnconfirmedTxs, error) {
 	// Get all transactions for now
 	transactions, err := s.nodeView.MempoolTransactions(maxTxs)
@@ -127,42 +97,10 @@ func (s *Service) ListUnconfirmedTxs(maxTxs int) (*ResultListUnconfirmedTxs, err
 	}, nil
 }
 
-func (s *Service) Subscribe(ctx context.Context, subscriptionID string, eventID string,
-	callback func(resultEvent *ResultEvent) (stop bool)) error {
-
-	queryBuilder := event.QueryForEventID(eventID)
-	s.logger.InfoMsg("Subscribing to events",
-		"query", queryBuilder.String(),
-		"subscription_id", subscriptionID,
-		"event_id", eventID)
-	return event.SubscribeCallback(ctx, s.subscribable, subscriptionID, queryBuilder,
-		func(message interface{}) (stop bool) {
-			resultEvent, err := NewResultEvent(eventID, message)
-			if err != nil {
-				s.logger.InfoMsg("Received event that could not be mapped to ResultEvent",
-					structure.ErrorKey, err,
-					"subscription_id", subscriptionID,
-					"event_id", eventID)
-				return false
-			}
-			return callback(resultEvent)
-		})
-}
-
-func (s *Service) Unsubscribe(ctx context.Context, subscriptionID string) error {
-	s.logger.InfoMsg("Unsubscribing from events",
-		"subscription_id", subscriptionID)
-	err := s.subscribable.UnsubscribeAll(ctx, subscriptionID)
-	if err != nil {
-		return fmt.Errorf("error unsubscribing from event with subscriptionID '%s': %v", subscriptionID, err)
-	}
-	return nil
-}
-
 func (s *Service) Status() (*ResultStatus, error) {
 	latestHeight := s.blockchain.LastBlockHeight()
 	var (
-		latestBlockMeta *tm_types.BlockMeta
+		latestBlockMeta *tmTypes.BlockMeta
 		latestBlockHash []byte
 		latestBlockTime int64
 	)
@@ -287,7 +225,6 @@ func (s *Service) DumpStorage(address crypto.Address) (*ResultDumpStorage, error
 		return
 	})
 	return &ResultDumpStorage{
-		StorageRoot:  account.StorageRoot(),
 		StorageItems: storageItems,
 	}, nil
 }
@@ -315,7 +252,6 @@ func (s *Service) GetAccountHumanReadable(address crypto.Address) (*ResultGetAcc
 			Sequence:    acc.Sequence(),
 			Balance:     acc.Balance(),
 			Code:        tokens,
-			StorageRoot: hex.EncodeUpperToString(acc.StorageRoot()),
 			Permissions: perms,
 			Roles:       acc.Permissions().Roles,
 		},
@@ -324,7 +260,7 @@ func (s *Service) GetAccountHumanReadable(address crypto.Address) (*ResultGetAcc
 
 // Name registry
 func (s *Service) GetName(name string) (*ResultGetName, error) {
-	entry, err := s.nameReg.GetNameEntry(name)
+	entry, err := s.nameReg.GetName(name)
 	if err != nil {
 		return nil, err
 	}
@@ -336,7 +272,7 @@ func (s *Service) GetName(name string) (*ResultGetName, error) {
 
 func (s *Service) ListNames(predicate func(*names.Entry) bool) (*ResultListNames, error) {
 	var nms []*names.Entry
-	s.nameReg.IterateNameEntries(func(entry *names.Entry) (stop bool) {
+	s.nameReg.IterateNames(func(entry *names.Entry) (stop bool) {
 		if predicate(entry) {
 			nms = append(nms, entry)
 		}
@@ -373,7 +309,7 @@ func (s *Service) ListBlocks(minHeight, maxHeight uint64) (*ResultListBlocks, er
 		minHeight = maxHeight - MaxBlockLookback
 	}
 
-	var blockMetas []*tm_types.BlockMeta
+	var blockMetas []*tmTypes.BlockMeta
 	for height := maxHeight; height >= minHeight; height-- {
 		blockMeta := s.nodeView.BlockStore().LoadBlockMeta(int64(height))
 		blockMetas = append(blockMetas, blockMeta)
@@ -419,7 +355,7 @@ func (s *Service) GeneratePrivateAccount() (*ResultGeneratePrivateAccount, error
 		return nil, err
 	}
 	return &ResultGeneratePrivateAccount{
-		PrivateAccount: acm.AsConcretePrivateAccount(privateAccount),
+		PrivateAccount: privateAccount.ConcretePrivateAccount(),
 	}, nil
 }
 
diff --git a/rpc/subscriptions.go b/rpc/subscriptions.go
deleted file mode 100644
index 35808890bcf78067304934bd41c0d7015bd82fda..0000000000000000000000000000000000000000
--- a/rpc/subscriptions.go
+++ /dev/null
@@ -1,144 +0,0 @@
-// Copyright 2017 Monax Industries Limited
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//    http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package rpc
-
-import (
-	"context"
-	"fmt"
-	"sync"
-	"time"
-
-	"github.com/hyperledger/burrow/event"
-)
-
-var (
-	reaperPeriod    = 5 * time.Second
-	reaperThreshold = 20 * time.Second
-)
-
-// Catches events that callers subscribe to and adds them to an array ready to be polled.
-type Subscriptions struct {
-	mtx     *sync.RWMutex
-	service *Service
-	subs    map[string]*SubscriptionsCache
-	reap    bool
-}
-
-type SubscriptionsCache struct {
-	mtx    *sync.Mutex
-	events []interface{}
-	ts     time.Time
-	subID  string
-}
-
-func NewSubscriptions(service *Service) *Subscriptions {
-	es := &Subscriptions{
-		mtx:     &sync.RWMutex{},
-		service: service,
-		subs:    make(map[string]*SubscriptionsCache),
-		reap:    true,
-	}
-	if es.reap {
-		go reap(es)
-	}
-	return es
-}
-
-func newSubscriptionsCache(subID string) *SubscriptionsCache {
-	return &SubscriptionsCache{
-		subID:  subID,
-		mtx:    &sync.Mutex{},
-		events: make([]interface{}, 0),
-		ts:     time.Now(),
-	}
-}
-
-func (subsCache *SubscriptionsCache) poll() []interface{} {
-	subsCache.mtx.Lock()
-	defer subsCache.mtx.Unlock()
-	var evts []interface{}
-	if len(subsCache.events) > 0 {
-		evts = subsCache.events
-		subsCache.events = []interface{}{}
-	} else {
-		evts = []interface{}{}
-	}
-	subsCache.ts = time.Now()
-	return evts
-}
-
-// Remove old subscriptions not recently polled
-func reap(es *Subscriptions) {
-	for {
-		time.Sleep(reaperPeriod)
-		for id, sub := range es.subs {
-			if time.Since(sub.ts) > reaperThreshold {
-				es.mtx.Lock()
-				delete(es.subs, id)
-				es.service.Unsubscribe(context.Background(), id)
-				es.mtx.Unlock()
-			}
-		}
-	}
-}
-
-// Add a subscription and return the generated id. Note event dispatcher
-// has to call func which involves acquiring a mutex lock, so might be
-// a delay - though a conflict is practically impossible, and if it does
-// happen it's for an insignificant amount of time (the time it takes to
-// carry out SubscriptionsCache.poll() ).
-func (subs *Subscriptions) Add(eventId string) (string, error) {
-	subID, err := event.GenerateSubscriptionID()
-	if err != nil {
-		return "", err
-	}
-	subs.mtx.Lock()
-	defer subs.mtx.Unlock()
-	cache := newSubscriptionsCache(subID)
-	subs.subs[subID] = cache
-
-	err = subs.service.Subscribe(context.Background(), subID, eventId, func(resultEvent *ResultEvent) (stop bool) {
-		cache.mtx.Lock()
-		defer cache.mtx.Unlock()
-		cache.events = append(cache.events, resultEvent)
-		return
-	})
-	if err != nil {
-		return "", err
-	}
-
-	return subID, nil
-}
-
-func (subs *Subscriptions) Poll(subId string) ([]interface{}, error) {
-	subs.mtx.RLock()
-	defer subs.mtx.RUnlock()
-	sub, ok := subs.subs[subId]
-	if !ok {
-		return nil, fmt.Errorf("Subscription not active. ID: " + subId)
-	}
-	return sub.poll(), nil
-}
-
-func (subs *Subscriptions) Remove(subId string) error {
-	subs.mtx.Lock()
-	defer subs.mtx.Unlock()
-	_, ok := subs.subs[subId]
-	if !ok {
-		return fmt.Errorf("Subscription not active. ID: " + subId)
-	}
-	delete(subs.subs, subId)
-	return nil
-}
diff --git a/rpc/subscriptions_test.go b/rpc/subscriptions_test.go
deleted file mode 100644
index fa67f6cf706636ccfd40b0abfb9f6b468a00c02a..0000000000000000000000000000000000000000
--- a/rpc/subscriptions_test.go
+++ /dev/null
@@ -1,166 +0,0 @@
-// Copyright 2017 Monax Industries Limited
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//    http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package rpc
-
-import (
-	"encoding/hex"
-	"fmt"
-	"testing"
-	"time"
-
-	"github.com/hyperledger/burrow/event"
-	"github.com/hyperledger/burrow/logging"
-	"github.com/stretchr/testify/assert"
-)
-
-var mockInterval = 20 * time.Millisecond
-
-// Test that event subscriptions can be added manually and then automatically reaped.
-func TestSubReaping(t *testing.T) {
-	NUM_SUBS := 100
-	reaperThreshold = 200 * time.Millisecond
-	reaperPeriod = 100 * time.Millisecond
-
-	mee := event.NewEmitter(logging.NewNoopLogger())
-	eSubs := NewSubscriptions(NewSubscribableService(mee, logging.NewNoopLogger()))
-	doneChan := make(chan error)
-	go func() {
-		for i := 0; i < NUM_SUBS; i++ {
-			time.Sleep(2 * time.Millisecond)
-			go func() {
-				id, err := eSubs.Add("WeirdEvent")
-				if err != nil {
-					doneChan <- err
-					return
-				}
-				if len(id) != 64 {
-					doneChan <- fmt.Errorf("Id not of length 64")
-					return
-				}
-				_, err2 := hex.DecodeString(id)
-				if err2 != nil {
-					doneChan <- err2
-				}
-
-				doneChan <- nil
-			}()
-		}
-	}()
-	k := 0
-	for k < NUM_SUBS {
-		err := <-doneChan
-		assert.NoError(t, err)
-		k++
-	}
-	time.Sleep(1100 * time.Millisecond)
-
-	assert.Len(t, eSubs.subs, 0)
-	t.Logf("Added %d subs that were all automatically reaped.", NUM_SUBS)
-}
-
-// Test that event subscriptions can be added and removed manually.
-func TestSubManualClose(t *testing.T) {
-	NUM_SUBS := 100
-	// Keep the reaper out of this.
-	reaperThreshold = 10000 * time.Millisecond
-	reaperPeriod = 10000 * time.Millisecond
-
-	mee := event.NewEmitter(logging.NewNoopLogger())
-	eSubs := NewSubscriptions(NewSubscribableService(mee, logging.NewNoopLogger()))
-	doneChan := make(chan error)
-	go func() {
-		for i := 0; i < NUM_SUBS; i++ {
-			time.Sleep(2 * time.Millisecond)
-			go func() {
-				id, err := eSubs.Add("WeirdEvent")
-				if err != nil {
-					doneChan <- err
-					return
-				}
-				if len(id) != 64 {
-					doneChan <- fmt.Errorf("Id not of length 64")
-					return
-				}
-				_, err2 := hex.DecodeString(id)
-				if err2 != nil {
-					doneChan <- err2
-				}
-				time.Sleep(100 * time.Millisecond)
-				err3 := eSubs.Remove(id)
-				if err3 != nil {
-					doneChan <- err3
-				}
-				doneChan <- nil
-			}()
-		}
-	}()
-	k := 0
-	for k < NUM_SUBS {
-		err := <-doneChan
-		assert.NoError(t, err)
-		k++
-	}
-
-	assert.Len(t, eSubs.subs, 0)
-	t.Logf("Added %d subs that were all closed down by unsubscribing.", NUM_SUBS)
-}
-
-// Test that the system doesn't fail under high pressure.
-func TestSubFlooding(t *testing.T) {
-	NUM_SUBS := 100
-	// Keep the reaper out of this.
-	reaperThreshold = 10000 * time.Millisecond
-	reaperPeriod = 10000 * time.Millisecond
-	// Crank it up. Now pressure is 10 times higher on each sub.
-	mockInterval = 1 * time.Millisecond
-	mee := event.NewEmitter(logging.NewNoopLogger())
-	eSubs := NewSubscriptions(NewSubscribableService(mee, logging.NewNoopLogger()))
-	doneChan := make(chan error)
-	go func() {
-		for i := 0; i < NUM_SUBS; i++ {
-			time.Sleep(1 * time.Millisecond)
-			go func() {
-				id, err := eSubs.Add("WeirdEvent")
-				if err != nil {
-					doneChan <- err
-					return
-				}
-				if len(id) != 64 {
-					doneChan <- fmt.Errorf("Id not of length 64")
-					return
-				}
-				_, err2 := hex.DecodeString(id)
-				if err2 != nil {
-					doneChan <- err2
-				}
-				time.Sleep(1000 * time.Millisecond)
-				err3 := eSubs.Remove(id)
-				if err3 != nil {
-					doneChan <- err3
-				}
-				doneChan <- nil
-			}()
-		}
-	}()
-	k := 0
-	for k < NUM_SUBS {
-		err := <-doneChan
-		assert.NoError(t, err)
-		k++
-	}
-
-	assert.Len(t, eSubs.subs, 0)
-	t.Logf("Added %d subs that all received 1000 events each. They were all closed down by unsubscribing.", NUM_SUBS)
-}
diff --git a/rpc/test/helpers.go b/rpc/test/helpers.go
deleted file mode 100644
index 0e7d934f526806819c3aa14e648c3aa963ea1046..0000000000000000000000000000000000000000
--- a/rpc/test/helpers.go
+++ /dev/null
@@ -1,99 +0,0 @@
-package test
-
-import (
-	"context"
-	"testing"
-
-	"github.com/hyperledger/burrow/consensus/tendermint"
-	"github.com/hyperledger/burrow/event"
-	"github.com/hyperledger/burrow/execution/events/pbevents"
-	"github.com/hyperledger/burrow/execution/evm/abi"
-	"github.com/hyperledger/burrow/execution/pbtransactor"
-	"github.com/hyperledger/burrow/rpc"
-	"github.com/stretchr/testify/assert"
-	"github.com/stretchr/testify/require"
-	"google.golang.org/grpc"
-)
-
-// Recursive call count for UpsieDownsie() function call from strange_loop.sol
-// Equals initial call, then depth from 17 -> 34, one for the bounce, then depth from 34 -> 23,
-// so... (I didn't say it had to make sense):
-const UpsieDownsieCallCount = 1 + (34 - 17) + 1 + (34 - 23)
-
-// Helpers
-func NewTransactorClient(t testing.TB) pbtransactor.TransactorClient {
-	conn, err := grpc.Dial(rpc.DefaultGRPCConfig().ListenAddress, grpc.WithInsecure())
-	require.NoError(t, err)
-	return pbtransactor.NewTransactorClient(conn)
-}
-
-func NewExecutionEventsClient(t testing.TB) pbevents.ExecutionEventsClient {
-	conn, err := grpc.Dial(rpc.DefaultGRPCConfig().ListenAddress, grpc.WithInsecure())
-	require.NoError(t, err)
-	return pbevents.NewExecutionEventsClient(conn)
-}
-
-func NewEventsClient(t testing.TB) pbevents.EventsClient {
-	conn, err := grpc.Dial(rpc.DefaultGRPCConfig().ListenAddress, grpc.WithInsecure())
-	require.NoError(t, err)
-	return pbevents.NewEventsClient(conn)
-}
-
-func CommittedTxCount(t *testing.T, em event.Emitter) chan int {
-	var numTxs int64
-	emptyBlocks := 0
-	maxEmptyBlocks := 2
-	outCh := make(chan int)
-	ctx := context.Background()
-	ch, err := tendermint.SubscribeNewBlock(ctx, em)
-	require.NoError(t, err)
-
-	go func() {
-		for ed := range ch {
-			if ed.Block.NumTxs == 0 {
-				emptyBlocks++
-			} else {
-				emptyBlocks = 0
-			}
-			if emptyBlocks > maxEmptyBlocks {
-				break
-			}
-			numTxs += ed.Block.NumTxs
-			t.Logf("Total TXs committed at block %v: %v (+%v)\n", ed.Block.Height, numTxs, ed.Block.NumTxs)
-		}
-		outCh <- int(numTxs)
-	}()
-	return outCh
-}
-
-func CreateContract(t testing.TB, cli pbtransactor.TransactorClient,
-	inputAccount *pbtransactor.InputAccount) *pbevents.EventDataCall {
-
-	create, err := cli.TransactAndHold(context.Background(), &pbtransactor.TransactParam{
-		InputAccount: inputAccount,
-		Address:      nil,
-		Data:         Bytecode_strange_loop,
-		Value:        0,
-		Fee:          2,
-		GasLimit:     10000,
-	})
-	require.NoError(t, err)
-	assert.Equal(t, uint64(0), create.StackDepth)
-	return create
-}
-
-func CallContract(t testing.TB, cli pbtransactor.TransactorClient,
-	inputAccount *pbtransactor.InputAccount, contractAddress []byte) (call *pbevents.EventDataCall) {
-
-	functionID := abi.FunctionID("UpsieDownsie()")
-	call, err := cli.TransactAndHold(context.Background(), &pbtransactor.TransactParam{
-		InputAccount: inputAccount,
-		Address:      contractAddress,
-		Data:         functionID[:],
-		Value:        0,
-		Fee:          2,
-		GasLimit:     10000,
-	})
-	require.NoError(t, err)
-	return call
-}
diff --git a/rpc/tm/client/websocket_client.go b/rpc/tm/client/websocket_client.go
deleted file mode 100644
index d07f05f1d2dbfd586f628769313c10d220fffb2d..0000000000000000000000000000000000000000
--- a/rpc/tm/client/websocket_client.go
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright 2017 Monax Industries Limited
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//    http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package client
-
-import (
-	"context"
-
-	"github.com/hyperledger/burrow/rpc/lib/types"
-	"github.com/hyperledger/burrow/rpc/tm"
-)
-
-type WebsocketClient interface {
-	Send(ctx context.Context, request types.RPCRequest) error
-}
-
-const SubscribeRequestID = "Subscribe"
-const UnsubscribeRequestID = "Unsubscribe"
-
-func EventResponseID(eventID string) string {
-	return tm.EventResponseID(SubscribeRequestID, eventID)
-}
-
-func Subscribe(wsc WebsocketClient, eventID string) error {
-	req, err := types.MapToRequest(SubscribeRequestID,
-		"subscribe", map[string]interface{}{"eventID": eventID})
-	if err != nil {
-		return err
-	}
-	return wsc.Send(context.Background(), req)
-}
-
-func Unsubscribe(websocketClient WebsocketClient, subscriptionID string) error {
-	req, err := types.MapToRequest(UnsubscribeRequestID,
-		"unsubscribe", map[string]interface{}{"subscriptionID": subscriptionID})
-	if err != nil {
-		return err
-	}
-	return websocketClient.Send(context.Background(), req)
-}
diff --git a/rpc/tm/integration/server_test.go b/rpc/tm/integration/server_test.go
deleted file mode 100644
index b30a66ec13da1107732b75f8d97337f858827e90..0000000000000000000000000000000000000000
--- a/rpc/tm/integration/server_test.go
+++ /dev/null
@@ -1,398 +0,0 @@
-// +build integration
-
-// Space above here matters
-// Copyright 2017 Monax Industries Limited
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//    http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package integration
-
-import (
-	"bytes"
-	"testing"
-	"time"
-
-	"fmt"
-	"strings"
-
-	"github.com/hyperledger/burrow/binary"
-	exe_events "github.com/hyperledger/burrow/execution/events"
-	"github.com/hyperledger/burrow/execution/names"
-	"github.com/hyperledger/burrow/rpc"
-	tm_client "github.com/hyperledger/burrow/rpc/tm/client"
-	"github.com/hyperledger/burrow/txs"
-	"github.com/hyperledger/burrow/txs/payload"
-	"github.com/stretchr/testify/assert"
-	"github.com/stretchr/testify/require"
-	"github.com/tendermint/tendermint/consensus/types"
-	"golang.org/x/crypto/ripemd160"
-)
-
-func testWithAllClients(t *testing.T, testFunction func(*testing.T, string, tm_client.RPCClient)) {
-	for clientName, client := range clients {
-		testFunction(t, clientName, client)
-	}
-}
-
-//--------------------------------------------------------------------------------
-func TestStatus(t *testing.T) {
-	testWithAllClients(t, func(t *testing.T, clientName string, client tm_client.RPCClient) {
-		resp, err := tm_client.Status(client)
-		assert.NoError(t, err)
-		assert.Equal(t, genesisDoc.ChainID(), resp.NodeInfo.Network, "ChainID should match NodeInfo.Network")
-	})
-}
-
-func TestBroadcastTx(t *testing.T) {
-	testWithAllClients(t, func(t *testing.T, clientName string, client tm_client.RPCClient) {
-		// Avoid duplicate Tx in mempool
-		amt := hashString(clientName) % 1000
-		toAddr := privateAccounts[1].Address()
-		txEnv := makeDefaultSendTxSigned(t, client, toAddr, amt)
-		receipt, err := broadcastTxAndWait(t, client, txEnv)
-		require.NoError(t, err)
-		assert.False(t, receipt.CreatesContract, "This tx should not create a contract")
-		assert.NotEmpty(t, receipt.TxHash, "Failed to compute tx hash")
-
-		hasher := ripemd160.New()
-		txSignBytes, err := txEnv.Tx.SignBytes()
-		require.NoError(t, err)
-		hasher.Write(txSignBytes)
-		txHashExpected := hasher.Sum(nil)
-
-		if bytes.Compare(receipt.TxHash, txHashExpected) != 0 {
-			t.Fatalf("The receipt hash '%x' does not equal the ripemd160 hash of the "+
-				"transaction signed bytes calculated in the test: '%x'",
-				receipt.TxHash, txHashExpected)
-		}
-	})
-}
-
-func TestGetAccount(t *testing.T) {
-	if testing.Short() {
-		t.Skip("skipping test in short mode.")
-	}
-	testWithAllClients(t, func(t *testing.T, clientName string, client tm_client.RPCClient) {
-		acc := getAccount(t, client, privateAccounts[0].Address())
-		if acc == nil {
-			t.Fatal("Account was nil")
-		}
-		if acc.Address() != privateAccounts[0].Address() {
-			t.Fatalf("Failed to get correct account. Got %s, expected %s", acc.Address(),
-				privateAccounts[0].Address())
-		}
-	})
-}
-
-func TestGetStorage(t *testing.T) {
-	if testing.Short() {
-		t.Skip("skipping test in short mode.")
-	}
-	testWithAllClients(t, func(t *testing.T, clientName string, client tm_client.RPCClient) {
-		amt, gasLim, fee := uint64(1100), uint64(1000), uint64(1000)
-		code := []byte{0x60, 0x5, 0x60, 0x1, 0x55}
-		// Call with nil address will create a contract
-		tx := makeDefaultCallTx(t, client, nil, code, amt, gasLim, fee)
-		receipt, err := broadcastTxAndWait(t, client, tx)
-		assert.NoError(t, err)
-		assert.Equal(t, true, receipt.CreatesContract, "This transaction should"+
-			" create a contract")
-		assert.NotEqual(t, 0, len(receipt.TxHash), "Receipt should contain a"+
-			" transaction hash")
-		contractAddr := receipt.ContractAddress
-		assert.NotEqual(t, 0, len(contractAddr), "Transactions claims to have"+
-			" created a contract but the contract address is empty")
-
-		v := getStorage(t, client, contractAddr, []byte{0x1})
-		got := binary.LeftPadWord256(v)
-		expected := binary.LeftPadWord256([]byte{0x5})
-		if got.Compare(expected) != 0 {
-			t.Fatalf("Wrong storage value. Got %x, expected %x", got.Bytes(),
-				expected.Bytes())
-		}
-	})
-}
-
-func TestCallCode(t *testing.T) {
-	if testing.Short() {
-		t.Skip("skipping test in short mode.")
-	}
-
-	testWithAllClients(t, func(t *testing.T, clientName string, client tm_client.RPCClient) {
-		// add two integers and return the result
-		code := []byte{0x60, 0x5, 0x60, 0x6, 0x1, 0x60, 0x0, 0x52, 0x60, 0x20, 0x60,
-			0x0, 0xf3}
-		data := []byte{}
-		expected := []byte{0xb}
-		callCode(t, client, privateAccounts[0].Address(), code, data, expected)
-
-		// pass two ints as calldata, add, and return the result
-		code = []byte{0x60, 0x0, 0x35, 0x60, 0x20, 0x35, 0x1, 0x60, 0x0, 0x52, 0x60,
-			0x20, 0x60, 0x0, 0xf3}
-		data = append(binary.LeftPadWord256([]byte{0x5}).Bytes(),
-			binary.LeftPadWord256([]byte{0x6}).Bytes()...)
-		expected = []byte{0xb}
-		callCode(t, client, privateAccounts[0].Address(), code, data, expected)
-	})
-}
-
-func TestCallContract(t *testing.T) {
-	if testing.Short() {
-		t.Skip("skipping test in short mode.")
-	}
-	testWithAllClients(t, func(t *testing.T, clientName string, client tm_client.RPCClient) {
-		// create the contract
-		amt, gasLim, fee := uint64(6969), uint64(1000), uint64(1000)
-		code, _, _ := simpleContract()
-		tx := makeDefaultCallTx(t, client, nil, code, amt, gasLim, fee)
-		receipt, err := broadcastTxAndWait(t, client, tx)
-		assert.NoError(t, err)
-		if err != nil {
-			t.Fatalf("Problem broadcasting transaction: %v", err)
-		}
-		assert.Equal(t, true, receipt.CreatesContract, "This transaction should"+
-			" create a contract")
-		assert.NotEqual(t, 0, len(receipt.TxHash), "Receipt should contain a"+
-			" transaction hash")
-		contractAddr := receipt.ContractAddress
-		assert.NotEqual(t, 0, len(contractAddr), "Transactions claims to have"+
-			" created a contract but the contract address is empty")
-
-		// run a call through the contract
-		data := []byte{}
-		expected := []byte{0xb}
-		callContract(t, client, privateAccounts[0].Address(), contractAddr, data, expected)
-	})
-}
-
-func TestNameReg(t *testing.T) {
-	if testing.Short() {
-		t.Skip("skipping test in short mode.")
-	}
-	wsc := newWSClient()
-	defer stopWSClient(wsc)
-	testWithAllClients(t, func(t *testing.T, clientName string, client tm_client.RPCClient) {
-		names.MinNameRegistrationPeriod = 1
-
-		// register a new name, check if its there
-		// since entries ought to be unique and these run against different clients, we append the client
-		name := "ye_old_domain_name_" + clientName
-		const data = "if not now, when"
-		fee := uint64(1000)
-		numDesiredBlocks := uint64(2)
-		amt := fee + numDesiredBlocks*names.NameByteCostMultiplier*names.NameBlockCostMultiplier*names.NameBaseCost(name, data)
-
-		txEnv := makeDefaultNameTx(t, client, name, data, amt, fee)
-		// verify the name by both using the event and by checking get_name
-		subscribeAndWaitForNext(t, wsc, exe_events.EventStringNameReg(name),
-			func() {
-				broadcastTx(t, client, txEnv)
-			},
-			func(eventID string, resultEvent *rpc.ResultEvent) (bool, error) {
-
-				eventDataTx := resultEvent.Execution.GetTx()
-				assert.NotNil(t, eventDataTx, "could not convert %s to EventDataTx", resultEvent)
-				tx, ok := eventDataTx.Tx.Payload.(*payload.NameTx)
-				if !ok {
-					t.Fatalf("Could not convert %v to *NameTx", eventDataTx)
-				}
-				assert.Equal(t, name, tx.Name)
-				assert.Equal(t, data, tx.Data)
-				return true, nil
-			})
-
-		entry := getNameRegEntry(t, client, name)
-		assert.Equal(t, data, entry.Data)
-		assert.Equal(t, privateAccounts[0].Address(), entry.Owner)
-
-		// update the data as the owner, make sure still there
-		numDesiredBlocks = uint64(5)
-		const updatedData = "these are amongst the things I wish to bestow upon " +
-			"the youth of generations come: a safe supply of honey, and a better " +
-			"money. For what else shall they need"
-		amt = fee + numDesiredBlocks*names.NameByteCostMultiplier*
-			names.NameBlockCostMultiplier*names.NameBaseCost(name, updatedData)
-		txEnv = makeDefaultNameTx(t, client, name, updatedData, amt, fee)
-		broadcastTxAndWait(t, client, txEnv)
-		entry = getNameRegEntry(t, client, name)
-
-		assert.Equal(t, updatedData, entry.Data)
-
-		// try to update as non owner, should fail
-		tx := payload.NewNameTxWithSequence(privateAccounts[1].PublicKey(), name, "never mind", amt, fee,
-			getSequence(t, client, privateAccounts[1].Address())+1)
-		txEnv = txs.Enclose(genesisDoc.ChainID(), tx)
-		require.NoError(t, txEnv.Sign(privateAccounts[1]))
-
-		_, err := tm_client.BroadcastTx(client, txEnv)
-		assert.Error(t, err, "Expected error when updating someone else's unexpired"+
-			" name registry entry")
-		if err != nil {
-			assert.Contains(t, err.Error(), "permission denied", "Error should be "+
-				"permission denied")
-		}
-
-		// Wait a couple of blocks to make sure name registration expires
-		waitNBlocks(t, wsc, 5)
-
-		//now the entry should be expired, so we can update as non owner
-		const data2 = "this is not my beautiful house"
-		tx = payload.NewNameTxWithSequence(privateAccounts[1].PublicKey(), name, data2, amt, fee,
-			getSequence(t, client, privateAccounts[1].Address())+1)
-		txEnv = txs.Enclose(genesisDoc.ChainID(), tx)
-		require.NoError(t, txEnv.Sign(privateAccounts[1]))
-
-		//_, err = tm_client.BroadcastTx(client, tx)
-		require.NoError(t, subscribeAndWaitForNext(t, wsc, exe_events.EventStringNameReg(name),
-			func() {
-				_, err = tm_client.BroadcastTx(client, txEnv)
-				assert.NoError(t, err, "Should be able to update a previously expired name"+
-					" registry entry as a different address")
-			},
-			func(eventID string, resultEvent *rpc.ResultEvent) (bool, error) {
-				return true, nil
-			}))
-		entry = getNameRegEntry(t, client, name)
-		assert.Equal(t, data2, entry.Data)
-		assert.Equal(t, privateAccounts[1].Address(), entry.Owner)
-	})
-}
-
-func TestWaitBlocks(t *testing.T) {
-	wsc := newWSClient()
-	defer stopWSClient(wsc)
-	waitNBlocks(t, wsc, 5)
-}
-
-func TestBlockchainInfo(t *testing.T) {
-	wsc := newWSClient()
-	defer stopWSClient(wsc)
-	testWithAllClients(t, func(t *testing.T, clientName string, client tm_client.RPCClient) {
-		// wait a mimimal number of blocks to ensure that the later query for block
-		// headers has a non-trivial length
-		nBlocks := 4
-		waitNBlocks(t, wsc, nBlocks)
-
-		resp, err := tm_client.ListBlocks(client, 0, 0)
-		if err != nil {
-			t.Fatalf("Failed to get blockchain info: %v", err)
-		}
-		lastBlockHeight := resp.LastHeight
-		nMetaBlocks := len(resp.BlockMetas)
-		assert.True(t, uint64(nMetaBlocks) <= lastBlockHeight,
-			"Logically number of block metas should be equal or less than block height.")
-		assert.True(t, nBlocks <= len(resp.BlockMetas),
-			"Should see at least %v BlockMetas after waiting for %v blocks but saw %v",
-			nBlocks, nBlocks, len(resp.BlockMetas))
-		// For the maximum number (default to 20) of retrieved block headers,
-		// check that they correctly chain to each other.
-		lastBlockHash := resp.BlockMetas[nMetaBlocks-1].Header.Hash()
-		for i := nMetaBlocks - 2; i >= 0; i-- {
-			// the blockhash in header of height h should be identical to the hash
-			// in the LastBlockID of the header of block height h+1.
-			assert.Equal(t, lastBlockHash, resp.BlockMetas[i].Header.LastBlockID.Hash,
-				"Blockchain should be a hash tree!")
-			lastBlockHash = resp.BlockMetas[i].Header.Hash()
-		}
-
-		// Now retrieve only two blockheaders (h=1, and h=2) and check that we got
-		// two results.
-		resp, err = tm_client.ListBlocks(client, 1, 2)
-		assert.NoError(t, err)
-		assert.Equal(t, 2, len(resp.BlockMetas),
-			"Should see 2 BlockMetas after extracting 2 blocks")
-	})
-}
-
-func TestListUnconfirmedTxs(t *testing.T) {
-	if testing.Short() {
-		t.Skip("skipping test in short mode.")
-	}
-	wsc := newWSClient()
-	defer stopWSClient(wsc)
-	testWithAllClients(t, func(t *testing.T, clientName string, client tm_client.RPCClient) {
-		amt, gasLim, fee := uint64(1100), uint64(1000), uint64(1000)
-		code := []byte{0x60, 0x5, 0x60, 0x1, 0x55}
-		// Call with nil address will create a contract
-		txEnv := makeDefaultCallTx(t, client, nil, code, amt, gasLim, fee)
-		txChan := make(chan []*txs.Envelope)
-
-		// We want to catch the Tx in mempool before it gets reaped by tendermint
-		// consensus. We should be able to do this almost always if we broadcast our
-		// transaction immediately after a block has been committed. There is about
-		// 1 second between blocks, and we will have the lock on Reap
-		// So we wait for a block here
-		waitNBlocks(t, wsc, 1)
-
-		go func() {
-			for {
-				resp, err := tm_client.ListUnconfirmedTxs(client, -1)
-				if resp != nil {
-
-				}
-				require.NoError(t, err)
-				if resp.NumTxs > 0 {
-					txChan <- resp.Txs
-				}
-			}
-		}()
-
-		require.NoError(t, runThenWaitForBlock(t, wsc, nextBlockPredicateFn(), func() {
-			broadcastTx(t, client, txEnv)
-			select {
-			case <-time.After(time.Second * timeoutSeconds * 10):
-				t.Fatal("Timeout out waiting for unconfirmed transactions to appear")
-			case transactions := <-txChan:
-				assert.Len(t, transactions, 1, "There should only be a single transaction in the "+
-					"mempool during this test (previous txs should have made it into a block)")
-				assert.Contains(t, transactions, txEnv, "Transaction should be returned by ListUnconfirmedTxs")
-			}
-		}))
-	})
-}
-
-func TestGetBlock(t *testing.T) {
-	wsc := newWSClient()
-	testWithAllClients(t, func(t *testing.T, clientName string, client tm_client.RPCClient) {
-		waitNBlocks(t, wsc, 3)
-		resp, err := tm_client.GetBlock(client, 2)
-		assert.NoError(t, err)
-		assert.Equal(t, int64(2), resp.Block.Height)
-		assert.Equal(t, int64(2), resp.BlockMeta.Header.Height)
-	})
-}
-
-func TestListValidators(t *testing.T) {
-	wsc := newWSClient()
-	testWithAllClients(t, func(t *testing.T, clientName string, client tm_client.RPCClient) {
-		waitNBlocks(t, wsc, 3)
-		resp, err := tm_client.ListValidators(client)
-		assert.NoError(t, err)
-		assert.Len(t, resp.BondedValidators, 1)
-		validator := resp.BondedValidators[0]
-		assert.Equal(t, genesisDoc.Validators[0].PublicKey, validator.PublicKey)
-	})
-}
-
-func TestDumpConsensusState(t *testing.T) {
-	wsc := newWSClient()
-	startTime := time.Now()
-	testWithAllClients(t, func(t *testing.T, clientName string, client tm_client.RPCClient) {
-		waitNBlocks(t, wsc, 3)
-		resp, err := tm_client.DumpConsensusState(client)
-		assert.NoError(t, err)
-		assert.NotZero(t, startTime)
-		assert.Equal(t, fmt.Sprintf("/0/%d", types.RoundStepNewHeight),
-			strings.TrimLeft(resp.RoundState.HeightRoundStep, "0123456789"))
-	})
-}
diff --git a/rpc/tm/integration/shared.go b/rpc/tm/integration/shared.go
deleted file mode 100644
index 8b33acc3be0f3a0add0f38de9c0ffcdc1a8a898c..0000000000000000000000000000000000000000
--- a/rpc/tm/integration/shared.go
+++ /dev/null
@@ -1,240 +0,0 @@
-// +build integration
-
-// Space above here matters
-// Copyright 2017 Monax Industries Limited
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//    http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package integration
-
-import (
-	"bytes"
-	"hash/fnv"
-	"testing"
-
-	acm "github.com/hyperledger/burrow/account"
-	"github.com/hyperledger/burrow/binary"
-	"github.com/hyperledger/burrow/core/integration"
-	"github.com/hyperledger/burrow/crypto"
-	"github.com/hyperledger/burrow/execution/names"
-	"github.com/hyperledger/burrow/rpc"
-	rpcClient "github.com/hyperledger/burrow/rpc/lib/client"
-	tmClient "github.com/hyperledger/burrow/rpc/tm/client"
-	"github.com/hyperledger/burrow/txs"
-	"github.com/hyperledger/burrow/txs/payload"
-	"github.com/stretchr/testify/require"
-)
-
-const (
-	rpcAddr           = "0.0.0.0:46657"
-	websocketAddr     = rpcAddr
-	websocketEndpoint = "/websocket"
-)
-
-// global variables for use across all tests
-var (
-	privateAccounts = integration.MakePrivateAccounts(5) // make keys
-	jsonRpcClient   = rpcClient.NewJSONRPCClient(rpcAddr)
-	httpClient      = rpcClient.NewURIClient(rpcAddr)
-	clients         = map[string]tmClient.RPCClient{
-		"JSONRPC": jsonRpcClient,
-		"HTTP":    httpClient,
-	}
-	genesisDoc = integration.TestGenesisDoc(privateAccounts)
-)
-
-//-------------------------------------------------------------------------------
-// some default transaction functions
-
-func makeDefaultSendTx(t *testing.T, client tmClient.RPCClient, addr crypto.Address, amt uint64) *payload.SendTx {
-	sequence := getSequence(t, client, privateAccounts[0].Address())
-	tx := payload.NewSendTx()
-	tx.AddInputWithSequence(privateAccounts[0].PublicKey(), amt, sequence+1)
-	tx.AddOutput(addr, amt)
-	return tx
-}
-
-func makeDefaultSendTxSigned(t *testing.T, client tmClient.RPCClient, addr crypto.Address, amt uint64) *txs.Envelope {
-	txEnv := txs.Enclose(genesisDoc.ChainID(), makeDefaultSendTx(t, client, addr, amt))
-	require.NoError(t, txEnv.Sign(privateAccounts[0]))
-	return txEnv
-}
-
-func makeDefaultCallTx(t *testing.T, client tmClient.RPCClient, addr *crypto.Address, code []byte, amt, gasLim,
-	fee uint64) *txs.Envelope {
-	sequence := getSequence(t, client, privateAccounts[0].Address())
-	tx := payload.NewCallTxWithSequence(privateAccounts[0].PublicKey(), addr, code, amt, gasLim, fee, sequence+1)
-	txEnv := txs.Enclose(genesisDoc.ChainID(), tx)
-	require.NoError(t, txEnv.Sign(privateAccounts[0]))
-	return txEnv
-}
-
-func makeDefaultNameTx(t *testing.T, client tmClient.RPCClient, name, value string, amt, fee uint64) *txs.Envelope {
-	sequence := getSequence(t, client, privateAccounts[0].Address())
-	tx := payload.NewNameTxWithSequence(privateAccounts[0].PublicKey(), name, value, amt, fee, sequence+1)
-	txEnv := txs.Enclose(genesisDoc.ChainID(), tx)
-	require.NoError(t, txEnv.Sign(privateAccounts[0]))
-	return txEnv
-}
-
-//-------------------------------------------------------------------------------
-// rpc call wrappers (fail on err)
-
-// get an account's sequence number
-func getSequence(t *testing.T, client tmClient.RPCClient, addr crypto.Address) uint64 {
-	acc, err := tmClient.GetAccount(client, addr)
-	if err != nil {
-		t.Fatal(err)
-	}
-	if acc == nil {
-		return 0
-	}
-	return acc.Sequence()
-}
-
-// get the account
-func getAccount(t *testing.T, client tmClient.RPCClient, addr crypto.Address) acm.Account {
-	ac, err := tmClient.GetAccount(client, addr)
-	if err != nil {
-		t.Fatal(err)
-	}
-	return ac
-}
-
-// sign transaction
-func signTx(t *testing.T, client tmClient.RPCClient, tx txs.Tx,
-	privAcc *acm.ConcretePrivateAccount) *txs.Envelope {
-	signedTx, err := tmClient.SignTx(client, tx, []*acm.ConcretePrivateAccount{privAcc})
-	if err != nil {
-		t.Fatal(err)
-	}
-	return signedTx
-}
-
-// broadcast transaction
-func broadcastTx(t *testing.T, client tmClient.RPCClient, txEnv *txs.Envelope) *txs.Receipt {
-	rec, err := tmClient.BroadcastTx(client, txEnv)
-	require.NoError(t, err)
-	return rec
-}
-
-// dump all storage for an account. currently unused
-func dumpStorage(t *testing.T, addr crypto.Address) *rpc.ResultDumpStorage {
-	client := clients["HTTP"]
-	resp, err := tmClient.DumpStorage(client, addr)
-	if err != nil {
-		t.Fatal(err)
-	}
-	return resp
-}
-
-func getStorage(t *testing.T, client tmClient.RPCClient, addr crypto.Address, key []byte) []byte {
-	resp, err := tmClient.GetStorage(client, addr, key)
-	if err != nil {
-		t.Fatal(err)
-	}
-	return resp
-}
-
-func callCode(t *testing.T, client tmClient.RPCClient, fromAddress crypto.Address, code, data,
-	expected []byte) {
-	resp, err := tmClient.CallCode(client, fromAddress, code, data)
-	if err != nil {
-		t.Fatal(err)
-	}
-	ret := resp.Return
-	// NOTE: we don't flip memory when it comes out of RETURN (?!)
-	if bytes.Compare(ret, binary.LeftPadWord256(expected).Bytes()) != 0 {
-		t.Fatalf("Conflicting return value. Got %x, expected %x", ret, expected)
-	}
-}
-
-func callContract(t *testing.T, client tmClient.RPCClient, fromAddress, toAddress crypto.Address,
-	data, expected []byte) {
-	resp, err := tmClient.Call(client, fromAddress, toAddress, data)
-	if err != nil {
-		t.Fatal(err)
-	}
-	ret := resp.Return
-	// NOTE: we don't flip memory when it comes out of RETURN (?!)
-	if bytes.Compare(ret, binary.LeftPadWord256(expected).Bytes()) != 0 {
-		t.Fatalf("Conflicting return value. Got %x, expected %x", ret, expected)
-	}
-}
-
-// get the namereg entry
-func getNameRegEntry(t *testing.T, client tmClient.RPCClient, name string) *names.Entry {
-	entry, err := tmClient.GetName(client, name)
-	if err != nil {
-		t.Fatal(err)
-	}
-	return entry
-}
-
-// Returns a positive int64 hash of text (consumers want int64 instead of uint64)
-func hashString(text string) uint64 {
-	hasher := fnv.New64()
-	hasher.Write([]byte(text))
-	return uint64(hasher.Sum64())
-}
-
-//--------------------------------------------------------------------------------
-// utility verification function
-
-// simple contract returns 5 + 6 = 0xb
-func simpleContract() ([]byte, []byte, []byte) {
-	// this is the code we want to run when the contract is called
-	contractCode := []byte{0x60, 0x5, 0x60, 0x6, 0x1, 0x60, 0x0, 0x52, 0x60, 0x20,
-		0x60, 0x0, 0xf3}
-	// the is the code we need to return the contractCode when the contract is initialized
-	lenCode := len(contractCode)
-	// push code to the stack
-	//code := append([]byte{byte(0x60 + lenCode - 1)}, RightPadWord256(contractCode).Bytes()...)
-	code := append([]byte{0x7f},
-		binary.RightPadWord256(contractCode).Bytes()...)
-	// store it in memory
-	code = append(code, []byte{0x60, 0x0, 0x52}...)
-	// return whats in memory
-	//code = append(code, []byte{0x60, byte(32 - lenCode), 0x60, byte(lenCode), 0xf3}...)
-	code = append(code, []byte{0x60, byte(lenCode), 0x60, 0x0, 0xf3}...)
-	// return init code, contract code, expected return
-	return code, contractCode, binary.LeftPadBytes([]byte{0xb}, 32)
-}
-
-// simple call contract calls another contract
-func simpleCallContract(addr crypto.Address) ([]byte, []byte, []byte) {
-	gas1, gas2 := byte(0x1), byte(0x1)
-	value := byte(0x1)
-	inOff, inSize := byte(0x0), byte(0x0) // no call data
-	retOff, retSize := byte(0x0), byte(0x20)
-	// this is the code we want to run (call a contract and return)
-	contractCode := []byte{0x60, retSize, 0x60, retOff, 0x60, inSize, 0x60, inOff,
-		0x60, value, 0x73}
-	contractCode = append(contractCode, addr.Bytes()...)
-	contractCode = append(contractCode, []byte{0x61, gas1, gas2, 0xf1, 0x60, 0x20,
-		0x60, 0x0, 0xf3}...)
-
-	// the is the code we need to return; the contractCode when the contract is initialized
-	// it should copy the code from the input into memory
-	lenCode := len(contractCode)
-	memOff := byte(0x0)
-	inOff = byte(0xc) // length of code before codeContract
-	length := byte(lenCode)
-
-	code := []byte{0x60, length, 0x60, inOff, 0x60, memOff, 0x37}
-	// return whats in memory
-	code = append(code, []byte{0x60, byte(lenCode), 0x60, 0x0, 0xf3}...)
-	code = append(code, contractCode...)
-	// return init code, contract code, expected return
-	return code, contractCode, binary.LeftPadBytes([]byte{0xb}, 32)
-}
diff --git a/rpc/tm/integration/websocket_client_test.go b/rpc/tm/integration/websocket_client_test.go
deleted file mode 100644
index 2c996ac1ec956a4745d80e535117a2b572334a89..0000000000000000000000000000000000000000
--- a/rpc/tm/integration/websocket_client_test.go
+++ /dev/null
@@ -1,337 +0,0 @@
-// +build integration
-
-// Space above here matters
-// Copyright 2017 Monax Industries Limited
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//    http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package integration
-
-import (
-	"encoding/json"
-	"fmt"
-	"testing"
-	"time"
-
-	"github.com/hyperledger/burrow/crypto"
-	"github.com/hyperledger/burrow/execution/events"
-	"github.com/hyperledger/burrow/rpc"
-	tmClient "github.com/hyperledger/burrow/rpc/tm/client"
-	"github.com/hyperledger/burrow/txs"
-	"github.com/hyperledger/burrow/txs/payload"
-	"github.com/stretchr/testify/assert"
-	"github.com/stretchr/testify/require"
-	tmTypes "github.com/tendermint/tendermint/types"
-)
-
-//--------------------------------------------------------------------------------
-// Test the websocket service
-
-// make a simple connection to the server
-func TestWSConnect(t *testing.T) {
-	wsc := newWSClient()
-	stopWSClient(wsc)
-}
-
-// receive a new block message
-func TestWSNewBlock(t *testing.T) {
-	wsc := newWSClient()
-	eid := tmTypes.EventNewBlock
-	subId := subscribeAndGetSubscriptionId(t, wsc, eid)
-	defer func() {
-		unsubscribe(t, wsc, subId)
-		stopWSClient(wsc)
-	}()
-	waitForEvent(t, wsc, eid, func() {},
-		func(eventID string, resultEvent *rpc.ResultEvent) (bool, error) {
-			fmt.Println("Check: ", resultEvent.Tendermint.EventDataNewBlock().Block)
-			return true, nil
-		})
-}
-
-// receive a few new block messages in a row, with increasing height
-func TestWSBlockchainGrowth(t *testing.T) {
-	if testing.Short() {
-		t.Skip("skipping test in short mode.")
-	}
-	wsc := newWSClient()
-	eid := tmTypes.EventNewBlock
-	subId := subscribeAndGetSubscriptionId(t, wsc, eid)
-	defer func() {
-		unsubscribe(t, wsc, subId)
-		stopWSClient(wsc)
-	}()
-	// listen for NewBlock, ensure height increases by 1
-	var initBlockN int64
-	for i := int64(0); i < 2; i++ {
-		waitForEvent(t, wsc, eid, func() {},
-			func(eventID string, resultEvent *rpc.ResultEvent) (bool, error) {
-				eventDataNewBlock := resultEvent.Tendermint.EventDataNewBlock()
-				if eventDataNewBlock == nil {
-					t.Fatalf("Was expecting EventDataNewBlock but got %v", resultEvent)
-				}
-				block := eventDataNewBlock.Block
-				if i == 0 {
-					initBlockN = block.Height
-				} else {
-					if block.Header.Height != initBlockN+i {
-						return true, fmt.Errorf("Expected block %d, got block %d", i,
-							block.Header.Height)
-					}
-				}
-				return true, nil
-			})
-	}
-}
-
-// send a transaction and validate the events from listening for both sender and receiver
-func TestWSSend(t *testing.T) {
-	wsc := newWSClient()
-	toAddr := privateAccounts[1].Address()
-	amt := uint64(100)
-	eidInput := events.EventStringAccountInput(privateAccounts[0].Address())
-	eidOutput := events.EventStringAccountOutput(toAddr)
-	subIdInput := subscribeAndGetSubscriptionId(t, wsc, eidInput)
-	subIdOutput := subscribeAndGetSubscriptionId(t, wsc, eidOutput)
-	defer func() {
-		unsubscribe(t, wsc, subIdInput)
-		unsubscribe(t, wsc, subIdOutput)
-		stopWSClient(wsc)
-	}()
-
-	tx := makeDefaultSendTxSigned(t, jsonRpcClient, toAddr, amt)
-	broadcastTx(t, jsonRpcClient, tx)
-
-	// Set of response IDs we expect
-	rids := map[string]struct{}{tmClient.EventResponseID(eidInput): {}, tmClient.EventResponseID(eidOutput): {}}
-
-	r := <-wsc.ResponsesCh
-	result, err := readResponse(r)
-	assert.NoError(t, err)
-	assert.NoError(t, unmarshalValidateSend(amt, toAddr, result))
-	delete(rids, r.ID)
-
-	r = <-wsc.ResponsesCh
-	result, err = readResponse(r)
-	assert.NoError(t, err)
-	assert.NoError(t, unmarshalValidateSend(amt, toAddr, result))
-	delete(rids, r.ID)
-
-	// Note currently we cannot guarantee order with pubsub event system
-	assert.Empty(t, rids, "Should receive input and output event")
-}
-
-// ensure events are only fired once for a given transaction
-func TestWSDoubleFire(t *testing.T) {
-	if testing.Short() {
-		t.Skip("skipping test in short mode.")
-	}
-	wsc := newWSClient()
-	eid := events.EventStringAccountInput(privateAccounts[0].Address())
-	subId := subscribeAndGetSubscriptionId(t, wsc, eid)
-	defer func() {
-		unsubscribe(t, wsc, subId)
-		stopWSClient(wsc)
-	}()
-	amt := uint64(100)
-	toAddr := privateAccounts[1].Address()
-	// broadcast the transaction, wait to hear about it
-	waitForEvent(t, wsc, eid, func() {
-		tx := makeDefaultSendTxSigned(t, jsonRpcClient, toAddr, amt)
-		broadcastTx(t, jsonRpcClient, tx)
-	}, func(eventID string, resultEvent *rpc.ResultEvent) (bool, error) {
-		return true, nil
-	})
-	select {
-	case <-wsc.ResponsesCh:
-		t.Fatal("Should time out waiting for second event")
-	case <-time.After(timeoutSeconds * time.Second):
-
-	}
-}
-
-// create a contract, wait for the event, and send it a msg, validate the return
-func TestWSCallWait(t *testing.T) {
-	if testing.Short() {
-		t.Skip("skipping test in short mode.")
-	}
-	wsc := newWSClient()
-	defer stopWSClient(wsc)
-	// Mini soak test
-	for i := 0; i < 20; i++ {
-		amt, gasLim, fee := uint64(10000), uint64(1000), uint64(1000)
-		code, returnCode, returnVal := simpleContract()
-		var contractAddr crypto.Address
-		eid1 := events.EventStringAccountInput(privateAccounts[0].Address())
-		subId1 := subscribeAndGetSubscriptionId(t, wsc, eid1)
-		// wait for the contract to be created
-		waitForEvent(t, wsc, eid1, func() {
-			tx := makeDefaultCallTx(t, jsonRpcClient, nil, code, amt, gasLim, fee)
-			receipt := broadcastTx(t, jsonRpcClient, tx)
-			contractAddr = receipt.ContractAddress
-		}, unmarshalValidateTx(amt, returnCode))
-
-		unsubscribe(t, wsc, subId1)
-
-		// susbscribe to the new contract
-		amt = uint64(10001)
-		eid2 := events.EventStringAccountOutput(contractAddr)
-		subId2 := subscribeAndGetSubscriptionId(t, wsc, eid2)
-		// get the return value from a call
-		data := []byte{0x1}
-		waitForEvent(t, wsc, eid2, func() {
-			tx := makeDefaultCallTx(t, jsonRpcClient, &contractAddr, data, amt, gasLim, fee)
-			receipt := broadcastTx(t, jsonRpcClient, tx)
-			contractAddr = receipt.ContractAddress
-		}, unmarshalValidateTx(amt, returnVal))
-		unsubscribe(t, wsc, subId2)
-	}
-}
-
-// create a contract and send it a msg without waiting. wait for contract event
-// and validate return
-func TestWSCallNoWait(t *testing.T) {
-	if testing.Short() {
-		t.Skip("skipping test in short mode.")
-	}
-	wsc := newWSClient()
-	defer stopWSClient(wsc)
-	amt, gasLim, fee := uint64(10000), uint64(1000), uint64(1000)
-	code, _, returnVal := simpleContract()
-
-	sequence := getSequence(t, jsonRpcClient, privateAccounts[0].Address())
-	txEnv := makeDefaultCallTx(t, jsonRpcClient, nil, code, amt, gasLim, fee)
-	receipt := broadcastTx(t, jsonRpcClient, txEnv)
-	contractAddr := receipt.ContractAddress
-
-	// susbscribe to the new contract
-	amt = uint64(10001)
-	eid := events.EventStringAccountOutput(contractAddr)
-	subId := subscribeAndGetSubscriptionId(t, wsc, eid)
-	defer unsubscribe(t, wsc, subId)
-
-	data := []byte{0x1}
-	waitForEvent(t, wsc, eid, func() {
-		tx := payload.NewCallTxWithSequence(privateAccounts[0].PublicKey(), &contractAddr, data, amt, gasLim, fee,
-			sequence+3)
-		txEnv = txs.Enclose(genesisDoc.ChainID(), tx)
-		require.NoError(t, txEnv.Sign(privateAccounts[0]))
-		broadcastTx(t, jsonRpcClient, txEnv)
-	}, unmarshalValidateTx(amt, returnVal))
-}
-
-// create two contracts, one of which calls the other
-func TestWSCallCall(t *testing.T) {
-	if testing.Short() {
-		t.Skip("skipping test in short mode.")
-	}
-	wsc := newWSClient()
-	defer stopWSClient(wsc)
-	amt, gasLim, fee := uint64(10000), uint64(1000), uint64(1000)
-	code, _, returnVal := simpleContract()
-	TxHash := new([]byte)
-
-	// deploy the two contracts
-	txEnv := makeDefaultCallTx(t, jsonRpcClient, nil, code, amt, gasLim, fee)
-	receipt := txEnv.Tx.GenerateReceipt()
-	contractAddr1 := receipt.ContractAddress
-	// subscribe to the new contracts
-	eid := events.EventStringAccountCall(contractAddr1)
-	subId := subscribeAndGetSubscriptionId(t, wsc, eid)
-	defer unsubscribe(t, wsc, subId)
-
-	_, err := broadcastTxAndWait(t, jsonRpcClient, txEnv)
-	require.NoError(t, err)
-
-	// call contract2, which should call contract1, and wait for ev1
-	code, _, _ = simpleCallContract(contractAddr1)
-	txEnv = makeDefaultCallTx(t, jsonRpcClient, nil, code, amt, gasLim, fee)
-	receipt2, err := broadcastTxAndWait(t, jsonRpcClient, txEnv)
-	require.NoError(t, err)
-	contractAddr2 := receipt2.ContractAddress
-
-	// let the contract get created first
-	waitForEvent(t, wsc, eid,
-		// Runner
-		func() {
-		},
-		// Event Checker
-		func(eventID string, resultEvent *rpc.ResultEvent) (bool, error) {
-			return true, nil
-		})
-	// call it
-	waitForEvent(t, wsc, eid,
-		// Runner
-		func() {
-			txEnv := makeDefaultCallTx(t, jsonRpcClient, &contractAddr2, nil, amt, gasLim, fee)
-			broadcastTx(t, jsonRpcClient, txEnv)
-			*TxHash = txEnv.Tx.Hash()
-		},
-		// Event checker
-		unmarshalValidateCall(privateAccounts[0].Address(), returnVal, TxHash))
-}
-
-func TestSubscribe(t *testing.T) {
-	wsc := newWSClient()
-	var subId string
-	subscribe(t, wsc, tmTypes.EventNewBlock)
-
-Subscribe:
-	for {
-		select {
-		case <-time.After(timeoutSeconds * time.Second):
-			t.Fatal("Timed out waiting for subscription result")
-
-		case response := <-wsc.ResponsesCh:
-			require.Nil(t, response.Error)
-			res := new(rpc.ResultSubscribe)
-			require.NoError(t, json.Unmarshal(response.Result, res))
-			assert.Equal(t, tmTypes.EventNewBlock, res.EventID)
-			subId = res.SubscriptionID
-			break Subscribe
-		}
-	}
-
-	blocksSeen := 0
-	for {
-		select {
-		// wait long enough to check we don't see another new block event even though
-		// a block will have come
-		case <-time.After(expectBlockInSeconds * time.Second):
-			if blocksSeen == 0 {
-				t.Fatal("Timed out without seeing a NewBlock event")
-			}
-			return
-
-		case response := <-wsc.ResponsesCh:
-			require.Nil(t, response.Error)
-
-			if response.ID == tmClient.EventResponseID(tmTypes.EventNewBlock) {
-				res := new(rpc.ResultEvent)
-				json.Unmarshal(response.Result, res)
-				enb := res.Tendermint.EventDataNewBlock()
-				if enb != nil {
-					assert.Equal(t, genesisDoc.ChainID(), enb.Block.ChainID)
-					if blocksSeen > 1 {
-						t.Fatal("Continued to see NewBlock event after unsubscribing")
-					} else {
-						if blocksSeen == 0 {
-							unsubscribe(t, wsc, subId)
-						}
-						blocksSeen++
-					}
-				}
-			}
-		}
-	}
-}
diff --git a/rpc/tm/integration/websocket_helpers.go b/rpc/tm/integration/websocket_helpers.go
deleted file mode 100644
index 6e19d8fee2f0c83328fe2c3b4cc361bc388ec010..0000000000000000000000000000000000000000
--- a/rpc/tm/integration/websocket_helpers.go
+++ /dev/null
@@ -1,323 +0,0 @@
-// +build integration
-
-// Space above here matters
-// Copyright 2017 Monax Industries Limited
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//    http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package integration
-
-import (
-	"bytes"
-	"encoding/json"
-	"fmt"
-	"runtime/debug"
-	"testing"
-	"time"
-
-	"github.com/hyperledger/burrow/crypto"
-	"github.com/hyperledger/burrow/execution/events"
-	"github.com/hyperledger/burrow/rpc"
-	rpcClient "github.com/hyperledger/burrow/rpc/lib/client"
-	rpcTypes "github.com/hyperledger/burrow/rpc/lib/types"
-	tmClient "github.com/hyperledger/burrow/rpc/tm/client"
-	"github.com/hyperledger/burrow/txs"
-	"github.com/hyperledger/burrow/txs/payload"
-	"github.com/stretchr/testify/require"
-	tmTypes "github.com/tendermint/tendermint/types"
-)
-
-const (
-	timeoutSeconds       = 8
-	expectBlockInSeconds = 2
-)
-
-//--------------------------------------------------------------------------------
-// Utilities for testing the websocket service
-type blockPredicate func(block *tmTypes.Block) bool
-type resultEventChecker func(eventID string, resultEvent *rpc.ResultEvent) (bool, error)
-
-// create a new connection
-func newWSClient() *rpcClient.WSClient {
-	wsc := rpcClient.NewWSClient(websocketAddr, websocketEndpoint)
-	if err := wsc.Start(); err != nil {
-		panic(err)
-	}
-	return wsc
-}
-
-func stopWSClient(wsc *rpcClient.WSClient) {
-	wsc.Stop()
-}
-
-// subscribe to an event
-func subscribe(t *testing.T, wsc *rpcClient.WSClient, eventId string) {
-	if err := tmClient.Subscribe(wsc, eventId); err != nil {
-		t.Fatal(err)
-	}
-}
-
-func subscribeAndGetSubscriptionId(t *testing.T, wsc *rpcClient.WSClient, eventId string) string {
-	if err := tmClient.Subscribe(wsc, eventId); err != nil {
-		t.Fatal(err)
-	}
-
-	timeout := time.NewTimer(timeoutSeconds * time.Second)
-	for {
-		select {
-		case <-timeout.C:
-			t.Fatal("Timeout waiting for subscription result")
-		case response := <-wsc.ResponsesCh:
-			require.Nil(t, response.Error, "Got error response from websocket channel: %v", response.Error)
-			if response.ID == tmClient.SubscribeRequestID {
-				res := new(rpc.ResultSubscribe)
-				err := json.Unmarshal(response.Result, res)
-				if err == nil {
-					return res.SubscriptionID
-				}
-			}
-		}
-	}
-}
-
-// unsubscribe from an event
-func unsubscribe(t *testing.T, wsc *rpcClient.WSClient, subscriptionId string) {
-	if err := tmClient.Unsubscribe(wsc, subscriptionId); err != nil {
-		t.Fatal(err)
-	}
-}
-
-// broadcast transaction and wait for new block
-func broadcastTxAndWait(t *testing.T, client tmClient.RPCClient, txEnv *txs.Envelope) (*txs.Receipt, error) {
-	wsc := newWSClient()
-	defer stopWSClient(wsc)
-	inputs := txEnv.Tx.GetInputs()
-	if len(inputs) == 0 {
-		t.Fatalf("cannot broadcastAndWait fot Tx with no inputs")
-	}
-	address := inputs[0].Address
-
-	var rec *txs.Receipt
-	var err error
-
-	err = subscribeAndWaitForNext(t, wsc, events.EventStringAccountInput(address),
-		func() {
-			rec, err = tmClient.BroadcastTx(client, txEnv)
-		}, func(eventID string, resultEvent *rpc.ResultEvent) (bool, error) {
-			return true, nil
-		})
-	if err != nil {
-		return nil, err
-	}
-	return rec, err
-}
-
-func nextBlockPredicateFn() blockPredicate {
-	initialHeight := int64(-1)
-	return func(block *tmTypes.Block) bool {
-		if initialHeight <= 0 {
-			initialHeight = block.Height
-			return false
-		} else {
-			// TODO: [Silas] remove the + 1 here. It is a workaround for the fact
-			// that tendermint fires the NewBlock event before it has finalised its
-			// state updates, so we have to wait for the block after the block we
-			// want in order for the Tx to be genuinely final.
-			// This should be addressed by: https://github.com/tendermint/tendermint/pull/265
-			return block.Height > initialHeight+1
-		}
-	}
-}
-
-func waitNBlocks(t *testing.T, wsc *rpcClient.WSClient, n int) {
-	i := 0
-	require.NoError(t, runThenWaitForBlock(t, wsc,
-		func(block *tmTypes.Block) bool {
-			i++
-			return i >= n
-		},
-		func() {}))
-}
-
-func runThenWaitForBlock(t *testing.T, wsc *rpcClient.WSClient, predicate blockPredicate, runner func()) error {
-	eventDataChecker := func(event string, eventData *rpc.ResultEvent) (bool, error) {
-		eventDataNewBlock := eventData.Tendermint.EventDataNewBlock()
-		if eventDataNewBlock == nil {
-			return false, fmt.Errorf("could not convert %#v to EventDataNewBlock", eventData)
-		}
-		return predicate(eventDataNewBlock.Block), nil
-	}
-	return subscribeAndWaitForNext(t, wsc, tmTypes.EventNewBlock, runner, eventDataChecker)
-}
-
-func subscribeAndWaitForNext(t *testing.T, wsc *rpcClient.WSClient, event string, runner func(),
-	checker resultEventChecker) error {
-
-	subId := subscribeAndGetSubscriptionId(t, wsc, event)
-	defer unsubscribe(t, wsc, subId)
-	return waitForEvent(t, wsc, event, runner, checker)
-}
-
-// waitForEvent executes runner that is expected to trigger events. It then
-// waits for any events on the supplies WSClient and checks the eventData with
-// the eventDataChecker which is a function that is passed the event name
-// and the Data and returns the pair of stopWaiting, err. Where if
-// stopWaiting is true waitForEvent will return or if stopWaiting is false
-// waitForEvent will keep listening for new events. If an error is returned
-// waitForEvent will fail the test.
-func waitForEvent(t *testing.T, wsc *rpcClient.WSClient, eventID string, runner func(),
-	checker resultEventChecker) error {
-
-	// go routine to wait for websocket msg
-	eventsCh := make(chan *rpc.ResultEvent)
-	shutdownEventsCh := make(chan bool, 1)
-	errCh := make(chan error)
-
-	// do stuff (transactions)
-	runner()
-
-	// Read message
-	go func() {
-		for {
-			select {
-			case <-shutdownEventsCh:
-				return
-			case r := <-wsc.ResponsesCh:
-				if r.Error != nil {
-					errCh <- r.Error
-					return
-				}
-				if r.ID == tmClient.EventResponseID(eventID) {
-					resultEvent, err := readResponse(r)
-					if err != nil {
-						errCh <- err
-					} else {
-						eventsCh <- resultEvent
-					}
-				}
-			case <-wsc.Quit():
-				return
-			}
-		}
-	}()
-
-	// Don't block up WSClient
-	defer func() { shutdownEventsCh <- true }()
-
-	for {
-		select {
-		// wait for an event or timeout
-		case <-time.After(timeoutSeconds * time.Second):
-			t.Fatalf("waitForEvent timed out: %s", debug.Stack())
-		case eventData := <-eventsCh:
-			// run the check
-			stopWaiting, err := checker(eventID, eventData)
-			if err != nil {
-				return err
-			}
-			if stopWaiting {
-				return nil
-			}
-		case err := <-errCh:
-			return err
-		}
-	}
-	return nil
-}
-
-func readResponse(r rpcTypes.RPCResponse) (*rpc.ResultEvent, error) {
-	if r.Error != nil {
-		return nil, r.Error
-	}
-	resultEvent := new(rpc.ResultEvent)
-	err := json.Unmarshal(r.Result, resultEvent)
-	if err != nil {
-		return nil, err
-	}
-	return resultEvent, nil
-}
-
-//--------------------------------------------------------------------------------
-
-func unmarshalValidateSend(amt uint64, toAddr crypto.Address, resultEvent *rpc.ResultEvent) error {
-	data := resultEvent.Execution.GetTx()
-	if data == nil {
-		return fmt.Errorf("event data %v is not EventDataTx", resultEvent)
-	}
-	if data.Exception == nil {
-		return data.Exception.AsError()
-	}
-	tx := data.Tx.Payload.(*payload.SendTx)
-	if tx.Inputs[0].Address != privateAccounts[0].Address() {
-		return fmt.Errorf("senders do not match up! Got %s, expected %s", tx.Inputs[0].Address,
-			privateAccounts[0].Address())
-	}
-	if tx.Inputs[0].Amount != amt {
-		return fmt.Errorf("amt does not match up! Got %d, expected %d", tx.Inputs[0].Amount, amt)
-	}
-	if tx.Outputs[0].Address != toAddr {
-		return fmt.Errorf("receivers do not match up! Got %s, expected %s", tx.Outputs[0].Address,
-			privateAccounts[0].Address())
-	}
-	return nil
-}
-
-func unmarshalValidateTx(amt uint64, returnCode []byte) resultEventChecker {
-	return func(eventID string, resultEvent *rpc.ResultEvent) (bool, error) {
-		data := resultEvent.Execution.GetTx()
-		if data == nil {
-			return true, fmt.Errorf("event data %v is not EventDataTx", *resultEvent)
-		}
-		if data.Exception != nil {
-			return true, data.Exception.AsError()
-		}
-		tx := data.Tx.Payload.(*payload.CallTx)
-		if tx.Input.Address != privateAccounts[0].Address() {
-			return true, fmt.Errorf("senders do not match up! Got %s, expected %s",
-				tx.Input.Address, privateAccounts[0].Address())
-		}
-		if tx.Input.Amount != amt {
-			return true, fmt.Errorf("amount does not match up! Got %d, expected %d",
-				tx.Input.Amount, amt)
-		}
-		ret := data.Return
-		if !bytes.Equal(ret, returnCode) {
-			return true, fmt.Errorf("tx did not return correctly. Got %x, expected %x", ret, returnCode)
-		}
-		return true, nil
-	}
-}
-
-func unmarshalValidateCall(origin crypto.Address, returnCode []byte, txid *[]byte) resultEventChecker {
-	return func(eventID string, resultEvent *rpc.ResultEvent) (bool, error) {
-		data := resultEvent.Execution.Call
-		if data == nil {
-			return true, fmt.Errorf("event data %v is not EventDataTx", *resultEvent)
-		}
-		if data.Exception != nil {
-			return true, data.Exception.AsError()
-		}
-		if data.Origin != origin {
-			return true, fmt.Errorf("origin does not match up! Got %s, expected %s", data.Origin, origin)
-		}
-		ret := data.Return
-		if !bytes.Equal(ret, returnCode) {
-			return true, fmt.Errorf("call did not return correctly. Got %x, expected %x", ret, returnCode)
-		}
-		if !bytes.Equal(resultEvent.Execution.Header.TxHash, *txid) {
-			return true, fmt.Errorf("TxIDs do not match up! Got %x, expected %x",
-				resultEvent.Execution.Header.TxHash, *txid)
-		}
-		return true, nil
-	}
-}
diff --git a/rpc/tm/methods.go b/rpc/tm/methods.go
index 017cf29c9bf88c4114f472d2825bc611532cdd14..e28e7d8626ad45c307e8fdd57fa3823eb857e2ad 100644
--- a/rpc/tm/methods.go
+++ b/rpc/tm/methods.go
@@ -1,27 +1,16 @@
 package tm
 
 import (
-	"context"
 	"fmt"
-	"time"
 
-	acm "github.com/hyperledger/burrow/account"
-	"github.com/hyperledger/burrow/crypto"
-	"github.com/hyperledger/burrow/event"
-	"github.com/hyperledger/burrow/execution/names"
+	"github.com/hyperledger/burrow/acm"
 	"github.com/hyperledger/burrow/logging"
 	"github.com/hyperledger/burrow/rpc"
 	"github.com/hyperledger/burrow/rpc/lib/server"
-	"github.com/hyperledger/burrow/rpc/lib/types"
-	"github.com/hyperledger/burrow/txs"
 )
 
 // Method names
 const (
-	BroadcastTx = "broadcast_tx"
-	Subscribe   = "subscribe"
-	Unsubscribe = "unsubscribe"
-
 	// Status
 	Status  = "status"
 	NetInfo = "net_info"
@@ -60,87 +49,9 @@ const (
 	LastBlockInfo = "last_block_info"
 )
 
-const SubscriptionTimeout = 5 * time.Second
-
 func GetRoutes(service *rpc.Service, logger *logging.Logger) map[string]*server.RPCFunc {
 	logger = logger.WithScope("GetRoutes")
 	return map[string]*server.RPCFunc{
-		// Transact
-		BroadcastTx: server.NewRPCFunc(func(txEnv *txs.Envelope) (*rpc.ResultBroadcastTx, error) {
-			receipt, err := service.Transactor().BroadcastTx(txEnv)
-			if err != nil {
-				return nil, err
-			}
-			return &rpc.ResultBroadcastTx{
-				Receipt: *receipt,
-			}, nil
-		}, "tx"),
-
-		SignTx: server.NewRPCFunc(func(txEnv *txs.Envelope, concretePrivateAccounts []*acm.ConcretePrivateAccount) (*rpc.ResultSignTx, error) {
-			txEnv, err := service.Transactor().SignTx(txEnv, acm.SigningAccounts(concretePrivateAccounts))
-			return &rpc.ResultSignTx{Tx: txEnv}, err
-
-		}, "tx,privAccounts"),
-
-		// Simulated call
-		Call: server.NewRPCFunc(func(fromAddress, toAddress crypto.Address, data []byte) (*rpc.ResultCall, error) {
-			call, err := service.Transactor().Call(service.State(), fromAddress, toAddress, data)
-			if err != nil {
-				return nil, err
-			}
-			return &rpc.ResultCall{Call: *call}, nil
-		}, "fromAddress,toAddress,data"),
-
-		CallCode: server.NewRPCFunc(func(fromAddress crypto.Address, code, data []byte) (*rpc.ResultCall, error) {
-			call, err := service.Transactor().CallCode(service.State(), fromAddress, code, data)
-			if err != nil {
-				return nil, err
-			}
-			return &rpc.ResultCall{Call: *call}, nil
-		}, "fromAddress,code,data"),
-
-		// Events
-		Subscribe: server.NewWSRPCFunc(func(wsCtx types.WSRPCContext, eventID string) (*rpc.ResultSubscribe, error) {
-			subscriptionID, err := event.GenerateSubscriptionID()
-			if err != nil {
-				return nil, err
-			}
-
-			ctx, cancel := context.WithTimeout(context.Background(), SubscriptionTimeout)
-			defer cancel()
-
-			err = service.Subscribe(ctx, subscriptionID, eventID, func(resultEvent *rpc.ResultEvent) (stop bool) {
-				keepAlive := wsCtx.TryWriteRPCResponse(types.NewRPCSuccessResponse(
-					EventResponseID(wsCtx.Request.ID, eventID), resultEvent))
-				if !keepAlive {
-					logger.InfoMsg("dropping subscription because could not write to websocket",
-						"subscription_id", subscriptionID,
-						"event_id", eventID)
-				}
-				return !keepAlive
-			})
-			if err != nil {
-				return nil, err
-			}
-			return &rpc.ResultSubscribe{
-				EventID:        eventID,
-				SubscriptionID: subscriptionID,
-			}, nil
-		}, "eventID"),
-
-		Unsubscribe: server.NewWSRPCFunc(func(wsCtx types.WSRPCContext, subscriptionID string) (*rpc.ResultUnsubscribe, error) {
-			ctx, cancel := context.WithTimeout(context.Background(), SubscriptionTimeout)
-			defer cancel()
-			// Since our model uses a random subscription ID per request we just drop all matching requests
-			err := service.Unsubscribe(ctx, subscriptionID)
-			if err != nil {
-				return nil, err
-			}
-			return &rpc.ResultUnsubscribe{
-				SubscriptionID: subscriptionID,
-			}, nil
-		}, "subscriptionID"),
-
 		// Status
 		Status:  server.NewRPCFunc(service.Status, ""),
 		NetInfo: server.NewRPCFunc(service.NetInfo, ""),
@@ -169,12 +80,8 @@ func GetRoutes(service *rpc.Service, logger *logging.Logger) map[string]*server.
 		DumpConsensusState: server.NewRPCFunc(service.DumpConsensusState, ""),
 
 		// Names
-		GetName: server.NewRPCFunc(service.GetName, "name"),
-		ListNames: server.NewRPCFunc(func() (*rpc.ResultListNames, error) {
-			return service.ListNames(func(*names.Entry) bool {
-				return true
-			})
-		}, ""),
+		GetName:   server.NewRPCFunc(service.GetName, "name"),
+		ListNames: server.NewRPCFunc(service.ListNames, ""),
 
 		// Private account
 		GeneratePrivateAccount: server.NewRPCFunc(service.GeneratePrivateAccount, ""),
diff --git a/rpc/tm/server.go b/rpc/tm/tm_server.go
similarity index 75%
rename from rpc/tm/server.go
rename to rpc/tm/tm_server.go
index 2baf381b65d86a367baa7ff50a5a21c2215a5c12..2944606ec8ba78f4b1e7b34270ff16289f991bcd 100644
--- a/rpc/tm/server.go
+++ b/rpc/tm/tm_server.go
@@ -17,26 +17,22 @@ package tm
 import (
 	"net/http"
 
-	"github.com/hyperledger/burrow/consensus/tendermint"
-	"github.com/hyperledger/burrow/event"
 	"github.com/hyperledger/burrow/logging"
 	"github.com/hyperledger/burrow/logging/structure"
 	"github.com/hyperledger/burrow/rpc"
 	"github.com/hyperledger/burrow/rpc/lib/server"
 )
 
-func StartServer(service *rpc.Service, pattern, listenAddress string, emitter event.Emitter,
-	logger *logging.Logger) (*http.Server, error) {
-
+func StartServer(service *rpc.Service, pattern, listenAddress string, logger *logging.Logger) (*http.Server, error) {
 	logger = logger.With(structure.ComponentKey, "RPC_TM")
 	routes := GetRoutes(service, logger)
 	mux := http.NewServeMux()
-	wm := server.NewWebsocketManager(routes, logger, server.EventSubscriber(tendermint.SubscribableAsEventBus(emitter)))
+	wm := server.NewWebsocketManager(routes, logger)
 	mux.HandleFunc(pattern, wm.WebsocketHandler)
 	server.RegisterRPCFuncs(mux, routes, logger)
-	server, err := server.StartHTTPServer(listenAddress, mux, logger)
+	srv, err := server.StartHTTPServer(listenAddress, mux, logger)
 	if err != nil {
 		return nil, err
 	}
-	return server, nil
+	return srv, nil
 }
diff --git a/rpc/tm/client/client.go b/rpc/tm/tmclient/client.go
similarity index 84%
rename from rpc/tm/client/client.go
rename to rpc/tm/tmclient/client.go
index 1b03a76e348cd6ae9042376aab316b7dfc41d488..f0fa4d43dcdebfaff06b7a99900348ab6fee55aa 100644
--- a/rpc/tm/client/client.go
+++ b/rpc/tm/tmclient/client.go
@@ -12,13 +12,13 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package client
+package tmclient
 
 import (
 	"errors"
 	"fmt"
 
-	acm "github.com/hyperledger/burrow/account"
+	"github.com/hyperledger/burrow/acm"
 	"github.com/hyperledger/burrow/crypto"
 	"github.com/hyperledger/burrow/execution/names"
 	"github.com/hyperledger/burrow/rpc"
@@ -30,15 +30,6 @@ type RPCClient interface {
 	Call(method string, params map[string]interface{}, result interface{}) (interface{}, error)
 }
 
-func BroadcastTx(client RPCClient, txEnv *txs.Envelope) (*txs.Receipt, error) {
-	res := new(txs.Receipt)
-	_, err := client.Call(tm.BroadcastTx, pmap("tx", txEnv), res)
-	if err != nil {
-		return nil, err
-	}
-	return res, nil
-}
-
 func Status(client RPCClient) (*rpc.ResultStatus, error) {
 	res := new(rpc.ResultStatus)
 	_, err := client.Call(tm.Status, pmap(), res)
@@ -106,25 +97,6 @@ func GetStorage(client RPCClient, address crypto.Address, key []byte) ([]byte, e
 	return res.Value, nil
 }
 
-func CallCode(client RPCClient, fromAddress crypto.Address, code, data []byte) (*rpc.ResultCall, error) {
-	res := new(rpc.ResultCall)
-	_, err := client.Call(tm.CallCode, pmap("fromAddress", fromAddress, "code", code, "data", data), res)
-	if err != nil {
-		return nil, err
-	}
-	return res, nil
-}
-
-func Call(client RPCClient, fromAddress, toAddress crypto.Address, data []byte) (*rpc.ResultCall, error) {
-	res := new(rpc.ResultCall)
-	_, err := client.Call(tm.Call, pmap("fromAddress", fromAddress, "toAddress", toAddress,
-		"data", data), res)
-	if err != nil {
-		return nil, err
-	}
-	return res, nil
-}
-
 func GetName(client RPCClient, name string) (*names.Entry, error) {
 	res := new(rpc.ResultGetName)
 	_, err := client.Call(tm.GetName, pmap("name", name), res)
diff --git a/rpc/tm/client/client_test.go b/rpc/tm/tmclient/client_test.go
similarity index 97%
rename from rpc/tm/client/client_test.go
rename to rpc/tm/tmclient/client_test.go
index b8c322d597b15695fda54a815f40c257170c6ec3..3adeec8d345c1c2e9f34a0a6928c1da8952f30f7 100644
--- a/rpc/tm/client/client_test.go
+++ b/rpc/tm/tmclient/client_test.go
@@ -1,4 +1,4 @@
-package client
+package tmclient
 
 import (
 	"testing"
diff --git a/rpc/v0/client.go b/rpc/v0/client.go
deleted file mode 100644
index f663a7993509daf900b8f1d4a4c7e25a4662783d..0000000000000000000000000000000000000000
--- a/rpc/v0/client.go
+++ /dev/null
@@ -1,127 +0,0 @@
-package v0
-
-import (
-	"bytes"
-	"encoding/json"
-	"io/ioutil"
-	"net/http"
-	"time"
-
-	"github.com/hyperledger/burrow/execution"
-	"github.com/hyperledger/burrow/execution/events"
-	"github.com/hyperledger/burrow/rpc"
-	"github.com/hyperledger/burrow/txs"
-)
-
-type V0Client struct {
-	url    string
-	codec  rpc.Codec
-	client *http.Client
-}
-
-type RPCResponse struct {
-	Result  json.RawMessage `json:"result"`
-	Error   *rpc.RPCError   `json:"error"`
-	Id      string          `json:"id"`
-	JSONRPC string          `json:"jsonrpc"`
-}
-
-func NewV0Client(url string) *V0Client {
-	return &V0Client{
-		url:   url,
-		codec: NewTCodec(),
-		client: &http.Client{
-			Timeout: 1000 * time.Second,
-		},
-	}
-}
-
-func (vc *V0Client) Transact(param TransactParam) (*txs.Receipt, error) {
-	receipt := new(txs.Receipt)
-	err := vc.CallMethod(TRANSACT, param, receipt)
-	if err != nil {
-		return nil, err
-	}
-	return receipt, nil
-}
-
-func (vc *V0Client) TransactAndHold(param TransactParam) (*events.EventDataCall, error) {
-	eventDataCall := new(events.EventDataCall)
-	err := vc.CallMethod(TRANSACT_AND_HOLD, param, eventDataCall)
-	if err != nil {
-		return nil, err
-	}
-	return eventDataCall, nil
-}
-
-func (vc *V0Client) Send(param SendParam) (*txs.Receipt, error) {
-	receipt := new(txs.Receipt)
-	err := vc.CallMethod(SEND, param, receipt)
-	if err != nil {
-		return nil, err
-	}
-	return receipt, nil
-}
-
-func (vc *V0Client) SendAndHold(param SendParam) (*txs.Receipt, error) {
-	receipt := new(txs.Receipt)
-	err := vc.CallMethod(SEND_AND_HOLD, param, receipt)
-	if err != nil {
-		return nil, err
-	}
-	return receipt, nil
-}
-
-func (vc *V0Client) Call(param CallParam) (*execution.Call, error) {
-	call := new(execution.Call)
-	err := vc.CallMethod(CALL, param, call)
-	if err != nil {
-		return nil, err
-	}
-	return call, nil
-}
-
-func (vc *V0Client) CallCode(param CallCodeParam) (*execution.Call, error) {
-	call := new(execution.Call)
-	err := vc.CallMethod(CALL_CODE, param, call)
-	if err != nil {
-		return nil, err
-	}
-	return call, nil
-}
-
-func (vc *V0Client) CallMethod(method string, param interface{}, result interface{}) error {
-	// Marhsal into JSONRPC request object
-	bs, err := vc.codec.EncodeBytes(param)
-	if err != nil {
-		return err
-	}
-	request := rpc.NewRPCRequest("test", method, bs)
-	bs, err = json.Marshal(request)
-	if err != nil {
-		return err
-	}
-	// Post to JSONService
-	resp, err := vc.client.Post(vc.url, "application/json", bytes.NewBuffer(bs))
-	if err != nil {
-		return err
-	}
-	// Marshal into JSONRPC response object
-	bs, err = ioutil.ReadAll(resp.Body)
-	if err != nil {
-		return err
-	}
-	rpcResponse := new(RPCResponse)
-	err = json.Unmarshal(bs, rpcResponse)
-	if err != nil {
-		return err
-	}
-	if rpcResponse.Error != nil {
-		return rpcResponse.Error
-	}
-	vc.codec.DecodeBytes(result, rpcResponse.Result)
-	if err != nil {
-		return err
-	}
-	return nil
-}
diff --git a/rpc/v0/codec.go b/rpc/v0/codec.go
deleted file mode 100644
index dc29f3e2fcb89af88b81fe574e4fc1de719da03b..0000000000000000000000000000000000000000
--- a/rpc/v0/codec.go
+++ /dev/null
@@ -1,62 +0,0 @@
-// Copyright 2017 Monax Industries Limited
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//    http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package v0
-
-import (
-	"io"
-	"io/ioutil"
-
-	"encoding/json"
-
-	"github.com/hyperledger/burrow/rpc"
-)
-
-// Codec that uses tendermints 'binary' package for JSON.
-type TCodec struct {
-}
-
-// Get a new codec.
-func NewTCodec() rpc.Codec {
-	return &TCodec{}
-}
-
-// Encode to an io.Writer.
-func (codec *TCodec) Encode(v interface{}, w io.Writer) error {
-	bs, err := codec.EncodeBytes(v)
-	if err != nil {
-		return err
-	}
-	_, err = w.Write(bs)
-	return err
-}
-
-// Encode to a byte array.
-func (codec *TCodec) EncodeBytes(v interface{}) ([]byte, error) {
-	return json.Marshal(v)
-}
-
-// Decode from an io.Reader.
-func (codec *TCodec) Decode(v interface{}, r io.Reader) error {
-	bs, err := ioutil.ReadAll(r)
-	if err != nil {
-		return err
-	}
-	return codec.DecodeBytes(v, bs)
-}
-
-// Decode from a byte array.
-func (codec *TCodec) DecodeBytes(v interface{}, bs []byte) error {
-	return json.Unmarshal(bs, v)
-}
diff --git a/rpc/v0/codec_test.go b/rpc/v0/codec_test.go
deleted file mode 100644
index 500afb1e5c8f8f8ab4adfb42da5c4ceb49bed822..0000000000000000000000000000000000000000
--- a/rpc/v0/codec_test.go
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright 2017 Monax Industries Limited
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//    http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package v0
-
-import (
-	"testing"
-
-	"github.com/hyperledger/burrow/crypto"
-	"github.com/stretchr/testify/assert"
-	"github.com/stretchr/testify/require"
-)
-
-func TestKeysEncoding(t *testing.T) {
-	codec := NewTCodec()
-	privateKey := crypto.PrivateKeyFromSecret("foo", crypto.CurveTypeEd25519)
-	type keyPair struct {
-		PrivateKey crypto.PrivateKey
-		PublicKey  crypto.PublicKey
-	}
-
-	kp := keyPair{
-		PrivateKey: privateKey,
-		PublicKey:  privateKey.GetPublicKey(),
-	}
-
-	bs, err := codec.EncodeBytes(kp)
-	require.NoError(t, err)
-
-	kpOut := keyPair{}
-	codec.DecodeBytes(&kpOut, bs)
-
-	assert.Equal(t, kp, kpOut)
-}
diff --git a/rpc/v0/integration/v0_test.go b/rpc/v0/integration/v0_test.go
deleted file mode 100644
index 563512eb7e8fdff10962b76a0bb7cd8929288119..0000000000000000000000000000000000000000
--- a/rpc/v0/integration/v0_test.go
+++ /dev/null
@@ -1,178 +0,0 @@
-// +build integration
-
-// Space above here matters
-// Copyright 2017 Monax Industries Limited
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//    http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package integration
-
-import (
-	"sync"
-	"testing"
-
-	"github.com/hyperledger/burrow/binary"
-	"github.com/hyperledger/burrow/execution/evm/abi"
-	"github.com/hyperledger/burrow/rpc/test"
-	"github.com/hyperledger/burrow/rpc/v0"
-	"github.com/stretchr/testify/assert"
-	"github.com/stretchr/testify/require"
-)
-
-func TestTransactCallNoCode(t *testing.T) {
-	cli := v0.NewV0Client("http://localhost:1337/rpc")
-
-	// Flip flops between sending private key and input address to test private key and address based signing
-	toAddress := privateAccounts[2].Address()
-
-	numCreates := 1000
-	countCh := test.CommittedTxCount(t, kern.Emitter)
-	for i := 0; i < numCreates; i++ {
-		receipt, err := cli.Transact(v0.TransactParam{
-			InputAccount: inputAccount(i),
-			Address:      toAddress.Bytes(),
-			Data:         []byte{},
-			Fee:          2,
-			GasLimit:     10000 + uint64(i),
-		})
-		require.NoError(t, err)
-		assert.False(t, receipt.CreatesContract)
-		assert.Equal(t, toAddress, receipt.ContractAddress)
-	}
-	require.Equal(t, numCreates, <-countCh)
-}
-
-func TestTransactCreate(t *testing.T) {
-	numGoroutines := 100
-	numCreates := 50
-	wg := new(sync.WaitGroup)
-	wg.Add(numGoroutines)
-	cli := v0.NewV0Client("http://localhost:1337/rpc")
-	// Flip flops between sending private key and input address to test private key and address based signing
-	countCh := test.CommittedTxCount(t, kern.Emitter)
-	for i := 0; i < numGoroutines; i++ {
-		go func() {
-			for j := 0; j < numCreates; j++ {
-				create, err := cli.Transact(v0.TransactParam{
-					InputAccount: inputAccount(i),
-					Address:      nil,
-					Data:         test.Bytecode_strange_loop,
-					Fee:          2,
-					GasLimit:     10000,
-				})
-				if assert.NoError(t, err) {
-					assert.True(t, create.CreatesContract)
-				}
-			}
-			wg.Done()
-		}()
-	}
-	wg.Wait()
-
-	require.Equal(t, numGoroutines*numCreates, <-countCh)
-}
-
-func BenchmarkTransactCreateContract(b *testing.B) {
-	cli := v0.NewV0Client("http://localhost:1337/rpc")
-
-	for i := 0; i < b.N; i++ {
-		create, err := cli.Transact(v0.TransactParam{
-			InputAccount: inputAccount(i),
-			Address:      nil,
-			Data:         test.Bytecode_strange_loop,
-			Fee:          2,
-			GasLimit:     10000,
-		})
-		require.NoError(b, err)
-		assert.True(b, create.CreatesContract)
-	}
-}
-
-func TestTransactAndHold(t *testing.T) {
-	cli := v0.NewV0Client("http://localhost:1337/rpc")
-
-	numGoroutines := 5
-	numRuns := 2
-	countCh := test.CommittedTxCount(t, kern.Emitter)
-	for i := 0; i < numGoroutines; i++ {
-		for j := 0; j < numRuns; j++ {
-			create, err := cli.TransactAndHold(v0.TransactParam{
-				InputAccount: inputAccount(i),
-				Address:      nil,
-				Data:         test.Bytecode_strange_loop,
-				Fee:          2,
-				GasLimit:     10000,
-			})
-			require.NoError(t, err)
-			assert.Equal(t, uint64(0), create.StackDepth)
-			functionID := abi.FunctionID("UpsieDownsie()")
-			call, err := cli.TransactAndHold(v0.TransactParam{
-				InputAccount: inputAccount(i),
-				Address:      create.CallData.Callee.Bytes(),
-				Data:         functionID[:],
-				Fee:          2,
-				GasLimit:     10000,
-			})
-			require.NoError(t, err)
-			depth := binary.Uint64FromWord256(binary.LeftPadWord256(call.Return))
-			// Would give 23 if taken from wrong frame
-			assert.Equal(t, 18, int(depth))
-		}
-	}
-	require.Equal(t, numGoroutines*numRuns*2, <-countCh)
-}
-
-func TestSend(t *testing.T) {
-	cli := v0.NewV0Client("http://localhost:1337/rpc")
-	numSends := 1000
-	countCh := test.CommittedTxCount(t, kern.Emitter)
-	for i := 0; i < numSends; i++ {
-		send, err := cli.Send(v0.SendParam{
-			InputAccount: inputAccount(i),
-			Amount:       2003,
-			ToAddress:    privateAccounts[3].Address().Bytes(),
-		})
-		require.NoError(t, err)
-		assert.Equal(t, false, send.CreatesContract)
-	}
-	require.Equal(t, numSends, <-countCh)
-}
-
-func TestSendAndHold(t *testing.T) {
-	cli := v0.NewV0Client("http://localhost:1337/rpc")
-
-	for i := 0; i < 2; i++ {
-		send, err := cli.SendAndHold(v0.SendParam{
-			InputAccount: inputAccount(i),
-			Amount:       2003,
-			ToAddress:    privateAccounts[3].Address().Bytes(),
-		})
-		require.NoError(t, err)
-		assert.Equal(t, false, send.CreatesContract)
-	}
-}
-
-// Helpers
-
-var inputPrivateKey = privateAccounts[0].PrivateKey().RawBytes()
-var inputAddress = privateAccounts[0].Address().Bytes()
-
-func inputAccount(i int) v0.InputAccount {
-	ia := v0.InputAccount{}
-	if i%2 == 0 {
-		ia.PrivateKey = inputPrivateKey
-	} else {
-		ia.Address = inputAddress
-	}
-	return ia
-}
diff --git a/rpc/v0/json_service.go b/rpc/v0/json_service.go
deleted file mode 100644
index 41595de660ede4e892f287403ca9a76098c4c4f3..0000000000000000000000000000000000000000
--- a/rpc/v0/json_service.go
+++ /dev/null
@@ -1,219 +0,0 @@
-// Copyright 2017 Monax Industries Limited
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//    http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package v0
-
-import (
-	"context"
-	"encoding/json"
-	"net/http"
-
-	"github.com/gin-gonic/gin"
-	"github.com/hyperledger/burrow/logging"
-	"github.com/hyperledger/burrow/rpc"
-	"github.com/hyperledger/burrow/rpc/v0/server"
-)
-
-// EventSubscribe
-type EventSub struct {
-	SubId string `json:"subId"`
-}
-
-// EventUnsubscribe
-type EventUnsub struct {
-	Result bool `json:"result"`
-}
-
-// EventPoll
-type PollResponse struct {
-	Events []interface{} `json:"events"`
-}
-
-// Server used to handle JSON-RPC 2.0 requests. Implements server.Server
-type JsonRpcServer struct {
-	service server.HttpService
-	running bool
-}
-
-// Create a new JsonRpcServer
-func NewJSONServer(service server.HttpService) *JsonRpcServer {
-	return &JsonRpcServer{service: service}
-}
-
-// Start adds the rpc path to the router.
-func (jrs *JsonRpcServer) Start(config *server.ServerConfig, router *gin.Engine) {
-	router.POST(config.HTTP.JsonRpcEndpoint, jrs.handleFunc)
-	jrs.running = true
-}
-
-// Is the server currently running?
-func (jrs *JsonRpcServer) Running() bool {
-	return jrs.running
-}
-
-// Shut the server down. Does nothing.
-func (jrs *JsonRpcServer) Shutdown(ctx context.Context) error {
-	jrs.running = false
-	return nil
-}
-
-// Handler passes message on directly to the service which expects
-// a normal http request and response writer.
-func (jrs *JsonRpcServer) handleFunc(c *gin.Context) {
-	r := c.Request
-	w := c.Writer
-
-	jrs.service.Process(r, w)
-}
-
-// Used for Burrow. Implements server.HttpService
-type JSONService struct {
-	codec           rpc.Codec
-	service         *rpc.Service
-	eventSubs       *rpc.Subscriptions
-	defaultHandlers map[string]RequestHandlerFunc
-	logger          *logging.Logger
-}
-
-// Create a new JSON-RPC 2.0 service for burrow (tendermint).
-func NewJSONService(codec rpc.Codec, service *rpc.Service, logger *logging.Logger) server.HttpService {
-
-	tmhttps := &JSONService{
-		codec:     codec,
-		service:   service,
-		eventSubs: rpc.NewSubscriptions(service),
-		logger:    logger.WithScope("NewJSONService"),
-	}
-
-	dhMap := GetMethods(codec, service, tmhttps.logger)
-	// Events
-	dhMap[EVENT_SUBSCRIBE] = tmhttps.EventSubscribe
-	dhMap[EVENT_UNSUBSCRIBE] = tmhttps.EventUnsubscribe
-	dhMap[EVENT_POLL] = tmhttps.EventPoll
-	tmhttps.defaultHandlers = dhMap
-	return tmhttps
-}
-
-// Process a request.
-func (js *JSONService) Process(r *http.Request, w http.ResponseWriter) {
-
-	// Create new request object and unmarshal.
-	req := &rpc.RPCRequest{}
-	decoder := json.NewDecoder(r.Body)
-	errU := decoder.Decode(req)
-
-	// Error when decoding.
-	if errU != nil {
-		js.writeError("Failed to parse request: "+errU.Error(), "",
-			rpc.PARSE_ERROR, w)
-		return
-	}
-
-	// Wrong protocol version.
-	if req.JSONRPC != "2.0" {
-		js.writeError("Wrong protocol version: "+req.JSONRPC, req.Id,
-			rpc.INVALID_REQUEST, w)
-		return
-	}
-
-	mName := req.Method
-
-	if handler, ok := js.defaultHandlers[mName]; ok {
-		js.logger.TraceMsg("Request received",
-			"id", req.Id,
-			"method", req.Method)
-		resp, errCode, err := handler(req, w)
-		if err != nil {
-			js.writeError(err.Error(), req.Id, errCode, w)
-		} else {
-			js.writeResponse(req.Id, resp, w)
-		}
-	} else {
-		js.writeError("Method not found: "+mName, req.Id, rpc.METHOD_NOT_FOUND, w)
-	}
-}
-
-// Helper for writing error responses.
-func (js *JSONService) writeError(msg, id string, code int, w http.ResponseWriter) {
-	response := rpc.NewRPCErrorResponse(id, code, msg)
-	err := js.codec.Encode(response, w)
-	// If there's an error here all bets are off.
-	if err != nil {
-		http.Error(w, "Failed to marshal standard error response: "+err.Error(), 500)
-		return
-	}
-	w.WriteHeader(200)
-}
-
-// Helper for writing responses.
-func (js *JSONService) writeResponse(id string, result interface{}, w http.ResponseWriter) {
-	response := rpc.NewRPCResponse(id, result)
-	err := js.codec.Encode(response, w)
-	if err != nil {
-		js.writeError("Internal error: "+err.Error(), id, rpc.INTERNAL_ERROR, w)
-		return
-	}
-	w.WriteHeader(200)
-}
-
-// *************************************** Events ************************************
-
-// Subscribe to an
-func (js *JSONService) EventSubscribe(request *rpc.RPCRequest,
-	requester interface{}) (interface{}, int, error) {
-	param := &EventIdParam{}
-	err := json.Unmarshal(request.Params, param)
-	if err != nil {
-		return nil, rpc.INVALID_PARAMS, err
-	}
-	eventId := param.EventId
-	subId, errC := js.eventSubs.Add(eventId)
-	if errC != nil {
-		return nil, rpc.INTERNAL_ERROR, errC
-	}
-	return &EventSub{subId}, 0, nil
-}
-
-// Un-subscribe from an
-func (js *JSONService) EventUnsubscribe(request *rpc.RPCRequest, requester interface{}) (interface{}, int, error) {
-	param := &SubIdParam{}
-	err := json.Unmarshal(request.Params, param)
-	if err != nil {
-		return nil, rpc.INVALID_PARAMS, err
-	}
-	subId := param.SubId
-
-	err = js.service.Unsubscribe(context.Background(), subId)
-	if err != nil {
-		return nil, rpc.INTERNAL_ERROR, err
-	}
-	return &EventUnsub{true}, 0, nil
-}
-
-// Check subscription event cache for new data.
-func (js *JSONService) EventPoll(request *rpc.RPCRequest,
-	requester interface{}) (interface{}, int, error) {
-	param := &SubIdParam{}
-	err := json.Unmarshal(request.Params, param)
-	if err != nil {
-		return nil, rpc.INVALID_PARAMS, err
-	}
-	subId := param.SubId
-
-	result, errC := js.eventSubs.Poll(subId)
-	if errC != nil {
-		return nil, rpc.INTERNAL_ERROR, errC
-	}
-	return &PollResponse{result}, 0, nil
-}
diff --git a/rpc/v0/json_service_data_test.go b/rpc/v0/json_service_data_test.go
deleted file mode 100644
index c258c4c2ca3f2b1275d1d4743779586a5b0f740a..0000000000000000000000000000000000000000
--- a/rpc/v0/json_service_data_test.go
+++ /dev/null
@@ -1,74 +0,0 @@
-// Copyright 2017 Monax Industries Limited
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//  http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package v0
-
-import (
-	"encoding/json"
-	"fmt"
-	"testing"
-
-	acm "github.com/hyperledger/burrow/account"
-	"github.com/hyperledger/burrow/rpc"
-	"github.com/hyperledger/burrow/txs"
-	"github.com/hyperledger/burrow/txs/payload"
-	"github.com/stretchr/testify/assert"
-	"github.com/stretchr/testify/require"
-)
-
-var txEnvelopeString = `{"Signatories":[{"Address":"83207817DC3814B96F57EFF925F467E07CAA9138","PublicKey":{"CurveType":"ed25519",` +
-	`"PublicKey":"34D26579DBB456693E540672CF922F52DDE0D6532E35BF06BE013A7C532F20E0"},` +
-	`"Signature":"5042F208824AA5AF8E03B2F11FB8CFCDDAE4F889B2F720714627395406E00D7740B2DB5B5F93BD6C13DED9B7C1FD5FB0DB4ECA31E6DA0B81033A72922076E90C"}],` +
-	`"Tx":{"ChainID":"testChain","Type":"CallTx","Payload":{"Input":{"Address":"83207817DC3814B96F57EFF925F467E07CAA9138","Amount":343,"Sequence":3},` +
-	`"Address":"AC280D53FD359D9FF11F19D0796D9B89907F3B53","GasLimit":2323,"Fee":12,"Data":"03040505"}}}`
-
-var testBroadcastCallTxJsonRequest = []byte(`
-{
-  "id": "57EC1D39-7B3D-4F96-B286-8FC128177AFC4",
-  "jsonrpc": "2.0",
-  "method": "burrow.broadcastTx",
-  "params": ` + txEnvelopeString + `
-}`)
-
-// strictly test the codec for go-wire encoding of the Json format,
-// This should restore compatibility with the format on v0.11.4
-// (which was broken on v0.12)
-func fixTestCallTxJsonFormatCodec(t *testing.T) {
-	codec := NewTCodec()
-	txEnv := new(txs.Envelope)
-	// Create new request object and unmarshal.
-	request := &rpc.RPCRequest{}
-	assert.NoError(t, json.Unmarshal(testBroadcastCallTxJsonRequest, request),
-		"Provided JSON test data does not unmarshal to rpc.RPCRequest object.")
-	assert.NoError(t, codec.DecodeBytes(txEnv, request.Params),
-		"RPC codec failed to decode params as transaction type.")
-	_, ok := txEnv.Tx.Payload.(*payload.CallTx)
-	assert.True(t, ok, "Type byte 0x02 should unmarshal into CallTx.")
-}
-
-func TestGenTxEnvelope(t *testing.T) {
-	codec := NewTCodec()
-	privAccFrom := acm.GeneratePrivateAccountFromSecret("foo")
-	privAccTo := acm.GeneratePrivateAccountFromSecret("bar")
-	toAddress := privAccTo.Address()
-	txEnv := txs.Enclose("testChain", payload.NewCallTxWithSequence(privAccFrom.PublicKey(), &toAddress,
-		[]byte{3, 4, 5, 5}, 343, 2323, 12, 3))
-	err := txEnv.Sign(privAccFrom)
-	require.NoError(t, err)
-	bs, err := codec.EncodeBytes(txEnv)
-	require.NoError(t, err)
-	if !assert.Equal(t, txEnvelopeString, string(bs)) {
-		fmt.Println(string(bs))
-	}
-}
diff --git a/rpc/v0/json_service_test.go b/rpc/v0/json_service_test.go
deleted file mode 100644
index 23ec7620908b691326cff65c5c13095ea8cedb7d..0000000000000000000000000000000000000000
--- a/rpc/v0/json_service_test.go
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright 2017 Monax Industries Limited
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//    http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package v0
-
-import (
-	"encoding/json"
-	"fmt"
-	"testing"
-
-	"github.com/stretchr/testify/require"
-)
-
-func TestPollResponse(t *testing.T) {
-	pr := PollResponse{}
-	bs, err := json.Marshal(pr)
-	require.NoError(t, err)
-	fmt.Println(string(bs))
-}
diff --git a/rpc/v0/methods.go b/rpc/v0/methods.go
deleted file mode 100644
index 7b510f23c169c54abb1215027409fee7885cf212..0000000000000000000000000000000000000000
--- a/rpc/v0/methods.go
+++ /dev/null
@@ -1,455 +0,0 @@
-// Copyright 2017 Monax Industries Limited
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//    http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package v0
-
-import (
-	"context"
-
-	acm "github.com/hyperledger/burrow/account"
-	"github.com/hyperledger/burrow/crypto"
-	"github.com/hyperledger/burrow/execution/names"
-	"github.com/hyperledger/burrow/logging"
-	"github.com/hyperledger/burrow/rpc"
-	"github.com/hyperledger/burrow/rpc/filters"
-	"github.com/hyperledger/burrow/txs"
-)
-
-// TODO use the method name definition file.
-const (
-	SERVICE_NAME = "burrow"
-
-	GET_ACCOUNTS              = SERVICE_NAME + ".getAccounts" // Accounts
-	GET_ACCOUNT               = SERVICE_NAME + ".getAccount"
-	GET_STORAGE               = SERVICE_NAME + ".getStorage"
-	GET_STORAGE_AT            = SERVICE_NAME + ".getStorageAt"
-	GEN_PRIV_ACCOUNT          = SERVICE_NAME + ".genPrivAccount"
-	GEN_PRIV_ACCOUNT_FROM_KEY = SERVICE_NAME + ".genPrivAccountFromKey"
-	GET_BLOCKCHAIN_INFO       = SERVICE_NAME + ".getBlockchainInfo" // Blockchain
-	GET_LATEST_BLOCK          = SERVICE_NAME + ".getLatestBlock"
-	GET_BLOCKS                = SERVICE_NAME + ".getBlocks"
-	GET_BLOCK                 = SERVICE_NAME + ".getBlock"
-	GET_CONSENSUS_STATE       = SERVICE_NAME + ".getConsensusState" // Consensus
-	GET_VALIDATORS            = SERVICE_NAME + ".getValidators"
-	GET_NETWORK_INFO          = SERVICE_NAME + ".getNetworkInfo" // Net
-	GET_CHAIN_ID              = SERVICE_NAME + ".getChainId"
-	GET_PEERS                 = SERVICE_NAME + ".getPeers"
-	CALL                      = SERVICE_NAME + ".call" // Tx
-	CALL_CODE                 = SERVICE_NAME + ".callCode"
-	BROADCAST_TX              = SERVICE_NAME + ".broadcastTx"
-	GET_UNCONFIRMED_TXS       = SERVICE_NAME + ".getUnconfirmedTxs"
-	SIGN_TX                   = SERVICE_NAME + ".signTx"
-	TRANSACT                  = SERVICE_NAME + ".transact"
-	TRANSACT_AND_HOLD         = SERVICE_NAME + ".transactAndHold"
-	SEND                      = SERVICE_NAME + ".send"
-	SEND_AND_HOLD             = SERVICE_NAME + ".sendAndHold"
-	TRANSACT_NAMEREG          = SERVICE_NAME + ".transactNameReg"
-	EVENT_SUBSCRIBE           = SERVICE_NAME + ".eventSubscribe" // Events
-	EVENT_UNSUBSCRIBE         = SERVICE_NAME + ".eventUnsubscribe"
-	EVENT_POLL                = SERVICE_NAME + ".eventPoll"
-	GET_NAMEREG_ENTRY         = SERVICE_NAME + ".getNameRegEntry" // Namereg
-	GET_NAMEREG_ENTRIES       = SERVICE_NAME + ".getNameRegEntries"
-)
-
-// Used to handle requests. interface{} param is a wildcard used for example with socket events.
-type RequestHandlerFunc func(request *rpc.RPCRequest, requester interface{}) (interface{}, int, error)
-
-// Private. Create a method name -> method handler map.
-func GetMethods(codec rpc.Codec, service *rpc.Service, logger *logging.Logger) map[string]RequestHandlerFunc {
-	accountFilterFactory := filters.NewAccountFilterFactory()
-	nameRegFilterFactory := filters.NewNameRegFilterFactory()
-	return map[string]RequestHandlerFunc{
-		// Accounts
-		GET_ACCOUNTS: func(request *rpc.RPCRequest, requester interface{}) (interface{}, int, error) {
-			param := &FilterListParam{}
-			if len(request.Params) > 0 {
-				err := codec.DecodeBytes(param, request.Params)
-				if err != nil {
-					return nil, rpc.INVALID_PARAMS, err
-				}
-			}
-			filter, err := accountFilterFactory.NewFilter(param.Filters)
-			if err != nil {
-				return nil, rpc.INVALID_PARAMS, err
-			}
-			list, err := service.ListAccounts(func(account acm.Account) bool {
-				return filter.Match(account)
-
-			})
-			if err != nil {
-				return nil, rpc.INTERNAL_ERROR, err
-			}
-			return list, 0, nil
-		},
-		GET_ACCOUNT: func(request *rpc.RPCRequest, requester interface{}) (interface{}, int, error) {
-			param := &AddressParam{}
-			err := codec.DecodeBytes(param, request.Params)
-			if err != nil {
-				return nil, rpc.INVALID_PARAMS, err
-			}
-			address, err := crypto.AddressFromBytes(param.Address)
-			if err != nil {
-				return nil, rpc.INVALID_PARAMS, err
-			}
-			account, err := service.GetAccount(address)
-			if err != nil {
-				return nil, rpc.INTERNAL_ERROR, err
-			}
-			return account, 0, nil
-		},
-		GET_STORAGE: func(request *rpc.RPCRequest, requester interface{}) (interface{}, int, error) {
-			param := &AddressParam{}
-			err := codec.DecodeBytes(param, request.Params)
-			if err != nil {
-				return nil, rpc.INVALID_PARAMS, err
-			}
-			address, err := crypto.AddressFromBytes(param.Address)
-			if err != nil {
-				return nil, rpc.INVALID_PARAMS, err
-			}
-			storage, err := service.DumpStorage(address)
-			if err != nil {
-				return nil, rpc.INTERNAL_ERROR, err
-			}
-			return storage, 0, nil
-		},
-		GET_STORAGE_AT: func(request *rpc.RPCRequest, requester interface{}) (interface{}, int, error) {
-			param := &StorageAtParam{}
-			err := codec.DecodeBytes(param, request.Params)
-			if err != nil {
-				return nil, rpc.INVALID_PARAMS, err
-			}
-			address, err := crypto.AddressFromBytes(param.Address)
-			if err != nil {
-				return nil, rpc.INVALID_PARAMS, err
-			}
-			storageItem, err := service.GetStorage(address, param.Key)
-			if err != nil {
-				return nil, rpc.INTERNAL_ERROR, err
-			}
-			return storageItem, 0, nil
-		},
-		GEN_PRIV_ACCOUNT: func(request *rpc.RPCRequest, requester interface{}) (interface{}, int, error) {
-			pa, err := acm.GeneratePrivateAccount()
-			if err != nil {
-				return nil, rpc.INTERNAL_ERROR, err
-			}
-			return acm.AsConcretePrivateAccount(pa), 0, nil
-		},
-		GEN_PRIV_ACCOUNT_FROM_KEY: func(request *rpc.RPCRequest, requester interface{}) (interface{}, int, error) {
-			param := &PrivateKeyParam{}
-			err := codec.DecodeBytes(param, request.Params)
-			if err != nil {
-				return nil, rpc.INVALID_PARAMS, err
-			}
-			pa, err := acm.GeneratePrivateAccountFromPrivateKeyBytes(param.PrivateKey)
-			if err != nil {
-				return nil, rpc.INTERNAL_ERROR, err
-			}
-			return acm.AsConcretePrivateAccount(pa), 0, nil
-		},
-		// Txs
-		CALL: func(request *rpc.RPCRequest, requester interface{}) (interface{}, int, error) {
-			param := &CallParam{}
-			err := codec.DecodeBytes(param, request.Params)
-			if err != nil {
-				return nil, rpc.INVALID_PARAMS, err
-			}
-			from, err := crypto.AddressFromBytes(param.From)
-			if err != nil {
-				return nil, rpc.INVALID_PARAMS, err
-			}
-			address, err := crypto.AddressFromBytes(param.Address)
-			if err != nil {
-				return nil, rpc.INVALID_PARAMS, err
-			}
-			call, err := service.Transactor().Call(service.MempoolAccounts(), from, address, param.Data)
-			if err != nil {
-				return nil, rpc.INTERNAL_ERROR, err
-			}
-			return call, 0, nil
-		},
-		CALL_CODE: func(request *rpc.RPCRequest, requester interface{}) (interface{}, int, error) {
-			param := &CallCodeParam{}
-			err := codec.DecodeBytes(param, request.Params)
-			if err != nil {
-				return nil, rpc.INVALID_PARAMS, err
-			}
-			from, err := crypto.AddressFromBytes(param.From)
-			if err != nil {
-				return nil, rpc.INVALID_PARAMS, err
-			}
-			call, err := service.Transactor().CallCode(service.MempoolAccounts(), from, param.Code, param.Data)
-			if err != nil {
-				return nil, rpc.INTERNAL_ERROR, err
-			}
-			return call, 0, nil
-		},
-		BROADCAST_TX: func(request *rpc.RPCRequest, requester interface{}) (interface{}, int, error) {
-			// Accept all transaction types as parameter for broadcast.
-			txEnv := new(txs.Envelope)
-			err := codec.DecodeBytes(txEnv, request.Params)
-			if err != nil {
-				return nil, rpc.INVALID_PARAMS, err
-			}
-			receipt, err := service.Transactor().BroadcastTx(txEnv)
-			if err != nil {
-				return nil, rpc.INTERNAL_ERROR, err
-			}
-			return receipt, 0, nil
-		},
-		SIGN_TX: func(request *rpc.RPCRequest, requester interface{}) (interface{}, int, error) {
-			param := &SignTxParam{}
-			err := codec.DecodeBytes(param, request.Params)
-			if err != nil {
-				return nil, rpc.INVALID_PARAMS, err
-			}
-			txRet, err := service.Transactor().SignTx(txs.Enclose(service.BlockchainInfo().ChainID(), param.Tx),
-				acm.SigningAccounts(param.PrivateAccounts))
-			if err != nil {
-				return nil, rpc.INTERNAL_ERROR, err
-			}
-			return txRet, 0, nil
-		},
-		TRANSACT: func(request *rpc.RPCRequest, requester interface{}) (interface{}, int, error) {
-			param := &TransactParam{}
-			err := codec.DecodeBytes(param, request.Params)
-			if err != nil {
-				return nil, rpc.INVALID_PARAMS, err
-			}
-			address, err := crypto.MaybeAddressFromBytes(param.Address)
-			if err != nil {
-				return nil, rpc.INVALID_PARAMS, err
-			}
-			// Use mempool state so that transact can generate a run of sequence numbers when formulating transactions
-			inputAccount, err := service.MempoolAccounts().GetSequentialSigningAccount(param.InputAccount.Address,
-				param.InputAccount.PrivateKey)
-			if err != nil {
-				return nil, rpc.INVALID_PARAMS, err
-			}
-			// We ensure zero value transfer for legacy compatibility reason (i.e. we always have)
-			receipt, err := service.Transactor().Transact(inputAccount, address, param.Data, param.GasLimit, 0,
-				param.Fee)
-			if err != nil {
-				return nil, rpc.INTERNAL_ERROR, err
-			}
-			return receipt, 0, nil
-		},
-		TRANSACT_AND_HOLD: func(request *rpc.RPCRequest, requester interface{}) (interface{}, int, error) {
-			param := &TransactParam{}
-			err := codec.DecodeBytes(param, request.Params)
-			if err != nil {
-				return nil, rpc.INVALID_PARAMS, err
-			}
-			address, err := crypto.MaybeAddressFromBytes(param.Address)
-			if err != nil {
-				return nil, rpc.INVALID_PARAMS, err
-			}
-			inputAccount, err := service.MempoolAccounts().GetSequentialSigningAccount(param.InputAccount.Address,
-				param.InputAccount.PrivateKey)
-			if err != nil {
-				return nil, rpc.INVALID_PARAMS, err
-			}
-			// We ensure zero value transfer for legacy compatibility reason (i.e. we always have)
-			eventDataCall, err := service.Transactor().TransactAndHold(context.Background(), inputAccount, address,
-				param.Data, param.GasLimit, 0, param.Fee)
-			if err != nil {
-				return nil, rpc.INTERNAL_ERROR, err
-			}
-			return eventDataCall, 0, nil
-		},
-		SEND: func(request *rpc.RPCRequest, requester interface{}) (interface{}, int, error) {
-			param := &SendParam{}
-			err := codec.DecodeBytes(param, request.Params)
-			if err != nil {
-				return nil, rpc.INVALID_PARAMS, err
-			}
-			toAddress, err := crypto.AddressFromBytes(param.ToAddress)
-			if err != nil {
-				return nil, rpc.INVALID_PARAMS, err
-			}
-			// Run Send against mempool state
-			inputAccount, err := service.MempoolAccounts().GetSequentialSigningAccount(param.InputAccount.Address,
-				param.InputAccount.PrivateKey)
-			if err != nil {
-				return nil, rpc.INVALID_PARAMS, err
-			}
-			receipt, err := service.Transactor().Send(inputAccount, toAddress, param.Amount)
-			if err != nil {
-				return nil, rpc.INTERNAL_ERROR, err
-			}
-			return receipt, 0, nil
-		},
-		SEND_AND_HOLD: func(request *rpc.RPCRequest, requester interface{}) (interface{}, int, error) {
-			param := &SendParam{}
-			err := codec.DecodeBytes(param, request.Params)
-			if err != nil {
-				return nil, rpc.INVALID_PARAMS, err
-			}
-			toAddress, err := crypto.AddressFromBytes(param.ToAddress)
-			if err != nil {
-				return nil, rpc.INVALID_PARAMS, err
-			}
-			// Run Send against mempool state
-			inputAccount, err := service.MempoolAccounts().GetSequentialSigningAccount(param.InputAccount.Address,
-				param.InputAccount.PrivateKey)
-			if err != nil {
-				return nil, rpc.INVALID_PARAMS, err
-			}
-			rec, err := service.Transactor().SendAndHold(context.Background(), inputAccount, toAddress, param.Amount)
-			if err != nil {
-				return nil, rpc.INTERNAL_ERROR, err
-			}
-			return rec, 0, nil
-		},
-		TRANSACT_NAMEREG: func(request *rpc.RPCRequest, requester interface{}) (interface{}, int, error) {
-			param := &TransactNameRegParam{}
-			err := codec.DecodeBytes(param, request.Params)
-			if err != nil {
-				return nil, rpc.INVALID_PARAMS, err
-			}
-			inputAccount, err := service.MempoolAccounts().GetSequentialSigningAccount(param.InputAccount.Address,
-				param.InputAccount.PrivateKey)
-			if err != nil {
-				return nil, rpc.INVALID_PARAMS, err
-			}
-			receipt, err := service.Transactor().TransactNameReg(inputAccount, param.Name, param.Data, param.Amount, param.Fee)
-			if err != nil {
-				return nil, rpc.INTERNAL_ERROR, err
-			}
-			return receipt, 0, nil
-		},
-
-		// Namereg
-		GET_NAMEREG_ENTRY: func(request *rpc.RPCRequest, requester interface{}) (interface{}, int, error) {
-			param := &NameRegEntryParam{}
-			err := codec.DecodeBytes(param, request.Params)
-			if err != nil {
-				return nil, rpc.INVALID_PARAMS, err
-			}
-			name := param.Name
-			// TODO is address check?
-			resultGetName, err := service.GetName(name)
-			if err != nil {
-				return nil, rpc.INTERNAL_ERROR, err
-			}
-			return resultGetName.Entry, 0, nil
-		},
-		GET_NAMEREG_ENTRIES: func(request *rpc.RPCRequest, requester interface{}) (interface{}, int, error) {
-			param := &FilterListParam{}
-			err := codec.DecodeBytes(param, request.Params)
-			if err != nil {
-				return nil, rpc.INVALID_PARAMS, err
-			}
-			filter, err := nameRegFilterFactory.NewFilter(param.Filters)
-			if err != nil {
-				return nil, rpc.INVALID_PARAMS, err
-			}
-			list, err := service.ListNames(func(entry *names.Entry) bool {
-				return filter.Match(entry)
-			})
-			if err != nil {
-				return nil, rpc.INTERNAL_ERROR, err
-			}
-			return list, 0, nil
-		},
-		// Blockchain
-		GET_BLOCKCHAIN_INFO: func(request *rpc.RPCRequest, requester interface{}) (interface{}, int, error) {
-			resultStatus, err := service.Status()
-			if err != nil {
-				return nil, rpc.INTERNAL_ERROR, err
-			}
-			return resultStatus, 0, nil
-		},
-		GET_LATEST_BLOCK: func(request *rpc.RPCRequest, requester interface{}) (interface{}, int, error) {
-			stat, err := service.Status()
-			if err != nil {
-				return nil, rpc.INTERNAL_ERROR, err
-			}
-			resultGetBlock, err := service.GetBlock(stat.LatestBlockHeight)
-			if err != nil {
-				return nil, rpc.INTERNAL_ERROR, err
-			}
-			return resultGetBlock, 0, nil
-		},
-		GET_BLOCKS: func(request *rpc.RPCRequest, requester interface{}) (interface{}, int, error) {
-			param := &BlocksParam{}
-			err := codec.DecodeBytes(param, request.Params)
-			if err != nil {
-				return nil, rpc.INVALID_PARAMS, err
-			}
-			blocks, err := service.ListBlocks(param.MinHeight, param.MaxHeight)
-			if err != nil {
-				return nil, rpc.INTERNAL_ERROR, err
-			}
-			return blocks, 0, nil
-		},
-		GET_BLOCK: func(request *rpc.RPCRequest, requester interface{}) (interface{}, int, error) {
-			param := &HeightParam{}
-			err := codec.DecodeBytes(param, request.Params)
-			if err != nil {
-				return nil, rpc.INVALID_PARAMS, err
-			}
-			block, err := service.GetBlock(param.Height)
-			if err != nil {
-				return nil, rpc.INTERNAL_ERROR, err
-			}
-			return block, 0, nil
-		},
-		GET_UNCONFIRMED_TXS: func(request *rpc.RPCRequest, requester interface{}) (interface{}, int, error) {
-			trans, err := service.ListUnconfirmedTxs(-1)
-			if err != nil {
-				return nil, rpc.INTERNAL_ERROR, err
-			}
-			return trans, 0, nil
-		},
-		// Consensus
-		GET_CONSENSUS_STATE: func(request *rpc.RPCRequest, requester interface{}) (interface{}, int, error) {
-			resultDumpConsensusState, err := service.DumpConsensusState()
-			if err != nil {
-				return nil, rpc.INTERNAL_ERROR, err
-			}
-			return resultDumpConsensusState, 0, nil
-		},
-		GET_VALIDATORS: func(request *rpc.RPCRequest, requester interface{}) (interface{}, int, error) {
-			resultListValidators, err := service.ListValidators()
-			if err != nil {
-				return nil, rpc.INTERNAL_ERROR, err
-			}
-			return resultListValidators, 0, nil
-		},
-		// Network
-		GET_NETWORK_INFO: func(request *rpc.RPCRequest, requester interface{}) (interface{}, int, error) {
-			resultNetInfo, err := service.NetInfo()
-			if err != nil {
-				return nil, rpc.INTERNAL_ERROR, err
-			}
-			return resultNetInfo, 0, nil
-		},
-		GET_CHAIN_ID: func(request *rpc.RPCRequest, requester interface{}) (interface{}, int, error) {
-			resultChainID, err := service.ChainIdentifiers()
-			if err != nil {
-				return nil, rpc.INTERNAL_ERROR, err
-			}
-			return resultChainID, 0, nil
-		},
-		GET_PEERS: func(request *rpc.RPCRequest, requester interface{}) (interface{}, int, error) {
-			resultPeers, err := service.Peers()
-			if err != nil {
-				return nil, rpc.INTERNAL_ERROR, err
-			}
-			return resultPeers, 0, nil
-		},
-	}
-}
diff --git a/rpc/v0/params.go b/rpc/v0/params.go
deleted file mode 100644
index b84c131e18d89d24d55acf0537b851dc90067be7..0000000000000000000000000000000000000000
--- a/rpc/v0/params.go
+++ /dev/null
@@ -1,124 +0,0 @@
-// Copyright 2017 Monax Industries Limited
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//    http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package v0
-
-import (
-	acm "github.com/hyperledger/burrow/account"
-	"github.com/hyperledger/burrow/binary"
-	"github.com/hyperledger/burrow/rpc/filters"
-	"github.com/hyperledger/burrow/txs/payload"
-)
-
-type (
-	// Used to send an address. The address should be hex and properly formatted.
-	AddressParam struct {
-		Address binary.HexBytes `json:"address"`
-	}
-
-	// Used to send an address
-	FilterListParam struct {
-		Filters []*filters.FilterData `json:"filters"`
-	}
-
-	PrivateKeyParam struct {
-		PrivateKey binary.HexBytes `json:"privateKey"`
-	}
-
-	InputAccount struct {
-		PrivateKey binary.HexBytes `json:"privateKey"`
-		Address    binary.HexBytes `json:"address"`
-	}
-
-	// StorageAt
-	StorageAtParam struct {
-		Address binary.HexBytes `json:"address"`
-		Key     binary.HexBytes `json:"key"`
-	}
-
-	// Get a block
-	HeightParam struct {
-		Height uint64 `json:"height"`
-	}
-
-	BlocksParam struct {
-		MinHeight uint64 `json:"minHeight"`
-		MaxHeight uint64 `json:"maxHeight"`
-	}
-
-	// Event Id
-	EventIdParam struct {
-		EventId string `json:"eventId"`
-	}
-
-	// Event Id
-	SubIdParam struct {
-		SubId string `json:"subId"`
-	}
-
-	PeerParam struct {
-		Address string `json:"address"`
-	}
-
-	// Used when doing calls
-	CallParam struct {
-		Address binary.HexBytes `json:"address"`
-		From    binary.HexBytes `json:"from"`
-		Data    binary.HexBytes `json:"data"`
-	}
-
-	// Used when doing code calls
-	CallCodeParam struct {
-		From binary.HexBytes `json:"from"`
-		Code binary.HexBytes `json:"code"`
-		Data binary.HexBytes `json:"data"`
-	}
-
-	// Used when signing a tx. Uses placeholders just like TxParam
-	SignTxParam struct {
-		Tx              *payload.CallTx               `json:"tx"`
-		PrivateAccounts []*acm.ConcretePrivateAccount `json:"privateAccounts"`
-	}
-
-	// Used when sending a transaction to be created and signed on the server
-	// (using the private key). This only uses the standard key type for now.
-	TransactParam struct {
-		InputAccount InputAccount    `json:"inputAccount"`
-		Data         binary.HexBytes `json:"data"`
-		Address      binary.HexBytes `json:"address"`
-		Fee          uint64          `json:"fee"`
-		GasLimit     uint64          `json:"gasLimit"`
-	}
-
-	// Used when sending a 'Send' transaction.
-	SendParam struct {
-		InputAccount InputAccount    `json:"inputAccount"`
-		ToAddress    binary.HexBytes `json:"toAddress"`
-		Amount       uint64          `json:"amount"`
-	}
-
-	NameRegEntryParam struct {
-		Name string `json:"name"`
-	}
-
-	// Used when sending a namereg transaction to be created and signed on the server
-	// (using the private key). This only uses the standard key type for now.
-	TransactNameRegParam struct {
-		InputAccount InputAccount `json:"inputAccount"`
-		Name         string       `json:"name"`
-		Data         string       `json:"data"`
-		Fee          uint64       `json:"fee"`
-		Amount       uint64       `json:"amount"`
-	}
-)
diff --git a/rpc/v0/server/README.md b/rpc/v0/server/README.md
deleted file mode 100644
index 14526e2b6ff47541494c06907be7463923e54187..0000000000000000000000000000000000000000
--- a/rpc/v0/server/README.md
+++ /dev/null
@@ -1,33 +0,0 @@
-# Server
-
-This package contains classes for starting and running HTTP and websocket servers.
-
-## Server interface
-
-Servers implements the `Server` interface. A 'ServerConfig' and 'gin.Engine' object is supplied in the 'Start' method, so that they may set themselves up and set up the routes etc.
-
-```
-type Server interface {
-	Start(*ServerConfig, *gin.Engine)
-	Running() bool
-	ShutDown()
-}
-```
-
-The `Server` interface can be found in `server.go`.
-
-## ServeProcess
-
-The `ServeProcess` does the port binding and listening. You may attach any number of servers to the serve-process, and it will automatically call their 'Start' and 'ShutDown' methods when starting up and shutting down. You may also attach start and shutdown listeners to the `ServeProcess`.
-
-The `ServeProcess` class can be found in `server.go`.
-
-## WebSocketServer
-
-The `WebSocketServer` is a template for servers that use websocket connections rather then HTTP. It will 
-
-## Config
-
-The config assumes that there is a default HTTP and Websocket server for RPC, and some other fields. See the main README.md for details.
-
-While the system is generic (i.e. it does not care what a `Server` is or does), the configuration file is not. The reason is that the server is written specifically for burrow, and I do not want to manage generic config files (or perhaps even one per server).
\ No newline at end of file
diff --git a/rpc/v0/server/config.go b/rpc/v0/server/config.go
deleted file mode 100644
index 6db3bdbe875221c317c3d8348166ba48b90aa560..0000000000000000000000000000000000000000
--- a/rpc/v0/server/config.go
+++ /dev/null
@@ -1,83 +0,0 @@
-// Copyright 2017 Monax Industries Limited
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//    http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package server
-
-type (
-	ServerConfig struct {
-		Bind      Bind      `toml:"bind"`
-		TLS       TLS       `toml:"TLS"`
-		CORS      CORS      `toml:"CORS"`
-		HTTP      HTTP      `toml:"HTTP"`
-		WebSocket WebSocket `toml:"web_socket"`
-	}
-
-	Bind struct {
-		Address string `toml:"address"`
-		Port    uint16 `toml:"port"`
-	}
-
-	TLS struct {
-		TLS      bool   `toml:"tls"`
-		CertPath string `toml:"cert_path"`
-		KeyPath  string `toml:"key_path"`
-	}
-
-	// Options stores configurations
-	CORS struct {
-		Enable           bool     `toml:"enable"`
-		AllowOrigins     []string `toml:"allow_origins"`
-		AllowCredentials bool     `toml:"allow_credentials"`
-		AllowMethods     []string `toml:"allow_methods"`
-		AllowHeaders     []string `toml:"allow_headers"`
-		ExposeHeaders    []string `toml:"expose_headers"`
-		MaxAge           uint64   `toml:"max_age"`
-	}
-
-	HTTP struct {
-		JsonRpcEndpoint string `toml:"json_rpc_endpoint"`
-	}
-
-	WebSocket struct {
-		WebSocketEndpoint    string `toml:"websocket_endpoint"`
-		MaxWebSocketSessions uint16 `toml:"max_websocket_sessions"`
-		ReadBufferSize       uint64 `toml:"read_buffer_size"`
-		WriteBufferSize      uint64 `toml:"write_buffer_size"`
-	}
-)
-
-func DefaultServerConfig() *ServerConfig {
-	cp := ""
-	kp := ""
-	return &ServerConfig{
-		Bind: Bind{
-			Address: "localhost",
-			Port:    1337,
-		},
-		TLS: TLS{TLS: false,
-			CertPath: cp,
-			KeyPath:  kp,
-		},
-		CORS: CORS{},
-		HTTP: HTTP{
-			JsonRpcEndpoint: "/rpc",
-		},
-		WebSocket: WebSocket{
-			WebSocketEndpoint:    "/socketrpc",
-			MaxWebSocketSessions: 50,
-			ReadBufferSize:       4096,
-			WriteBufferSize:      4096,
-		},
-	}
-}
diff --git a/rpc/v0/server/idpool.go b/rpc/v0/server/idpool.go
deleted file mode 100644
index 44a72cba4d1b3266430b4ff95841a90db4316de8..0000000000000000000000000000000000000000
--- a/rpc/v0/server/idpool.go
+++ /dev/null
@@ -1,56 +0,0 @@
-// Copyright 2017 Monax Industries Limited
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//    http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package server
-
-import (
-	"container/list"
-	"fmt"
-)
-
-// Simple id pool. Lets you get and release uints. Will panic
-// if trying to get an id and it's empty.
-type IdPool struct {
-	ids *list.List
-}
-
-func NewIdPool(totNum uint) *IdPool {
-	idPool := &IdPool{}
-	idPool.init(totNum)
-	return idPool
-}
-
-// We start from 1, so that 0 is not used as an id.
-func (idp *IdPool) init(totNum uint) {
-	idp.ids = list.New()
-	for i := uint(1); i <= totNum; i++ {
-		idp.ids.PushBack(i)
-	}
-}
-
-// Get an id from the pool.
-func (idp *IdPool) GetId() (uint, error) {
-	if idp.ids.Len() == 0 {
-		return 0, fmt.Errorf("Out of IDs")
-	}
-	val := idp.ids.Front()
-	idp.ids.Remove(val)
-	num, _ := val.Value.(uint)
-	return num, nil
-}
-
-// Release an id back into the pool.
-func (idp *IdPool) ReleaseId(id uint) {
-	idp.ids.PushBack(id)
-}
diff --git a/rpc/v0/server/server.go b/rpc/v0/server/server.go
deleted file mode 100644
index ec4c89c2e8d7733ef4c5d0c16460780f22a7f4dc..0000000000000000000000000000000000000000
--- a/rpc/v0/server/server.go
+++ /dev/null
@@ -1,264 +0,0 @@
-// Copyright 2017 Monax Industries Limited
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//    http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package server
-
-import (
-	"context"
-	"crypto/tls"
-	"fmt"
-	"net"
-	"net/http"
-	"time"
-
-	"github.com/gin-gonic/gin"
-	"github.com/hyperledger/burrow/logging"
-	"github.com/tommy351/gin-cors"
-	"gopkg.in/tylerb/graceful.v1"
-)
-
-var (
-	killTime = 100 * time.Millisecond
-)
-
-type HttpService interface {
-	Process(*http.Request, http.ResponseWriter)
-}
-
-// A server serves a number of different http calls.
-type Server interface {
-	Start(*ServerConfig, *gin.Engine)
-	Running() bool
-	Shutdown(ctx context.Context) error
-}
-
-// The ServeProcess wraps all the Servers. Starting it will
-// add all the server handlers to the router and start listening
-// for incoming requests. There is also startup and shutdown events
-// that can be listened to, on top of any events that the servers
-// may have (the default websocket server has events for monitoring
-// sessions. Startup event listeners should be added before calling
-// 'Start()'. Stop event listeners can be added up to the point where
-// the server is stopped and the event is fired.
-type ServeProcess struct {
-	config           *ServerConfig
-	servers          []Server
-	stopChan         chan struct{}
-	startListenChans []chan struct{}
-	stopListenChans  []chan struct{}
-	srv              *graceful.Server
-	logger           *logging.Logger
-}
-
-// Initializes all the servers and starts listening for connections.
-func (serveProcess *ServeProcess) Start() error {
-	gin.SetMode(gin.ReleaseMode)
-	router := gin.New()
-	config := serveProcess.config
-
-	ch := NewCORSMiddleware(config.CORS)
-	router.Use(gin.Recovery(), logHandler(serveProcess.logger), contentTypeMW, ch)
-
-	address := config.Bind.Address
-	port := config.Bind.Port
-
-	if port == 0 {
-		return fmt.Errorf("0 is not a valid port.")
-	}
-
-	listenAddress := address + ":" + fmt.Sprintf("%d", port)
-	srv := &graceful.Server{
-		Server: &http.Server{
-			Handler: router,
-		},
-	}
-
-	// Start the servers/handlers.
-	for _, s := range serveProcess.servers {
-		s.Start(config, router)
-	}
-
-	var lst net.Listener
-	l, lErr := net.Listen("tcp", listenAddress)
-	if lErr != nil {
-		return lErr
-	}
-
-	// For secure connections.
-	if config.TLS.TLS {
-		addr := srv.Addr
-		if addr == "" {
-			addr = ":https"
-		}
-
-		tConfig := &tls.Config{}
-		if tConfig.NextProtos == nil {
-			tConfig.NextProtos = []string{"http/1.1"}
-		}
-
-		var tErr error
-		tConfig.Certificates = make([]tls.Certificate, 1)
-		tConfig.Certificates[0], tErr = tls.LoadX509KeyPair(config.TLS.CertPath, config.TLS.KeyPath)
-		if tErr != nil {
-			return tErr
-		}
-
-		lst = tls.NewListener(l, tConfig)
-	} else {
-		lst = l
-	}
-	serveProcess.srv = srv
-	serveProcess.logger.InfoMsg("Server started.",
-		"address", serveProcess.config.Bind.Address,
-		"port", serveProcess.config.Bind.Port)
-	for _, c := range serveProcess.startListenChans {
-		c <- struct{}{}
-	}
-	// Start the serve routine.
-	go func() {
-		serveProcess.srv.Serve(lst)
-		for _, s := range serveProcess.servers {
-			s.Shutdown(context.Background())
-		}
-	}()
-	// Listen to the process stop event, it will call 'Stop'
-	// on the graceful Server. This happens when someone
-	// calls 'Stop' on the process.
-	go func() {
-		<-serveProcess.stopChan
-		serveProcess.logger.InfoMsg("Close signal sent to server.")
-		serveProcess.srv.Stop(killTime)
-	}()
-	// Listen to the servers stop event. It is triggered when
-	// the server has been fully shut down.
-	go func() {
-		<-serveProcess.srv.StopChan()
-		serveProcess.logger.InfoMsg("Server stop event fired. Good bye.")
-		for _, c := range serveProcess.stopListenChans {
-			c <- struct{}{}
-		}
-	}()
-	return nil
-}
-
-// Stop will release the port, process any remaining requests
-// up until the timeout duration is passed, at which point it
-// will abort them and shut down.
-func (serveProcess *ServeProcess) Shutdown(ctx context.Context) error {
-	var err error
-	for _, s := range serveProcess.servers {
-		serr := s.Shutdown(ctx)
-		if serr != nil && err == nil {
-			err = serr
-		}
-	}
-
-	lChan := serveProcess.StopEventChannel()
-	serveProcess.stopChan <- struct{}{}
-	select {
-	case <-lChan:
-		return err
-	case <-ctx.Done():
-		return ctx.Err()
-	}
-}
-
-// Get a start-event channel from the server. The start event
-// is fired after the Start() function is called, and after
-// the server has started listening for incoming connections.
-// An error here .
-func (serveProcess *ServeProcess) StartEventChannel() <-chan struct{} {
-	lChan := make(chan struct{}, 1)
-	serveProcess.startListenChans = append(serveProcess.startListenChans, lChan)
-	return lChan
-}
-
-// Get a stop-event channel from the server. The event happens
-// after the Stop() function has been called, and after the
-// timeout has passed. When the timeout has passed it will wait
-// for confirmation from the http.Server, which normally takes
-// a very short time (milliseconds).
-func (serveProcess *ServeProcess) StopEventChannel() <-chan struct{} {
-	lChan := make(chan struct{}, 1)
-	serveProcess.stopListenChans = append(serveProcess.stopListenChans, lChan)
-	return lChan
-}
-
-// Creates a new serve process.
-func NewServeProcess(config *ServerConfig, logger *logging.Logger,
-	servers ...Server) (*ServeProcess, error) {
-	var scfg ServerConfig
-	if config == nil {
-		return nil, fmt.Errorf("Nil passed as server configuration")
-	} else {
-		scfg = *config
-	}
-	stopChan := make(chan struct{}, 1)
-	startListeners := make([]chan struct{}, 0)
-	stopListeners := make([]chan struct{}, 0)
-	sp := &ServeProcess{
-		config:           &scfg,
-		servers:          servers,
-		stopChan:         stopChan,
-		startListenChans: startListeners,
-		stopListenChans:  stopListeners,
-		srv:              nil,
-		logger:           logger.WithScope("ServeProcess"),
-	}
-	return sp, nil
-}
-
-// Used to enable log15 logging instead of the default Gin logging.
-func logHandler(logger *logging.Logger) gin.HandlerFunc {
-	logger = logger.WithScope("ginLogHandler")
-	return func(c *gin.Context) {
-
-		path := c.Request.URL.Path
-
-		// Process request
-		c.Next()
-
-		clientIP := c.ClientIP()
-		method := c.Request.Method
-		statusCode := c.Writer.Status()
-		comment := c.Errors.String()
-
-		logger.Info.Log("client_ip", clientIP,
-			"status_code", statusCode,
-			"method", method,
-			"path", path,
-			"error", comment)
-	}
-}
-
-func NewCORSMiddleware(options CORS) gin.HandlerFunc {
-	o := cors.Options{
-		AllowCredentials: options.AllowCredentials,
-		AllowHeaders:     options.AllowHeaders,
-		AllowMethods:     options.AllowMethods,
-		AllowOrigins:     options.AllowOrigins,
-		ExposeHeaders:    options.ExposeHeaders,
-		MaxAge:           time.Duration(options.MaxAge),
-	}
-	return cors.Middleware(o)
-}
-
-// Just a catch-all for POST requests right now. Only allow default charset (utf8).
-func contentTypeMW(c *gin.Context) {
-	if c.Request.Method == "POST" && c.ContentType() != "application/json" {
-		c.AbortWithError(415, fmt.Errorf("Media type not supported: "+c.ContentType()))
-	} else {
-		c.Next()
-	}
-}
diff --git a/rpc/v0/server/server_test.go b/rpc/v0/server/server_test.go
deleted file mode 100644
index 5efdad26819e4d2f12ed568c71954eb27ce1405c..0000000000000000000000000000000000000000
--- a/rpc/v0/server/server_test.go
+++ /dev/null
@@ -1,55 +0,0 @@
-// Copyright 2017 Monax Industries Limited
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//    http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package server
-
-import (
-	//"fmt"
-	"testing"
-
-	"github.com/stretchr/testify/assert"
-)
-
-// Unit tests for server components goes here. Full-on client-server tests
-// can be found in the test folder.
-
-func TestIdGet(t *testing.T) {
-	idPool := NewIdPool(100)
-	idparr := make([]uint, 100)
-	arr := make([]uint, 100)
-	for i := 0; i < 100; i++ {
-		idparr[i] = uint(i + 1)
-		arr[i], _ = idPool.GetId()
-	}
-	assert.Equal(t, idparr, arr, "Array of gotten id's is not [1, 2, ..., 101] as expected")
-}
-
-func TestIdPut(t *testing.T) {
-	idPool := NewIdPool(10)
-	for i := 0; i < 10; i++ {
-		idPool.GetId()
-	}
-	idPool.ReleaseId(5)
-	id, _ := idPool.GetId()
-	assert.Equal(t, id, uint(5), "Id gotten is not 5.")
-}
-
-func TestIdFull(t *testing.T) {
-	idPool := NewIdPool(10)
-	for i := 0; i < 10; i++ {
-		idPool.GetId()
-	}
-	_, err := idPool.GetId()
-	assert.Error(t, err)
-}
diff --git a/rpc/v0/server/websocket.go b/rpc/v0/server/websocket.go
deleted file mode 100644
index cda4f7def80b26957378e6d789db9a1e4e735f9c..0000000000000000000000000000000000000000
--- a/rpc/v0/server/websocket.go
+++ /dev/null
@@ -1,440 +0,0 @@
-// Copyright 2017 Monax Industries Limited
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//    http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package server
-
-import (
-	"context"
-	"fmt"
-	"net/http"
-	"sync"
-	"time"
-
-	"github.com/gin-gonic/gin"
-	"github.com/gorilla/websocket"
-	"github.com/hyperledger/burrow/logging"
-)
-
-// TODO too much fluff. Should probably phase gorilla out and move closer
-// to net in connections/session management. At some point...
-
-const (
-	// Time allowed to write a message to the peer.
-	writeWait = 0 * time.Second
-	// Maximum message size allowed from a peer.
-	maxMessageSize = 1000000
-)
-
-// Services requests. Message bytes are passed along with the session
-// object. The service is expected to write any response back using
-// the Write function on WSSession, which passes the message over
-// a channel to the write pump.
-type WebSocketService interface {
-	Process([]byte, *WSSession)
-}
-
-// The websocket server handles incoming websocket connection requests,
-// upgrading, reading, writing, and session management. Handling the
-// actual requests is delegated to a websocket service.
-type WebSocketServer struct {
-	upgrader       websocket.Upgrader
-	running        bool
-	maxSessions    uint16
-	sessionManager *SessionManager
-	config         *ServerConfig
-	allOrigins     bool
-	logger         *logging.Logger
-}
-
-// Create a new server.
-// maxSessions is the maximum number of active websocket connections that is allowed.
-// NOTE: This is not the total number of connections allowed - only those that are
-// upgraded to websockets. Requesting a websocket connection will fail with a 503 if
-// the server is at capacity.
-func NewWebSocketServer(maxSessions uint16, service WebSocketService,
-	logger *logging.Logger) *WebSocketServer {
-	return &WebSocketServer{
-		maxSessions:    maxSessions,
-		sessionManager: NewSessionManager(maxSessions, service, logger),
-		logger:         logger.WithScope("WebSocketServer"),
-	}
-}
-
-// Start the server. Adds the handler to the router and sets everything up.
-func (wsServer *WebSocketServer) Start(config *ServerConfig, router *gin.Engine) {
-
-	wsServer.config = config
-
-	wsServer.upgrader = websocket.Upgrader{
-		ReadBufferSize: int(config.WebSocket.ReadBufferSize),
-		// TODO Will this be enough for massive "get blockchain" requests?
-		WriteBufferSize: int(config.WebSocket.WriteBufferSize),
-	}
-	wsServer.upgrader.CheckOrigin = func(r *http.Request) bool { return true }
-	router.GET(config.WebSocket.WebSocketEndpoint, wsServer.handleFunc)
-	wsServer.running = true
-}
-
-// Is the server currently running.
-func (wsServer *WebSocketServer) Running() bool {
-	return wsServer.running
-}
-
-// Shut the server down.
-func (wsServer *WebSocketServer) Shutdown(ctx context.Context) error {
-	wsServer.sessionManager.Shutdown()
-	wsServer.running = false
-	return nil
-}
-
-// Get the session-manager.
-func (wsServer *WebSocketServer) SessionManager() *SessionManager {
-	return wsServer.sessionManager
-}
-
-// Handler for websocket requests.
-func (wsServer *WebSocketServer) handleFunc(c *gin.Context) {
-	r := c.Request
-	w := c.Writer
-	// Upgrade to websocket.
-	wsConn, uErr := wsServer.upgrader.Upgrade(w, r, nil)
-
-	if uErr != nil {
-		errMsg := "Failed to upgrade to websocket connection"
-		http.Error(w, fmt.Sprintf("%s: %s", errMsg, uErr.Error()), 400)
-		wsServer.logger.InfoMsg(errMsg, "error", uErr)
-		return
-	}
-
-	session, cErr := wsServer.sessionManager.createSession(wsConn)
-
-	if cErr != nil {
-		errMsg := "Failed to establish websocket connection"
-		http.Error(w, fmt.Sprintf("%s: %s", errMsg, cErr.Error()), 503)
-		wsServer.logger.InfoMsg(errMsg, "error", cErr)
-		return
-	}
-
-	// Start the connection.
-	wsServer.logger.InfoMsg("New websocket connection",
-		"session_id", session.id)
-	session.Open()
-}
-
-// Used to track sessions. Will notify when a session are opened
-// and closed.
-type SessionObserver interface {
-	NotifyOpened(*WSSession)
-	NotifyClosed(*WSSession)
-}
-
-// WSSession wraps a gorilla websocket.Conn, which in turn wraps a
-// net.Conn object. Writing is done using the 'Write([]byte)' method,
-// which passes the bytes on to the write pump over a channel.
-type WSSession struct {
-	sessionManager *SessionManager
-	id             uint
-	wsConn         *websocket.Conn
-	writeChan      chan []byte
-	writeCloseChan chan struct{}
-	service        WebSocketService
-	opened         bool
-	closed         bool
-	logger         *logging.Logger
-}
-
-// Write a text message to the client.
-func (wsSession *WSSession) Write(msg []byte) error {
-	if wsSession.closed {
-		wsSession.logger.InfoMsg("Attempting to write to closed session.")
-		return fmt.Errorf("Session is closed")
-	}
-	wsSession.writeChan <- msg
-	return nil
-}
-
-// Private. Helper for writing control messages.
-func (wsSession *WSSession) write(mt int, payload []byte) error {
-	wsSession.wsConn.SetWriteDeadline(time.Now().Add(writeWait))
-	return wsSession.wsConn.WriteMessage(mt, payload)
-}
-
-// Get the session id number.
-func (wsSession *WSSession) Id() uint {
-	return wsSession.id
-}
-
-// Starts the read and write pumps. Blocks on the former.
-// Notifies all the observers.
-func (wsSession *WSSession) Open() {
-	wsSession.opened = true
-	wsSession.sessionManager.notifyOpened(wsSession)
-	go wsSession.writePump()
-	wsSession.readPump()
-}
-
-// Closes the net connection and cleans up. Notifies all the observers.
-func (wsSession *WSSession) Close() {
-	if !wsSession.closed {
-		wsSession.closed = true
-		wsSession.wsConn.Close()
-		wsSession.sessionManager.removeSession(wsSession.id)
-		wsSession.logger.InfoMsg("Closing websocket connection.",
-			"remaining_active_sessions", len(wsSession.sessionManager.activeSessions))
-		wsSession.sessionManager.notifyClosed(wsSession)
-	}
-}
-
-// Has the session been opened?
-func (wsSession *WSSession) Opened() bool {
-	return wsSession.opened
-}
-
-// Has the session been closed?
-func (wsSession *WSSession) Closed() bool {
-	return wsSession.closed
-}
-
-// Pump debugging
-/*
-var rp int = 0
-var wp int = 0
-var rpm *sync.Mutex = &sync.Mutex{}
-var wpm *sync.Mutex = &sync.Mutex{}
-*/
-
-// Read loop. Will terminate on a failed read.
-func (wsSession *WSSession) readPump() {
-	/*
-		rpm.Lock()
-		rp++
-		log.Debug("readpump created", "total", rp)
-		rpm.Unlock()
-		defer func(){
-			rpm.Lock()
-			rp--
-			log.Debug("readpump removed", "total", rp)
-			rpm.Unlock()
-			}()
-	*/
-	wsSession.wsConn.SetReadLimit(maxMessageSize)
-	// this.wsConn.SetReadDeadline(time.Now().Add(pongWait))
-	// this.wsConn.SetPongHandler(func(string) error { this.wsConn.SetReadDeadline(time.Now().Add(pongWait)); return nil })
-
-	for {
-		// Read
-		msgType, msg, err := wsSession.wsConn.ReadMessage()
-
-		// Read error.
-		if err != nil {
-			// Socket could have been gracefully closed, so not really an error.
-			wsSession.logger.InfoMsg(
-				"Socket closed. Removing.", "error", err)
-			wsSession.writeCloseChan <- struct{}{}
-			return
-		}
-
-		if msgType != websocket.TextMessage {
-			wsSession.logger.InfoMsg(
-				"Receiving non text-message from client, closing.")
-			wsSession.writeCloseChan <- struct{}{}
-			return
-		}
-
-		go func() {
-			// Process the request.
-			wsSession.service.Process(msg, wsSession)
-		}()
-	}
-}
-
-// Writes messages coming in on the write channel. Will terminate on failed writes,
-// if pings are not responded to, or if a message comes in on the write close channel.
-func (wsSession *WSSession) writePump() {
-	/*
-		wpm.Lock()
-		wp++
-		log.Debug("writepump created", "total", wp)
-		wpm.Unlock()
-		defer func() {
-			wpm.Lock()
-			wp--
-			log.Debug("writepump removed", "total", wp)
-			wpm.Unlock()
-		}()
-	*/
-	// ticker := time.NewTicker(pingPeriod)
-
-	defer func() {
-		// ticker.Stop()
-		wsSession.Close()
-	}()
-
-	// Write loop. Blocks while waiting for data to come in over a channel.
-	for {
-		select {
-		// Write request.
-		case msg := <-wsSession.writeChan:
-
-			// Write the bytes to the socket.
-			err := wsSession.wsConn.WriteMessage(websocket.TextMessage, msg)
-			if err != nil {
-				// Could be due to the socket being closed so not really an error.
-				wsSession.logger.InfoMsg(
-					"Writing to socket failed. Closing.")
-				return
-			}
-		case <-wsSession.writeCloseChan:
-			return
-			// Ticker run out. Time for another ping message.
-			/*
-				case <-ticker.C:
-					if err := this.write(websocket.PingMessage, []byte{}); err != nil {
-						log.Debug("Failed to write ping message to socket. Closing.")
-						return
-					}
-			*/
-		}
-
-	}
-}
-
-// Session manager handles the adding, tracking and removing of session objects.
-type SessionManager struct {
-	maxSessions     uint16
-	activeSessions  map[uint]*WSSession
-	idPool          *IdPool
-	mtx             *sync.Mutex
-	service         WebSocketService
-	openEventChans  []chan *WSSession
-	closeEventChans []chan *WSSession
-	logger          *logging.Logger
-}
-
-// Create a new WebsocketManager.
-func NewSessionManager(maxSessions uint16, wss WebSocketService,
-	logger *logging.Logger) *SessionManager {
-	return &SessionManager{
-		maxSessions:     maxSessions,
-		activeSessions:  make(map[uint]*WSSession),
-		idPool:          NewIdPool(uint(maxSessions)),
-		mtx:             &sync.Mutex{},
-		service:         wss,
-		openEventChans:  []chan *WSSession{},
-		closeEventChans: []chan *WSSession{},
-		logger:          logger.WithScope("SessionManager"),
-	}
-}
-
-// TODO
-func (sessionManager *SessionManager) Shutdown() {
-	sessionManager.activeSessions = nil
-}
-
-// Add a listener to session open events.
-func (sessionManager *SessionManager) SessionOpenEventChannel() <-chan *WSSession {
-	lChan := make(chan *WSSession, 1)
-	sessionManager.openEventChans = append(sessionManager.openEventChans, lChan)
-	return lChan
-}
-
-// Remove a listener from session open events.
-func (sessionManager *SessionManager) RemoveSessionOpenEventChannel(lChan chan *WSSession) bool {
-	ec := sessionManager.openEventChans
-	if len(ec) == 0 {
-		return false
-	}
-	for _, c := range ec {
-		if lChan == c {
-			return true
-		}
-	}
-	return false
-}
-
-// Add a listener to session close events
-func (sessionManager *SessionManager) SessionCloseEventChannel() <-chan *WSSession {
-	lChan := make(chan *WSSession, 1)
-	sessionManager.closeEventChans = append(sessionManager.closeEventChans, lChan)
-	return lChan
-}
-
-// Remove a listener from session close events.
-func (sessionManager *SessionManager) RemoveSessionCloseEventChannel(lChan chan *WSSession) bool {
-	ec := sessionManager.closeEventChans
-	if len(ec) == 0 {
-		return false
-	}
-	for _, c := range ec {
-		if lChan == c {
-			return true
-		}
-	}
-	return false
-}
-
-// Used to notify all observers that a new session was opened.
-func (sessionManager *SessionManager) notifyOpened(session *WSSession) {
-	for _, lChan := range sessionManager.openEventChans {
-		lChan <- session
-	}
-}
-
-// Used to notify all observers that a new session was closed.
-func (sessionManager *SessionManager) notifyClosed(session *WSSession) {
-	for _, lChan := range sessionManager.closeEventChans {
-		lChan <- session
-	}
-}
-
-// Creates a new session and adds it to the manager.
-func (sessionManager *SessionManager) createSession(wsConn *websocket.Conn) (*WSSession, error) {
-	// Check that the capacity hasn't been exceeded.
-	sessionManager.mtx.Lock()
-	defer sessionManager.mtx.Unlock()
-	if sessionManager.atCapacity() {
-		return nil, fmt.Errorf("Already at capacity")
-	}
-
-	// Create and start
-	newId, _ := sessionManager.idPool.GetId()
-	conn := &WSSession{
-		sessionManager: sessionManager,
-		id:             newId,
-		wsConn:         wsConn,
-		writeChan:      make(chan []byte, maxMessageSize),
-		writeCloseChan: make(chan struct{}),
-		service:        sessionManager.service,
-		logger:         sessionManager.logger.WithScope("WSSession").With("session_id", newId),
-	}
-	sessionManager.activeSessions[conn.id] = conn
-	return conn, nil
-}
-
-// Remove a session from the list.
-func (sessionManager *SessionManager) removeSession(id uint) {
-	sessionManager.mtx.Lock()
-	defer sessionManager.mtx.Unlock()
-	// Check that it exists.
-	_, ok := sessionManager.activeSessions[id]
-	if ok {
-		delete(sessionManager.activeSessions, id)
-		sessionManager.idPool.ReleaseId(id)
-	}
-}
-
-// True if the number of active connections is at the maximum.
-func (sessionManager *SessionManager) atCapacity() bool {
-	return len(sessionManager.activeSessions) >= int(sessionManager.maxSessions)
-}
diff --git a/rpc/v0/websocket_service.go b/rpc/v0/websocket_service.go
deleted file mode 100644
index 259a3f13d6e8a01900eb098cd24489503c30d616..0000000000000000000000000000000000000000
--- a/rpc/v0/websocket_service.go
+++ /dev/null
@@ -1,166 +0,0 @@
-// Copyright 2017 Monax Industries Limited
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//    http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package v0
-
-import (
-	"context"
-	"encoding/json"
-	"fmt"
-
-	"github.com/hyperledger/burrow/event"
-	"github.com/hyperledger/burrow/logging"
-	"github.com/hyperledger/burrow/logging/structure"
-	"github.com/hyperledger/burrow/rpc"
-	"github.com/hyperledger/burrow/rpc/v0/server"
-)
-
-// Used for Burrow. Implements WebSocketService.
-type WebsocketService struct {
-	codec           rpc.Codec
-	service         *rpc.Service
-	defaultHandlers map[string]RequestHandlerFunc
-	logger          *logging.Logger
-}
-
-// Create a new websocket service.
-func NewWebsocketService(codec rpc.Codec, service *rpc.Service, logger *logging.Logger) server.WebSocketService {
-	tmwss := &WebsocketService{
-		codec:   codec,
-		service: service,
-		logger:  logger.WithScope("NewWebsocketService"),
-	}
-	dhMap := GetMethods(codec, service, tmwss.logger)
-	// Events
-	dhMap[EVENT_SUBSCRIBE] = tmwss.EventSubscribe
-	dhMap[EVENT_UNSUBSCRIBE] = tmwss.EventUnsubscribe
-	tmwss.defaultHandlers = dhMap
-	return tmwss
-}
-
-// Process a request.
-func (ws *WebsocketService) Process(msg []byte, session *server.WSSession) {
-	defer func() {
-		if r := recover(); r != nil {
-			err := fmt.Errorf("panic in WebsocketService.Process(): %v", r)
-			ws.logger.InfoMsg("Panic in WebsocketService.Process()", structure.ErrorKey, err)
-			if !session.Closed() {
-				ws.writeError(err.Error(), "", rpc.INTERNAL_ERROR, session)
-			}
-		}
-	}()
-	// Create new request object and unmarshal.
-	req := &rpc.RPCRequest{}
-	errU := json.Unmarshal(msg, req)
-
-	// Error when unmarshaling.
-	if errU != nil {
-		ws.writeError("Failed to parse request: "+errU.Error()+" . Raw: "+string(msg),
-			"", rpc.PARSE_ERROR, session)
-		return
-	}
-
-	// Wrong protocol version.
-	if req.JSONRPC != "2.0" {
-		ws.writeError("Wrong protocol version: "+req.JSONRPC, req.Id,
-			rpc.INVALID_REQUEST, session)
-		return
-	}
-
-	mName := req.Method
-
-	if handler, ok := ws.defaultHandlers[mName]; ok {
-		resp, errCode, err := handler(req, session)
-		if err != nil {
-			ws.writeError(err.Error(), req.Id, errCode, session)
-		} else {
-			ws.writeResponse(req.Id, resp, session)
-		}
-	} else {
-		ws.writeError("Method not found: "+mName, req.Id,
-			rpc.METHOD_NOT_FOUND, session)
-	}
-}
-
-// Convenience method for writing error responses.
-func (ws *WebsocketService) writeError(msg, id string, code int,
-	session *server.WSSession) {
-	response := rpc.NewRPCErrorResponse(id, code, msg)
-	bts, err := ws.codec.EncodeBytes(response)
-	// If there's an error here all bets are off.
-	if err != nil {
-		panic("Failed to marshal standard error response." + err.Error())
-	}
-	session.Write(bts)
-}
-
-// Convenience method for writing responses.
-func (ws *WebsocketService) writeResponse(id string, result interface{},
-	session *server.WSSession) error {
-	response := rpc.NewRPCResponse(id, result)
-	bts, err := ws.codec.EncodeBytes(response)
-	if err != nil {
-		ws.writeError("Internal error: "+err.Error(), id, rpc.INTERNAL_ERROR, session)
-		return err
-	}
-	return session.Write(bts)
-}
-
-// *************************************** Events ************************************
-
-func (ws *WebsocketService) EventSubscribe(request *rpc.RPCRequest,
-	requester interface{}) (interface{}, int, error) {
-	session, ok := requester.(*server.WSSession)
-	if !ok {
-		return 0, rpc.INTERNAL_ERROR,
-			fmt.Errorf("Passing wrong object to websocket events")
-	}
-	param := &EventIdParam{}
-	err := ws.codec.DecodeBytes(param, request.Params)
-	if err != nil {
-		return nil, rpc.INVALID_PARAMS, err
-	}
-	eventId := param.EventId
-	subId, err := event.GenerateSubscriptionID()
-	if err != nil {
-		return nil, rpc.INTERNAL_ERROR, err
-	}
-
-	err = ws.service.Subscribe(context.Background(), subId, eventId, func(resultEvent *rpc.ResultEvent) (stop bool) {
-		ws.writeResponse(subId, resultEvent, session)
-		return
-	})
-	if err != nil {
-		return nil, rpc.INTERNAL_ERROR, err
-	}
-	return &EventSub{SubId: subId}, 0, nil
-}
-
-func (ws *WebsocketService) EventUnsubscribe(request *rpc.RPCRequest, requester interface{}) (interface{}, int, error) {
-	param := &SubIdParam{}
-	err := ws.codec.DecodeBytes(param, request.Params)
-	if err != nil {
-		return nil, rpc.INVALID_PARAMS, err
-	}
-
-	err = ws.service.Unsubscribe(context.Background(), param.SubId)
-	if err != nil {
-		return nil, rpc.INTERNAL_ERROR, err
-	}
-	return &EventUnsub{Result: true}, 0, nil
-}
-
-func (ws *WebsocketService) EventPoll(request *rpc.RPCRequest, requester interface{}) (interface{}, int, error) {
-	return nil, rpc.INTERNAL_ERROR, fmt.Errorf("Cannot poll with websockets")
-}
diff --git a/txs/amino_codec_test.go b/txs/amino_codec_test.go
index 41c3e4885f691502c26641cbd907986075b76ada..536bfc06d4009a99edcd6cf795d67708de6411b5 100644
--- a/txs/amino_codec_test.go
+++ b/txs/amino_codec_test.go
@@ -3,7 +3,7 @@ package txs
 import (
 	"testing"
 
-	acm "github.com/hyperledger/burrow/account"
+	"github.com/hyperledger/burrow/acm"
 	"github.com/hyperledger/burrow/crypto"
 	"github.com/hyperledger/burrow/txs/payload"
 	"github.com/stretchr/testify/assert"
diff --git a/txs/envelope.go b/txs/envelope.go
index 107c7a6770a853de5a34e992ab39dd983653a071..06ed3832a145f30c86cfbe41d66a5b58bfb8bc01 100644
--- a/txs/envelope.go
+++ b/txs/envelope.go
@@ -3,9 +3,10 @@ package txs
 import (
 	"fmt"
 
-	acm "github.com/hyperledger/burrow/account"
-	"github.com/hyperledger/burrow/account/state"
+	"github.com/hyperledger/burrow/acm"
+	"github.com/hyperledger/burrow/acm/state"
 	"github.com/hyperledger/burrow/crypto"
+	"github.com/hyperledger/burrow/event/query"
 	"github.com/hyperledger/burrow/txs/payload"
 )
 
@@ -22,12 +23,6 @@ type Decoder interface {
 	DecodeTx(txBytes []byte) (*Envelope, error)
 }
 
-// An envelope contains both the signable Tx and the signatures for each input (in signatories)
-type Envelope struct {
-	Signatories []Signatory
-	Tx          *Tx
-}
-
 // Enclose a Payload in an Envelope so it is ready to be signed by first wrapping the Payload
 // as a Tx (including ChainID) and writing it to the Tx field of the Envelope
 func Enclose(chainID string, payload payload.Payload) *Envelope {
@@ -40,13 +35,6 @@ func (txEnv *Envelope) String() string {
 	return fmt.Sprintf("TxEnvelope{Signatures: %v, Tx: %s}", len(txEnv.Signatories), txEnv.Tx)
 }
 
-// Signatory contains signature and one or both of Address and PublicKey to identify the signer
-type Signatory struct {
-	Address   *crypto.Address
-	PublicKey *crypto.PublicKey
-	crypto.Signature
-}
-
 // Attempts to 'realise' the PublicKey and Address of a Signatory possibly referring to state
 // in the case where the Signatory contains an Address by no PublicKey. Checks consistency in other
 // cases, possibly generating the Address from the PublicKey
@@ -150,3 +138,7 @@ func (txEnv *Envelope) Sign(signingAccounts ...acm.AddressableSigner) error {
 	}
 	return nil
 }
+
+func (txEnv *Envelope) Tagged() query.Tagged {
+	return query.MergeTags(query.MustReflectTags(txEnv, "Signatories"), txEnv.Tx.Tagged())
+}
diff --git a/txs/json_codec_test.go b/txs/json_codec_test.go
index f0056290c55d5efa285733fcb5831ad1138b936b..2a4527f490c011951e37a193f80ce5eb39ae766e 100644
--- a/txs/json_codec_test.go
+++ b/txs/json_codec_test.go
@@ -3,7 +3,7 @@ package txs
 import (
 	"testing"
 
-	"github.com/hyperledger/burrow/account"
+	"github.com/hyperledger/burrow/acm"
 	"github.com/hyperledger/burrow/crypto"
 	"github.com/hyperledger/burrow/txs/payload"
 	"github.com/stretchr/testify/assert"
@@ -39,7 +39,7 @@ func TestJSONEncodeTxDecodeTx(t *testing.T) {
 
 func TestJSONEncodeTxDecodeTx_CallTx(t *testing.T) {
 	codec := NewJSONCodec()
-	inputAccount := account.GeneratePrivateAccountFromSecret("fooo")
+	inputAccount := acm.GeneratePrivateAccountFromSecret("fooo")
 	amount := uint64(2)
 	sequence := uint64(3)
 	tx := &payload.CallTx{
@@ -66,7 +66,7 @@ func TestJSONEncodeTxDecodeTx_CallTx(t *testing.T) {
 
 func TestJSONEncodeTxDecodeTx_CallTxNoData(t *testing.T) {
 	codec := NewJSONCodec()
-	inputAccount := account.GeneratePrivateAccountFromSecret("fooo")
+	inputAccount := acm.GeneratePrivateAccountFromSecret("fooo")
 	amount := uint64(2)
 	sequence := uint64(3)
 	tx := &payload.CallTx{
@@ -88,5 +88,11 @@ func TestJSONEncodeTxDecodeTx_CallTxNoData(t *testing.T) {
 	}
 	txEnvOut, err := codec.DecodeTx(txBytes)
 	assert.NoError(t, err, "DecodeTx error")
-	assert.Equal(t, txEnv, txEnvOut)
+
+	bs, err := codec.EncodeTx(txEnv)
+	require.NoError(t, err)
+	bsOut, err := codec.EncodeTx(txEnvOut)
+	require.NoError(t, err)
+
+	assert.Equal(t, bs, bsOut)
 }
diff --git a/txs/payload/bond_tx.go b/txs/payload/bond_tx.go
index 7752b9411e23c338ae5996f1d3c19d2991f947f0..59585b6e01611c145006aaca73ed30701d92ad0c 100644
--- a/txs/payload/bond_tx.go
+++ b/txs/payload/bond_tx.go
@@ -3,16 +3,10 @@ package payload
 import (
 	"fmt"
 
-	"github.com/hyperledger/burrow/account/state"
+	"github.com/hyperledger/burrow/acm/state"
 	"github.com/hyperledger/burrow/crypto"
 )
 
-type BondTx struct {
-	// At least one should have bond permission (even if 0 amount transfer)
-	Inputs   []*TxInput
-	UnbondTo []*TxOutput
-}
-
 func NewBondTx(pubkey crypto.PublicKey) (*BondTx, error) {
 	return &BondTx{
 		Inputs:   []*TxInput{},
diff --git a/txs/payload/call_tx.go b/txs/payload/call_tx.go
index 559e72e13b02cf8d632ff4e92897048bcd2037d2..68638de3e46eca620b55d658801dc54437b4f804 100644
--- a/txs/payload/call_tx.go
+++ b/txs/payload/call_tx.go
@@ -3,21 +3,10 @@ package payload
 import (
 	"fmt"
 
-	"github.com/hyperledger/burrow/account/state"
-	"github.com/hyperledger/burrow/binary"
+	"github.com/hyperledger/burrow/acm/state"
 	"github.com/hyperledger/burrow/crypto"
 )
 
-type CallTx struct {
-	Input *TxInput
-	// Pointer since CallTx defines unset 'to' address as inducing account creation
-	Address  *crypto.Address
-	GasLimit uint64
-	Fee      uint64
-	// Signing normalisation needs omitempty
-	Data binary.HexBytes `json:",omitempty"`
-}
-
 func NewCallTx(st state.AccountGetter, from crypto.PublicKey, to *crypto.Address, data []byte,
 	amt, gasLimit, fee uint64) (*CallTx, error) {
 
@@ -59,5 +48,14 @@ func (tx *CallTx) GetInputs() []*TxInput {
 }
 
 func (tx *CallTx) String() string {
-	return fmt.Sprintf("CallTx{%v -> %s: %X}", tx.Input, tx.Address, tx.Data)
+	return fmt.Sprintf("CallTx{%v -> %s: %v}", tx.Input, tx.Address, tx.Data)
+}
+
+// Returns the contract address that this CallTx would create if CallTx.Address == nil otherwise returns nil
+func (tx *CallTx) CreatesContractAddress() *crypto.Address {
+	if tx.Address != nil {
+		return nil
+	}
+	address := crypto.NewContractAddress(tx.Input.Address, tx.Input.Sequence)
+	return &address
 }
diff --git a/txs/payload/errors.go b/txs/payload/errors.go
index 93a7f2feed1c4559812770b1ec99232a02eac10f..affd564371667d29d81218fdf8316182c5ff6a91 100644
--- a/txs/payload/errors.go
+++ b/txs/payload/errors.go
@@ -15,14 +15,6 @@ var (
 	ErrTxInvalidSignature  = errors.New("error invalid signature")
 )
 
-type ErrTxInvalidString struct {
-	Msg string
-}
-
-func (e ErrTxInvalidString) Error() string {
-	return e.Msg
-}
-
 type ErrTxInvalidSequence struct {
 	Got      uint64
 	Expected uint64
diff --git a/txs/payload/governance_tx.go b/txs/payload/governance_tx.go
index 24c0cb48ad0a060d960345561057d4c39a55ac92..046f912916a4397f147ffbc717ac4c9c30bc38b1 100644
--- a/txs/payload/governance_tx.go
+++ b/txs/payload/governance_tx.go
@@ -3,17 +3,12 @@ package payload
 import (
 	"fmt"
 
-	"github.com/hyperledger/burrow/account/state"
+	"github.com/hyperledger/burrow/acm/state"
 	"github.com/hyperledger/burrow/crypto"
 	"github.com/hyperledger/burrow/genesis/spec"
 )
 
-type GovernanceTx struct {
-	Input          *TxInput
-	AccountUpdates []spec.TemplateAccount
-}
-
-func NewGovTx(st state.AccountGetter, from crypto.Address, accounts ...spec.TemplateAccount) (*GovernanceTx, error) {
+func NewGovTx(st state.AccountGetter, from crypto.Address, accounts ...*spec.TemplateAccount) (*GovernanceTx, error) {
 	acc, err := st.GetAccount(from)
 	if err != nil {
 		return nil, err
@@ -26,12 +21,12 @@ func NewGovTx(st state.AccountGetter, from crypto.Address, accounts ...spec.Temp
 	return NewGovTxWithSequence(from, sequence, accounts), nil
 }
 
-func NewGovTxWithSequence(from crypto.Address, sequence uint64, accounts []spec.TemplateAccount) *GovernanceTx {
+func NewGovTxWithSequence(from crypto.Address, sequence uint64, accounts []*spec.TemplateAccount) *GovernanceTx {
 	return &GovernanceTx{
-		Input: &TxInput{
+		Inputs: []*TxInput{{
 			Address:  from,
 			Sequence: sequence,
-		},
+		}},
 		AccountUpdates: accounts,
 	}
 }
@@ -41,9 +36,9 @@ func (tx *GovernanceTx) Type() Type {
 }
 
 func (tx *GovernanceTx) GetInputs() []*TxInput {
-	return []*TxInput{tx.Input}
+	return tx.Inputs
 }
 
 func (tx *GovernanceTx) String() string {
-	return fmt.Sprintf("GovernanceTx{%v -> %v}", tx.Input, tx.AccountUpdates)
+	return fmt.Sprintf("GovernanceTx{%v -> %v}", tx.Inputs, tx.AccountUpdates)
 }
diff --git a/txs/payload/name_tx.go b/txs/payload/name_tx.go
index a1037fc5a9bef4b559dfd55d37b41fb781606506..334fa6df32d0a2d940be81e65ec935e9517d581d 100644
--- a/txs/payload/name_tx.go
+++ b/txs/payload/name_tx.go
@@ -2,25 +2,11 @@ package payload
 
 import (
 	"fmt"
-	"regexp"
 
-	"github.com/hyperledger/burrow/account/state"
+	"github.com/hyperledger/burrow/acm/state"
 	"github.com/hyperledger/burrow/crypto"
-	"github.com/hyperledger/burrow/execution/names"
 )
 
-// Name should be file system lik
-// Data should be anything permitted in JSON
-var regexpAlphaNum = regexp.MustCompile("^[a-zA-Z0-9._/-@]*$")
-var regexpJSON = regexp.MustCompile(`^[a-zA-Z0-9_/ \-+"':,\n\t.{}()\[\]]*$`)
-
-type NameTx struct {
-	Input *TxInput
-	Name  string
-	Data  string
-	Fee   uint64
-}
-
 func NewNameTx(st state.AccountGetter, from crypto.PublicKey, name, data string, amt, fee uint64) (*NameTx, error) {
 	addr := from.Address()
 	acc, err := st.GetAccount(addr)
@@ -58,37 +44,6 @@ func (tx *NameTx) GetInputs() []*TxInput {
 	return []*TxInput{tx.Input}
 }
 
-func (tx *NameTx) ValidateStrings() error {
-	if len(tx.Name) == 0 {
-		return ErrTxInvalidString{"Name must not be empty"}
-	}
-	if len(tx.Name) > names.MaxNameLength {
-		return ErrTxInvalidString{fmt.Sprintf("Name is too long. Max %d bytes", names.MaxNameLength)}
-	}
-	if len(tx.Data) > names.MaxDataLength {
-		return ErrTxInvalidString{fmt.Sprintf("Data is too long. Max %d bytes", names.MaxDataLength)}
-	}
-
-	if !validateNameRegEntryName(tx.Name) {
-		return ErrTxInvalidString{fmt.Sprintf("Invalid characters found in NameTx.Name (%s). Only alphanumeric, underscores, dashes, forward slashes, and @ are allowed", tx.Name)}
-	}
-
-	if !validateNameRegEntryData(tx.Data) {
-		return ErrTxInvalidString{fmt.Sprintf("Invalid characters found in NameTx.Data (%s). Only the kind of things found in a JSON file are allowed", tx.Data)}
-	}
-
-	return nil
-}
-
 func (tx *NameTx) String() string {
 	return fmt.Sprintf("NameTx{%v -> %s: %s}", tx.Input, tx.Name, tx.Data)
 }
-
-// filter strings
-func validateNameRegEntryName(name string) bool {
-	return regexpAlphaNum.Match([]byte(name))
-}
-
-func validateNameRegEntryData(data string) bool {
-	return regexpJSON.Match([]byte(data))
-}
diff --git a/txs/payload/payload.go b/txs/payload/payload.go
index cc0c5e181466e3d76eeb33da2495fb0f4e0faedf..f415d8f8331e06f85e3dc8d9488fe07a56ffcc74 100644
--- a/txs/payload/payload.go
+++ b/txs/payload/payload.go
@@ -16,7 +16,7 @@ Admin Txs:
  - PermissionsTx
 */
 
-type Type int8
+type Type uint32
 
 // Types of Payload implementations
 const (
@@ -75,10 +75,21 @@ func (typ *Type) UnmarshalText(data []byte) error {
 	return nil
 }
 
+// Protobuf support
+func (typ Type) Marshal() ([]byte, error) {
+	return typ.MarshalText()
+}
+
+func (typ *Type) Unmarshal(data []byte) error {
+	return typ.UnmarshalText(data)
+}
+
 type Payload interface {
 	String() string
 	GetInputs() []*TxInput
 	Type() Type
+	// The serialised size in bytes
+	Size() int
 }
 
 func New(txType Type) Payload {
diff --git a/txs/payload/payload.pb.go b/txs/payload/payload.pb.go
new file mode 100644
index 0000000000000000000000000000000000000000..a5e27c742767e7080a284510272574ec29ecf60a
--- /dev/null
+++ b/txs/payload/payload.pb.go
@@ -0,0 +1,2498 @@
+// Code generated by protoc-gen-gogo. DO NOT EDIT.
+// source: payload.proto
+
+/*
+	Package payload is a generated protocol buffer package.
+
+	It is generated from these files:
+		payload.proto
+
+	It has these top-level messages:
+		AnyPayload
+		TxInput
+		TxOutput
+		CallTx
+		SendTx
+		PermissionsTx
+		NameTx
+		BondTx
+		UnbondTx
+		GovernanceTx
+*/
+package payload
+
+import proto "github.com/gogo/protobuf/proto"
+import golang_proto "github.com/golang/protobuf/proto"
+import fmt "fmt"
+import math "math"
+import _ "github.com/gogo/protobuf/gogoproto"
+import permission "github.com/hyperledger/burrow/permission"
+import spec "github.com/hyperledger/burrow/genesis/spec"
+
+import github_com_hyperledger_burrow_crypto "github.com/hyperledger/burrow/crypto"
+import github_com_hyperledger_burrow_binary "github.com/hyperledger/burrow/binary"
+
+import io "io"
+
+// Reference imports to suppress errors if they are not otherwise used.
+var _ = proto.Marshal
+var _ = golang_proto.Marshal
+var _ = fmt.Errorf
+var _ = math.Inf
+
+// This is a compile-time assertion to ensure that this generated file
+// is compatible with the proto package it is being compiled against.
+// A compilation error at this line likely means your copy of the
+// proto package needs to be updated.
+const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package
+
+type AnyPayload struct {
+	CallTx        *CallTx        `protobuf:"bytes,1,opt,name=CallTx" json:"CallTx,omitempty"`
+	SendTx        *SendTx        `protobuf:"bytes,2,opt,name=SendTx" json:"SendTx,omitempty"`
+	NameTx        *NameTx        `protobuf:"bytes,3,opt,name=NameTx" json:"NameTx,omitempty"`
+	PermissionsTx *PermissionsTx `protobuf:"bytes,4,opt,name=PermissionsTx" json:"PermissionsTx,omitempty"`
+	GovernanceTx  *GovernanceTx  `protobuf:"bytes,5,opt,name=GovernanceTx" json:"GovernanceTx,omitempty"`
+}
+
+func (m *AnyPayload) Reset()                    { *m = AnyPayload{} }
+func (m *AnyPayload) String() string            { return proto.CompactTextString(m) }
+func (*AnyPayload) ProtoMessage()               {}
+func (*AnyPayload) Descriptor() ([]byte, []int) { return fileDescriptorPayload, []int{0} }
+
+func (m *AnyPayload) GetCallTx() *CallTx {
+	if m != nil {
+		return m.CallTx
+	}
+	return nil
+}
+
+func (m *AnyPayload) GetSendTx() *SendTx {
+	if m != nil {
+		return m.SendTx
+	}
+	return nil
+}
+
+func (m *AnyPayload) GetNameTx() *NameTx {
+	if m != nil {
+		return m.NameTx
+	}
+	return nil
+}
+
+func (m *AnyPayload) GetPermissionsTx() *PermissionsTx {
+	if m != nil {
+		return m.PermissionsTx
+	}
+	return nil
+}
+
+func (m *AnyPayload) GetGovernanceTx() *GovernanceTx {
+	if m != nil {
+		return m.GovernanceTx
+	}
+	return nil
+}
+
+func (*AnyPayload) XXX_MessageName() string {
+	return "payload.AnyPayload"
+}
+
+// An input to a transaction that may carry an Amount as a charge and whose sequence number must be one greater than
+// that associated with the account at Address at the time of being received
+type TxInput struct {
+	// The address from which this input flows
+	Address github_com_hyperledger_burrow_crypto.Address `protobuf:"bytes,1,opt,name=Address,proto3,customtype=github.com/hyperledger/burrow/crypto.Address" json:"Address"`
+	// The amount of native token to transfer from the input address
+	Amount uint64 `protobuf:"varint,2,opt,name=Amount,proto3" json:"Amount,omitempty"`
+	// The sequence number that this transaction will induce (i.e. one greater than the input account's current sequence)
+	Sequence uint64 `protobuf:"varint,3,opt,name=Sequence,proto3" json:"Sequence,omitempty"`
+}
+
+func (m *TxInput) Reset()                    { *m = TxInput{} }
+func (*TxInput) ProtoMessage()               {}
+func (*TxInput) Descriptor() ([]byte, []int) { return fileDescriptorPayload, []int{1} }
+
+func (m *TxInput) GetAmount() uint64 {
+	if m != nil {
+		return m.Amount
+	}
+	return 0
+}
+
+func (m *TxInput) GetSequence() uint64 {
+	if m != nil {
+		return m.Sequence
+	}
+	return 0
+}
+
+func (*TxInput) XXX_MessageName() string {
+	return "payload.TxInput"
+}
+
+// An output from a transaction that may carry an amount as a charge
+type TxOutput struct {
+	// The address to which this output flows
+	Address github_com_hyperledger_burrow_crypto.Address `protobuf:"bytes,1,opt,name=Address,proto3,customtype=github.com/hyperledger/burrow/crypto.Address" json:"Address"`
+	// The amount of native token to transfer to the output address
+	Amount uint64 `protobuf:"varint,2,opt,name=Amount,proto3" json:"Amount,omitempty"`
+}
+
+func (m *TxOutput) Reset()                    { *m = TxOutput{} }
+func (*TxOutput) ProtoMessage()               {}
+func (*TxOutput) Descriptor() ([]byte, []int) { return fileDescriptorPayload, []int{2} }
+
+func (m *TxOutput) GetAmount() uint64 {
+	if m != nil {
+		return m.Amount
+	}
+	return 0
+}
+
+func (*TxOutput) XXX_MessageName() string {
+	return "payload.TxOutput"
+}
+
+// A instruction to run smart contract code in the EVM
+type CallTx struct {
+	// The caller's input
+	Input *TxInput `protobuf:"bytes,1,opt,name=Input" json:"Input,omitempty"`
+	// The contract address to call or nil if we are creating a contract
+	Address *github_com_hyperledger_burrow_crypto.Address `protobuf:"bytes,2,opt,name=Address,proto3,customtype=github.com/hyperledger/burrow/crypto.Address" json:"Address,omitempty"`
+	// The upper bound on the amount of gas (and therefore EVM execution steps) this CallTx may generate
+	GasLimit uint64 `protobuf:"varint,3,opt,name=GasLimit,proto3" json:"GasLimit,omitempty"`
+	// Fee to offer validators for processing transaction
+	Fee uint64 `protobuf:"varint,4,opt,name=Fee,proto3" json:"Fee,omitempty"`
+	// EVM bytecode payload
+	Data github_com_hyperledger_burrow_binary.HexBytes `protobuf:"bytes,5,opt,name=Data,proto3,customtype=github.com/hyperledger/burrow/binary.HexBytes" json:"Data"`
+}
+
+func (m *CallTx) Reset()                    { *m = CallTx{} }
+func (*CallTx) ProtoMessage()               {}
+func (*CallTx) Descriptor() ([]byte, []int) { return fileDescriptorPayload, []int{3} }
+
+func (m *CallTx) GetInput() *TxInput {
+	if m != nil {
+		return m.Input
+	}
+	return nil
+}
+
+func (m *CallTx) GetGasLimit() uint64 {
+	if m != nil {
+		return m.GasLimit
+	}
+	return 0
+}
+
+func (m *CallTx) GetFee() uint64 {
+	if m != nil {
+		return m.Fee
+	}
+	return 0
+}
+
+func (*CallTx) XXX_MessageName() string {
+	return "payload.CallTx"
+}
+
+// A payment between two sets of parties
+type SendTx struct {
+	// The payers
+	Inputs []*TxInput `protobuf:"bytes,1,rep,name=Inputs" json:"Inputs,omitempty"`
+	// The payees
+	Outputs []*TxOutput `protobuf:"bytes,2,rep,name=Outputs" json:"Outputs,omitempty"`
+}
+
+func (m *SendTx) Reset()                    { *m = SendTx{} }
+func (*SendTx) ProtoMessage()               {}
+func (*SendTx) Descriptor() ([]byte, []int) { return fileDescriptorPayload, []int{4} }
+
+func (*SendTx) XXX_MessageName() string {
+	return "payload.SendTx"
+}
+
+// An update to the on-chain permissions
+type PermissionsTx struct {
+	// The permission moderator
+	Input *TxInput `protobuf:"bytes,1,opt,name=Input" json:"Input,omitempty"`
+	// The modified permissions
+	PermArgs permission.PermArgs `protobuf:"bytes,2,opt,name=PermArgs" json:"PermArgs"`
+}
+
+func (m *PermissionsTx) Reset()                    { *m = PermissionsTx{} }
+func (*PermissionsTx) ProtoMessage()               {}
+func (*PermissionsTx) Descriptor() ([]byte, []int) { return fileDescriptorPayload, []int{5} }
+
+func (m *PermissionsTx) GetInput() *TxInput {
+	if m != nil {
+		return m.Input
+	}
+	return nil
+}
+
+func (m *PermissionsTx) GetPermArgs() permission.PermArgs {
+	if m != nil {
+		return m.PermArgs
+	}
+	return permission.PermArgs{}
+}
+
+func (*PermissionsTx) XXX_MessageName() string {
+	return "payload.PermissionsTx"
+}
+
+// A request to claim a globally unique name across the entire chain with some optional data storage leased for a fee
+type NameTx struct {
+	// The name updater
+	Input *TxInput `protobuf:"bytes,1,opt,name=Input" json:"Input,omitempty"`
+	// The name to update or create
+	Name string `protobuf:"bytes,2,opt,name=Name,proto3" json:"Name,omitempty"`
+	// The data to store against the name
+	Data string `protobuf:"bytes,3,opt,name=Data,proto3" json:"Data,omitempty"`
+	// The fee to provide that will determine the lenght of the name lease
+	Fee uint64 `protobuf:"varint,4,opt,name=Fee,proto3" json:"Fee,omitempty"`
+}
+
+func (m *NameTx) Reset()                    { *m = NameTx{} }
+func (*NameTx) ProtoMessage()               {}
+func (*NameTx) Descriptor() ([]byte, []int) { return fileDescriptorPayload, []int{6} }
+
+func (m *NameTx) GetInput() *TxInput {
+	if m != nil {
+		return m.Input
+	}
+	return nil
+}
+
+func (m *NameTx) GetName() string {
+	if m != nil {
+		return m.Name
+	}
+	return ""
+}
+
+func (m *NameTx) GetData() string {
+	if m != nil {
+		return m.Data
+	}
+	return ""
+}
+
+func (m *NameTx) GetFee() uint64 {
+	if m != nil {
+		return m.Fee
+	}
+	return 0
+}
+
+func (*NameTx) XXX_MessageName() string {
+	return "payload.NameTx"
+}
+
+type BondTx struct {
+	Inputs   []*TxInput  `protobuf:"bytes,1,rep,name=Inputs" json:"Inputs,omitempty"`
+	UnbondTo []*TxOutput `protobuf:"bytes,2,rep,name=UnbondTo" json:"UnbondTo,omitempty"`
+}
+
+func (m *BondTx) Reset()                    { *m = BondTx{} }
+func (*BondTx) ProtoMessage()               {}
+func (*BondTx) Descriptor() ([]byte, []int) { return fileDescriptorPayload, []int{7} }
+
+func (*BondTx) XXX_MessageName() string {
+	return "payload.BondTx"
+}
+
+type UnbondTx struct {
+	Input   *TxInput                                     `protobuf:"bytes,1,opt,name=Input" json:"Input,omitempty"`
+	Address github_com_hyperledger_burrow_crypto.Address `protobuf:"bytes,2,opt,name=Address,proto3,customtype=github.com/hyperledger/burrow/crypto.Address" json:"Address"`
+	Height  uint64                                       `protobuf:"varint,3,opt,name=Height,proto3" json:"Height,omitempty"`
+}
+
+func (m *UnbondTx) Reset()                    { *m = UnbondTx{} }
+func (*UnbondTx) ProtoMessage()               {}
+func (*UnbondTx) Descriptor() ([]byte, []int) { return fileDescriptorPayload, []int{8} }
+
+func (*UnbondTx) XXX_MessageName() string {
+	return "payload.UnbondTx"
+}
+
+type GovernanceTx struct {
+	Inputs         []*TxInput              `protobuf:"bytes,1,rep,name=Inputs" json:"Inputs,omitempty"`
+	AccountUpdates []*spec.TemplateAccount `protobuf:"bytes,2,rep,name=AccountUpdates" json:"AccountUpdates,omitempty"`
+}
+
+func (m *GovernanceTx) Reset()                    { *m = GovernanceTx{} }
+func (*GovernanceTx) ProtoMessage()               {}
+func (*GovernanceTx) Descriptor() ([]byte, []int) { return fileDescriptorPayload, []int{9} }
+
+func (*GovernanceTx) XXX_MessageName() string {
+	return "payload.GovernanceTx"
+}
+func init() {
+	proto.RegisterType((*AnyPayload)(nil), "payload.AnyPayload")
+	golang_proto.RegisterType((*AnyPayload)(nil), "payload.AnyPayload")
+	proto.RegisterType((*TxInput)(nil), "payload.TxInput")
+	golang_proto.RegisterType((*TxInput)(nil), "payload.TxInput")
+	proto.RegisterType((*TxOutput)(nil), "payload.TxOutput")
+	golang_proto.RegisterType((*TxOutput)(nil), "payload.TxOutput")
+	proto.RegisterType((*CallTx)(nil), "payload.CallTx")
+	golang_proto.RegisterType((*CallTx)(nil), "payload.CallTx")
+	proto.RegisterType((*SendTx)(nil), "payload.SendTx")
+	golang_proto.RegisterType((*SendTx)(nil), "payload.SendTx")
+	proto.RegisterType((*PermissionsTx)(nil), "payload.PermissionsTx")
+	golang_proto.RegisterType((*PermissionsTx)(nil), "payload.PermissionsTx")
+	proto.RegisterType((*NameTx)(nil), "payload.NameTx")
+	golang_proto.RegisterType((*NameTx)(nil), "payload.NameTx")
+	proto.RegisterType((*BondTx)(nil), "payload.BondTx")
+	golang_proto.RegisterType((*BondTx)(nil), "payload.BondTx")
+	proto.RegisterType((*UnbondTx)(nil), "payload.UnbondTx")
+	golang_proto.RegisterType((*UnbondTx)(nil), "payload.UnbondTx")
+	proto.RegisterType((*GovernanceTx)(nil), "payload.GovernanceTx")
+	golang_proto.RegisterType((*GovernanceTx)(nil), "payload.GovernanceTx")
+}
+func (m *AnyPayload) Marshal() (dAtA []byte, err error) {
+	size := m.Size()
+	dAtA = make([]byte, size)
+	n, err := m.MarshalTo(dAtA)
+	if err != nil {
+		return nil, err
+	}
+	return dAtA[:n], nil
+}
+
+func (m *AnyPayload) MarshalTo(dAtA []byte) (int, error) {
+	var i int
+	_ = i
+	var l int
+	_ = l
+	if m.CallTx != nil {
+		dAtA[i] = 0xa
+		i++
+		i = encodeVarintPayload(dAtA, i, uint64(m.CallTx.Size()))
+		n1, err := m.CallTx.MarshalTo(dAtA[i:])
+		if err != nil {
+			return 0, err
+		}
+		i += n1
+	}
+	if m.SendTx != nil {
+		dAtA[i] = 0x12
+		i++
+		i = encodeVarintPayload(dAtA, i, uint64(m.SendTx.Size()))
+		n2, err := m.SendTx.MarshalTo(dAtA[i:])
+		if err != nil {
+			return 0, err
+		}
+		i += n2
+	}
+	if m.NameTx != nil {
+		dAtA[i] = 0x1a
+		i++
+		i = encodeVarintPayload(dAtA, i, uint64(m.NameTx.Size()))
+		n3, err := m.NameTx.MarshalTo(dAtA[i:])
+		if err != nil {
+			return 0, err
+		}
+		i += n3
+	}
+	if m.PermissionsTx != nil {
+		dAtA[i] = 0x22
+		i++
+		i = encodeVarintPayload(dAtA, i, uint64(m.PermissionsTx.Size()))
+		n4, err := m.PermissionsTx.MarshalTo(dAtA[i:])
+		if err != nil {
+			return 0, err
+		}
+		i += n4
+	}
+	if m.GovernanceTx != nil {
+		dAtA[i] = 0x2a
+		i++
+		i = encodeVarintPayload(dAtA, i, uint64(m.GovernanceTx.Size()))
+		n5, err := m.GovernanceTx.MarshalTo(dAtA[i:])
+		if err != nil {
+			return 0, err
+		}
+		i += n5
+	}
+	return i, nil
+}
+
+func (m *TxInput) Marshal() (dAtA []byte, err error) {
+	size := m.Size()
+	dAtA = make([]byte, size)
+	n, err := m.MarshalTo(dAtA)
+	if err != nil {
+		return nil, err
+	}
+	return dAtA[:n], nil
+}
+
+func (m *TxInput) MarshalTo(dAtA []byte) (int, error) {
+	var i int
+	_ = i
+	var l int
+	_ = l
+	dAtA[i] = 0xa
+	i++
+	i = encodeVarintPayload(dAtA, i, uint64(m.Address.Size()))
+	n6, err := m.Address.MarshalTo(dAtA[i:])
+	if err != nil {
+		return 0, err
+	}
+	i += n6
+	if m.Amount != 0 {
+		dAtA[i] = 0x10
+		i++
+		i = encodeVarintPayload(dAtA, i, uint64(m.Amount))
+	}
+	if m.Sequence != 0 {
+		dAtA[i] = 0x18
+		i++
+		i = encodeVarintPayload(dAtA, i, uint64(m.Sequence))
+	}
+	return i, nil
+}
+
+func (m *TxOutput) Marshal() (dAtA []byte, err error) {
+	size := m.Size()
+	dAtA = make([]byte, size)
+	n, err := m.MarshalTo(dAtA)
+	if err != nil {
+		return nil, err
+	}
+	return dAtA[:n], nil
+}
+
+func (m *TxOutput) MarshalTo(dAtA []byte) (int, error) {
+	var i int
+	_ = i
+	var l int
+	_ = l
+	dAtA[i] = 0xa
+	i++
+	i = encodeVarintPayload(dAtA, i, uint64(m.Address.Size()))
+	n7, err := m.Address.MarshalTo(dAtA[i:])
+	if err != nil {
+		return 0, err
+	}
+	i += n7
+	if m.Amount != 0 {
+		dAtA[i] = 0x10
+		i++
+		i = encodeVarintPayload(dAtA, i, uint64(m.Amount))
+	}
+	return i, nil
+}
+
+func (m *CallTx) Marshal() (dAtA []byte, err error) {
+	size := m.Size()
+	dAtA = make([]byte, size)
+	n, err := m.MarshalTo(dAtA)
+	if err != nil {
+		return nil, err
+	}
+	return dAtA[:n], nil
+}
+
+func (m *CallTx) MarshalTo(dAtA []byte) (int, error) {
+	var i int
+	_ = i
+	var l int
+	_ = l
+	if m.Input != nil {
+		dAtA[i] = 0xa
+		i++
+		i = encodeVarintPayload(dAtA, i, uint64(m.Input.Size()))
+		n8, err := m.Input.MarshalTo(dAtA[i:])
+		if err != nil {
+			return 0, err
+		}
+		i += n8
+	}
+	if m.Address != nil {
+		dAtA[i] = 0x12
+		i++
+		i = encodeVarintPayload(dAtA, i, uint64(m.Address.Size()))
+		n9, err := m.Address.MarshalTo(dAtA[i:])
+		if err != nil {
+			return 0, err
+		}
+		i += n9
+	}
+	if m.GasLimit != 0 {
+		dAtA[i] = 0x18
+		i++
+		i = encodeVarintPayload(dAtA, i, uint64(m.GasLimit))
+	}
+	if m.Fee != 0 {
+		dAtA[i] = 0x20
+		i++
+		i = encodeVarintPayload(dAtA, i, uint64(m.Fee))
+	}
+	dAtA[i] = 0x2a
+	i++
+	i = encodeVarintPayload(dAtA, i, uint64(m.Data.Size()))
+	n10, err := m.Data.MarshalTo(dAtA[i:])
+	if err != nil {
+		return 0, err
+	}
+	i += n10
+	return i, nil
+}
+
+func (m *SendTx) Marshal() (dAtA []byte, err error) {
+	size := m.Size()
+	dAtA = make([]byte, size)
+	n, err := m.MarshalTo(dAtA)
+	if err != nil {
+		return nil, err
+	}
+	return dAtA[:n], nil
+}
+
+func (m *SendTx) MarshalTo(dAtA []byte) (int, error) {
+	var i int
+	_ = i
+	var l int
+	_ = l
+	if len(m.Inputs) > 0 {
+		for _, msg := range m.Inputs {
+			dAtA[i] = 0xa
+			i++
+			i = encodeVarintPayload(dAtA, i, uint64(msg.Size()))
+			n, err := msg.MarshalTo(dAtA[i:])
+			if err != nil {
+				return 0, err
+			}
+			i += n
+		}
+	}
+	if len(m.Outputs) > 0 {
+		for _, msg := range m.Outputs {
+			dAtA[i] = 0x12
+			i++
+			i = encodeVarintPayload(dAtA, i, uint64(msg.Size()))
+			n, err := msg.MarshalTo(dAtA[i:])
+			if err != nil {
+				return 0, err
+			}
+			i += n
+		}
+	}
+	return i, nil
+}
+
+func (m *PermissionsTx) Marshal() (dAtA []byte, err error) {
+	size := m.Size()
+	dAtA = make([]byte, size)
+	n, err := m.MarshalTo(dAtA)
+	if err != nil {
+		return nil, err
+	}
+	return dAtA[:n], nil
+}
+
+func (m *PermissionsTx) MarshalTo(dAtA []byte) (int, error) {
+	var i int
+	_ = i
+	var l int
+	_ = l
+	if m.Input != nil {
+		dAtA[i] = 0xa
+		i++
+		i = encodeVarintPayload(dAtA, i, uint64(m.Input.Size()))
+		n11, err := m.Input.MarshalTo(dAtA[i:])
+		if err != nil {
+			return 0, err
+		}
+		i += n11
+	}
+	dAtA[i] = 0x12
+	i++
+	i = encodeVarintPayload(dAtA, i, uint64(m.PermArgs.Size()))
+	n12, err := m.PermArgs.MarshalTo(dAtA[i:])
+	if err != nil {
+		return 0, err
+	}
+	i += n12
+	return i, nil
+}
+
+func (m *NameTx) Marshal() (dAtA []byte, err error) {
+	size := m.Size()
+	dAtA = make([]byte, size)
+	n, err := m.MarshalTo(dAtA)
+	if err != nil {
+		return nil, err
+	}
+	return dAtA[:n], nil
+}
+
+func (m *NameTx) MarshalTo(dAtA []byte) (int, error) {
+	var i int
+	_ = i
+	var l int
+	_ = l
+	if m.Input != nil {
+		dAtA[i] = 0xa
+		i++
+		i = encodeVarintPayload(dAtA, i, uint64(m.Input.Size()))
+		n13, err := m.Input.MarshalTo(dAtA[i:])
+		if err != nil {
+			return 0, err
+		}
+		i += n13
+	}
+	if len(m.Name) > 0 {
+		dAtA[i] = 0x12
+		i++
+		i = encodeVarintPayload(dAtA, i, uint64(len(m.Name)))
+		i += copy(dAtA[i:], m.Name)
+	}
+	if len(m.Data) > 0 {
+		dAtA[i] = 0x1a
+		i++
+		i = encodeVarintPayload(dAtA, i, uint64(len(m.Data)))
+		i += copy(dAtA[i:], m.Data)
+	}
+	if m.Fee != 0 {
+		dAtA[i] = 0x20
+		i++
+		i = encodeVarintPayload(dAtA, i, uint64(m.Fee))
+	}
+	return i, nil
+}
+
+func (m *BondTx) Marshal() (dAtA []byte, err error) {
+	size := m.Size()
+	dAtA = make([]byte, size)
+	n, err := m.MarshalTo(dAtA)
+	if err != nil {
+		return nil, err
+	}
+	return dAtA[:n], nil
+}
+
+func (m *BondTx) MarshalTo(dAtA []byte) (int, error) {
+	var i int
+	_ = i
+	var l int
+	_ = l
+	if len(m.Inputs) > 0 {
+		for _, msg := range m.Inputs {
+			dAtA[i] = 0xa
+			i++
+			i = encodeVarintPayload(dAtA, i, uint64(msg.Size()))
+			n, err := msg.MarshalTo(dAtA[i:])
+			if err != nil {
+				return 0, err
+			}
+			i += n
+		}
+	}
+	if len(m.UnbondTo) > 0 {
+		for _, msg := range m.UnbondTo {
+			dAtA[i] = 0x12
+			i++
+			i = encodeVarintPayload(dAtA, i, uint64(msg.Size()))
+			n, err := msg.MarshalTo(dAtA[i:])
+			if err != nil {
+				return 0, err
+			}
+			i += n
+		}
+	}
+	return i, nil
+}
+
+func (m *UnbondTx) Marshal() (dAtA []byte, err error) {
+	size := m.Size()
+	dAtA = make([]byte, size)
+	n, err := m.MarshalTo(dAtA)
+	if err != nil {
+		return nil, err
+	}
+	return dAtA[:n], nil
+}
+
+func (m *UnbondTx) MarshalTo(dAtA []byte) (int, error) {
+	var i int
+	_ = i
+	var l int
+	_ = l
+	if m.Input != nil {
+		dAtA[i] = 0xa
+		i++
+		i = encodeVarintPayload(dAtA, i, uint64(m.Input.Size()))
+		n14, err := m.Input.MarshalTo(dAtA[i:])
+		if err != nil {
+			return 0, err
+		}
+		i += n14
+	}
+	dAtA[i] = 0x12
+	i++
+	i = encodeVarintPayload(dAtA, i, uint64(m.Address.Size()))
+	n15, err := m.Address.MarshalTo(dAtA[i:])
+	if err != nil {
+		return 0, err
+	}
+	i += n15
+	if m.Height != 0 {
+		dAtA[i] = 0x18
+		i++
+		i = encodeVarintPayload(dAtA, i, uint64(m.Height))
+	}
+	return i, nil
+}
+
+func (m *GovernanceTx) Marshal() (dAtA []byte, err error) {
+	size := m.Size()
+	dAtA = make([]byte, size)
+	n, err := m.MarshalTo(dAtA)
+	if err != nil {
+		return nil, err
+	}
+	return dAtA[:n], nil
+}
+
+func (m *GovernanceTx) MarshalTo(dAtA []byte) (int, error) {
+	var i int
+	_ = i
+	var l int
+	_ = l
+	if len(m.Inputs) > 0 {
+		for _, msg := range m.Inputs {
+			dAtA[i] = 0xa
+			i++
+			i = encodeVarintPayload(dAtA, i, uint64(msg.Size()))
+			n, err := msg.MarshalTo(dAtA[i:])
+			if err != nil {
+				return 0, err
+			}
+			i += n
+		}
+	}
+	if len(m.AccountUpdates) > 0 {
+		for _, msg := range m.AccountUpdates {
+			dAtA[i] = 0x12
+			i++
+			i = encodeVarintPayload(dAtA, i, uint64(msg.Size()))
+			n, err := msg.MarshalTo(dAtA[i:])
+			if err != nil {
+				return 0, err
+			}
+			i += n
+		}
+	}
+	return i, nil
+}
+
+func encodeVarintPayload(dAtA []byte, offset int, v uint64) int {
+	for v >= 1<<7 {
+		dAtA[offset] = uint8(v&0x7f | 0x80)
+		v >>= 7
+		offset++
+	}
+	dAtA[offset] = uint8(v)
+	return offset + 1
+}
+func (m *AnyPayload) Size() (n int) {
+	var l int
+	_ = l
+	if m.CallTx != nil {
+		l = m.CallTx.Size()
+		n += 1 + l + sovPayload(uint64(l))
+	}
+	if m.SendTx != nil {
+		l = m.SendTx.Size()
+		n += 1 + l + sovPayload(uint64(l))
+	}
+	if m.NameTx != nil {
+		l = m.NameTx.Size()
+		n += 1 + l + sovPayload(uint64(l))
+	}
+	if m.PermissionsTx != nil {
+		l = m.PermissionsTx.Size()
+		n += 1 + l + sovPayload(uint64(l))
+	}
+	if m.GovernanceTx != nil {
+		l = m.GovernanceTx.Size()
+		n += 1 + l + sovPayload(uint64(l))
+	}
+	return n
+}
+
+func (m *TxInput) Size() (n int) {
+	var l int
+	_ = l
+	l = m.Address.Size()
+	n += 1 + l + sovPayload(uint64(l))
+	if m.Amount != 0 {
+		n += 1 + sovPayload(uint64(m.Amount))
+	}
+	if m.Sequence != 0 {
+		n += 1 + sovPayload(uint64(m.Sequence))
+	}
+	return n
+}
+
+func (m *TxOutput) Size() (n int) {
+	var l int
+	_ = l
+	l = m.Address.Size()
+	n += 1 + l + sovPayload(uint64(l))
+	if m.Amount != 0 {
+		n += 1 + sovPayload(uint64(m.Amount))
+	}
+	return n
+}
+
+func (m *CallTx) Size() (n int) {
+	var l int
+	_ = l
+	if m.Input != nil {
+		l = m.Input.Size()
+		n += 1 + l + sovPayload(uint64(l))
+	}
+	if m.Address != nil {
+		l = m.Address.Size()
+		n += 1 + l + sovPayload(uint64(l))
+	}
+	if m.GasLimit != 0 {
+		n += 1 + sovPayload(uint64(m.GasLimit))
+	}
+	if m.Fee != 0 {
+		n += 1 + sovPayload(uint64(m.Fee))
+	}
+	l = m.Data.Size()
+	n += 1 + l + sovPayload(uint64(l))
+	return n
+}
+
+func (m *SendTx) Size() (n int) {
+	var l int
+	_ = l
+	if len(m.Inputs) > 0 {
+		for _, e := range m.Inputs {
+			l = e.Size()
+			n += 1 + l + sovPayload(uint64(l))
+		}
+	}
+	if len(m.Outputs) > 0 {
+		for _, e := range m.Outputs {
+			l = e.Size()
+			n += 1 + l + sovPayload(uint64(l))
+		}
+	}
+	return n
+}
+
+func (m *PermissionsTx) Size() (n int) {
+	var l int
+	_ = l
+	if m.Input != nil {
+		l = m.Input.Size()
+		n += 1 + l + sovPayload(uint64(l))
+	}
+	l = m.PermArgs.Size()
+	n += 1 + l + sovPayload(uint64(l))
+	return n
+}
+
+func (m *NameTx) Size() (n int) {
+	var l int
+	_ = l
+	if m.Input != nil {
+		l = m.Input.Size()
+		n += 1 + l + sovPayload(uint64(l))
+	}
+	l = len(m.Name)
+	if l > 0 {
+		n += 1 + l + sovPayload(uint64(l))
+	}
+	l = len(m.Data)
+	if l > 0 {
+		n += 1 + l + sovPayload(uint64(l))
+	}
+	if m.Fee != 0 {
+		n += 1 + sovPayload(uint64(m.Fee))
+	}
+	return n
+}
+
+func (m *BondTx) Size() (n int) {
+	var l int
+	_ = l
+	if len(m.Inputs) > 0 {
+		for _, e := range m.Inputs {
+			l = e.Size()
+			n += 1 + l + sovPayload(uint64(l))
+		}
+	}
+	if len(m.UnbondTo) > 0 {
+		for _, e := range m.UnbondTo {
+			l = e.Size()
+			n += 1 + l + sovPayload(uint64(l))
+		}
+	}
+	return n
+}
+
+func (m *UnbondTx) Size() (n int) {
+	var l int
+	_ = l
+	if m.Input != nil {
+		l = m.Input.Size()
+		n += 1 + l + sovPayload(uint64(l))
+	}
+	l = m.Address.Size()
+	n += 1 + l + sovPayload(uint64(l))
+	if m.Height != 0 {
+		n += 1 + sovPayload(uint64(m.Height))
+	}
+	return n
+}
+
+func (m *GovernanceTx) Size() (n int) {
+	var l int
+	_ = l
+	if len(m.Inputs) > 0 {
+		for _, e := range m.Inputs {
+			l = e.Size()
+			n += 1 + l + sovPayload(uint64(l))
+		}
+	}
+	if len(m.AccountUpdates) > 0 {
+		for _, e := range m.AccountUpdates {
+			l = e.Size()
+			n += 1 + l + sovPayload(uint64(l))
+		}
+	}
+	return n
+}
+
+func sovPayload(x uint64) (n int) {
+	for {
+		n++
+		x >>= 7
+		if x == 0 {
+			break
+		}
+	}
+	return n
+}
+func sozPayload(x uint64) (n int) {
+	return sovPayload(uint64((x << 1) ^ uint64((int64(x) >> 63))))
+}
+func (m *AnyPayload) Unmarshal(dAtA []byte) error {
+	l := len(dAtA)
+	iNdEx := 0
+	for iNdEx < l {
+		preIndex := iNdEx
+		var wire uint64
+		for shift := uint(0); ; shift += 7 {
+			if shift >= 64 {
+				return ErrIntOverflowPayload
+			}
+			if iNdEx >= l {
+				return io.ErrUnexpectedEOF
+			}
+			b := dAtA[iNdEx]
+			iNdEx++
+			wire |= (uint64(b) & 0x7F) << shift
+			if b < 0x80 {
+				break
+			}
+		}
+		fieldNum := int32(wire >> 3)
+		wireType := int(wire & 0x7)
+		if wireType == 4 {
+			return fmt.Errorf("proto: AnyPayload: wiretype end group for non-group")
+		}
+		if fieldNum <= 0 {
+			return fmt.Errorf("proto: AnyPayload: illegal tag %d (wire type %d)", fieldNum, wire)
+		}
+		switch fieldNum {
+		case 1:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field CallTx", wireType)
+			}
+			var msglen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowPayload
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				msglen |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if msglen < 0 {
+				return ErrInvalidLengthPayload
+			}
+			postIndex := iNdEx + msglen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			if m.CallTx == nil {
+				m.CallTx = &CallTx{}
+			}
+			if err := m.CallTx.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+				return err
+			}
+			iNdEx = postIndex
+		case 2:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field SendTx", wireType)
+			}
+			var msglen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowPayload
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				msglen |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if msglen < 0 {
+				return ErrInvalidLengthPayload
+			}
+			postIndex := iNdEx + msglen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			if m.SendTx == nil {
+				m.SendTx = &SendTx{}
+			}
+			if err := m.SendTx.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+				return err
+			}
+			iNdEx = postIndex
+		case 3:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field NameTx", wireType)
+			}
+			var msglen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowPayload
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				msglen |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if msglen < 0 {
+				return ErrInvalidLengthPayload
+			}
+			postIndex := iNdEx + msglen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			if m.NameTx == nil {
+				m.NameTx = &NameTx{}
+			}
+			if err := m.NameTx.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+				return err
+			}
+			iNdEx = postIndex
+		case 4:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field PermissionsTx", wireType)
+			}
+			var msglen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowPayload
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				msglen |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if msglen < 0 {
+				return ErrInvalidLengthPayload
+			}
+			postIndex := iNdEx + msglen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			if m.PermissionsTx == nil {
+				m.PermissionsTx = &PermissionsTx{}
+			}
+			if err := m.PermissionsTx.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+				return err
+			}
+			iNdEx = postIndex
+		case 5:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field GovernanceTx", wireType)
+			}
+			var msglen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowPayload
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				msglen |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if msglen < 0 {
+				return ErrInvalidLengthPayload
+			}
+			postIndex := iNdEx + msglen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			if m.GovernanceTx == nil {
+				m.GovernanceTx = &GovernanceTx{}
+			}
+			if err := m.GovernanceTx.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+				return err
+			}
+			iNdEx = postIndex
+		default:
+			iNdEx = preIndex
+			skippy, err := skipPayload(dAtA[iNdEx:])
+			if err != nil {
+				return err
+			}
+			if skippy < 0 {
+				return ErrInvalidLengthPayload
+			}
+			if (iNdEx + skippy) > l {
+				return io.ErrUnexpectedEOF
+			}
+			iNdEx += skippy
+		}
+	}
+
+	if iNdEx > l {
+		return io.ErrUnexpectedEOF
+	}
+	return nil
+}
+func (m *TxInput) Unmarshal(dAtA []byte) error {
+	l := len(dAtA)
+	iNdEx := 0
+	for iNdEx < l {
+		preIndex := iNdEx
+		var wire uint64
+		for shift := uint(0); ; shift += 7 {
+			if shift >= 64 {
+				return ErrIntOverflowPayload
+			}
+			if iNdEx >= l {
+				return io.ErrUnexpectedEOF
+			}
+			b := dAtA[iNdEx]
+			iNdEx++
+			wire |= (uint64(b) & 0x7F) << shift
+			if b < 0x80 {
+				break
+			}
+		}
+		fieldNum := int32(wire >> 3)
+		wireType := int(wire & 0x7)
+		if wireType == 4 {
+			return fmt.Errorf("proto: TxInput: wiretype end group for non-group")
+		}
+		if fieldNum <= 0 {
+			return fmt.Errorf("proto: TxInput: illegal tag %d (wire type %d)", fieldNum, wire)
+		}
+		switch fieldNum {
+		case 1:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Address", wireType)
+			}
+			var byteLen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowPayload
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				byteLen |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if byteLen < 0 {
+				return ErrInvalidLengthPayload
+			}
+			postIndex := iNdEx + byteLen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			if err := m.Address.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+				return err
+			}
+			iNdEx = postIndex
+		case 2:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Amount", wireType)
+			}
+			m.Amount = 0
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowPayload
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				m.Amount |= (uint64(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+		case 3:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Sequence", wireType)
+			}
+			m.Sequence = 0
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowPayload
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				m.Sequence |= (uint64(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+		default:
+			iNdEx = preIndex
+			skippy, err := skipPayload(dAtA[iNdEx:])
+			if err != nil {
+				return err
+			}
+			if skippy < 0 {
+				return ErrInvalidLengthPayload
+			}
+			if (iNdEx + skippy) > l {
+				return io.ErrUnexpectedEOF
+			}
+			iNdEx += skippy
+		}
+	}
+
+	if iNdEx > l {
+		return io.ErrUnexpectedEOF
+	}
+	return nil
+}
+func (m *TxOutput) Unmarshal(dAtA []byte) error {
+	l := len(dAtA)
+	iNdEx := 0
+	for iNdEx < l {
+		preIndex := iNdEx
+		var wire uint64
+		for shift := uint(0); ; shift += 7 {
+			if shift >= 64 {
+				return ErrIntOverflowPayload
+			}
+			if iNdEx >= l {
+				return io.ErrUnexpectedEOF
+			}
+			b := dAtA[iNdEx]
+			iNdEx++
+			wire |= (uint64(b) & 0x7F) << shift
+			if b < 0x80 {
+				break
+			}
+		}
+		fieldNum := int32(wire >> 3)
+		wireType := int(wire & 0x7)
+		if wireType == 4 {
+			return fmt.Errorf("proto: TxOutput: wiretype end group for non-group")
+		}
+		if fieldNum <= 0 {
+			return fmt.Errorf("proto: TxOutput: illegal tag %d (wire type %d)", fieldNum, wire)
+		}
+		switch fieldNum {
+		case 1:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Address", wireType)
+			}
+			var byteLen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowPayload
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				byteLen |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if byteLen < 0 {
+				return ErrInvalidLengthPayload
+			}
+			postIndex := iNdEx + byteLen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			if err := m.Address.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+				return err
+			}
+			iNdEx = postIndex
+		case 2:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Amount", wireType)
+			}
+			m.Amount = 0
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowPayload
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				m.Amount |= (uint64(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+		default:
+			iNdEx = preIndex
+			skippy, err := skipPayload(dAtA[iNdEx:])
+			if err != nil {
+				return err
+			}
+			if skippy < 0 {
+				return ErrInvalidLengthPayload
+			}
+			if (iNdEx + skippy) > l {
+				return io.ErrUnexpectedEOF
+			}
+			iNdEx += skippy
+		}
+	}
+
+	if iNdEx > l {
+		return io.ErrUnexpectedEOF
+	}
+	return nil
+}
+func (m *CallTx) Unmarshal(dAtA []byte) error {
+	l := len(dAtA)
+	iNdEx := 0
+	for iNdEx < l {
+		preIndex := iNdEx
+		var wire uint64
+		for shift := uint(0); ; shift += 7 {
+			if shift >= 64 {
+				return ErrIntOverflowPayload
+			}
+			if iNdEx >= l {
+				return io.ErrUnexpectedEOF
+			}
+			b := dAtA[iNdEx]
+			iNdEx++
+			wire |= (uint64(b) & 0x7F) << shift
+			if b < 0x80 {
+				break
+			}
+		}
+		fieldNum := int32(wire >> 3)
+		wireType := int(wire & 0x7)
+		if wireType == 4 {
+			return fmt.Errorf("proto: CallTx: wiretype end group for non-group")
+		}
+		if fieldNum <= 0 {
+			return fmt.Errorf("proto: CallTx: illegal tag %d (wire type %d)", fieldNum, wire)
+		}
+		switch fieldNum {
+		case 1:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Input", wireType)
+			}
+			var msglen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowPayload
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				msglen |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if msglen < 0 {
+				return ErrInvalidLengthPayload
+			}
+			postIndex := iNdEx + msglen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			if m.Input == nil {
+				m.Input = &TxInput{}
+			}
+			if err := m.Input.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+				return err
+			}
+			iNdEx = postIndex
+		case 2:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Address", wireType)
+			}
+			var byteLen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowPayload
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				byteLen |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if byteLen < 0 {
+				return ErrInvalidLengthPayload
+			}
+			postIndex := iNdEx + byteLen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			var v github_com_hyperledger_burrow_crypto.Address
+			m.Address = &v
+			if err := m.Address.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+				return err
+			}
+			iNdEx = postIndex
+		case 3:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field GasLimit", wireType)
+			}
+			m.GasLimit = 0
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowPayload
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				m.GasLimit |= (uint64(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+		case 4:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Fee", wireType)
+			}
+			m.Fee = 0
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowPayload
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				m.Fee |= (uint64(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+		case 5:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Data", wireType)
+			}
+			var byteLen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowPayload
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				byteLen |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if byteLen < 0 {
+				return ErrInvalidLengthPayload
+			}
+			postIndex := iNdEx + byteLen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			if err := m.Data.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+				return err
+			}
+			iNdEx = postIndex
+		default:
+			iNdEx = preIndex
+			skippy, err := skipPayload(dAtA[iNdEx:])
+			if err != nil {
+				return err
+			}
+			if skippy < 0 {
+				return ErrInvalidLengthPayload
+			}
+			if (iNdEx + skippy) > l {
+				return io.ErrUnexpectedEOF
+			}
+			iNdEx += skippy
+		}
+	}
+
+	if iNdEx > l {
+		return io.ErrUnexpectedEOF
+	}
+	return nil
+}
+func (m *SendTx) Unmarshal(dAtA []byte) error {
+	l := len(dAtA)
+	iNdEx := 0
+	for iNdEx < l {
+		preIndex := iNdEx
+		var wire uint64
+		for shift := uint(0); ; shift += 7 {
+			if shift >= 64 {
+				return ErrIntOverflowPayload
+			}
+			if iNdEx >= l {
+				return io.ErrUnexpectedEOF
+			}
+			b := dAtA[iNdEx]
+			iNdEx++
+			wire |= (uint64(b) & 0x7F) << shift
+			if b < 0x80 {
+				break
+			}
+		}
+		fieldNum := int32(wire >> 3)
+		wireType := int(wire & 0x7)
+		if wireType == 4 {
+			return fmt.Errorf("proto: SendTx: wiretype end group for non-group")
+		}
+		if fieldNum <= 0 {
+			return fmt.Errorf("proto: SendTx: illegal tag %d (wire type %d)", fieldNum, wire)
+		}
+		switch fieldNum {
+		case 1:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Inputs", wireType)
+			}
+			var msglen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowPayload
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				msglen |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if msglen < 0 {
+				return ErrInvalidLengthPayload
+			}
+			postIndex := iNdEx + msglen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			m.Inputs = append(m.Inputs, &TxInput{})
+			if err := m.Inputs[len(m.Inputs)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+				return err
+			}
+			iNdEx = postIndex
+		case 2:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Outputs", wireType)
+			}
+			var msglen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowPayload
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				msglen |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if msglen < 0 {
+				return ErrInvalidLengthPayload
+			}
+			postIndex := iNdEx + msglen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			m.Outputs = append(m.Outputs, &TxOutput{})
+			if err := m.Outputs[len(m.Outputs)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+				return err
+			}
+			iNdEx = postIndex
+		default:
+			iNdEx = preIndex
+			skippy, err := skipPayload(dAtA[iNdEx:])
+			if err != nil {
+				return err
+			}
+			if skippy < 0 {
+				return ErrInvalidLengthPayload
+			}
+			if (iNdEx + skippy) > l {
+				return io.ErrUnexpectedEOF
+			}
+			iNdEx += skippy
+		}
+	}
+
+	if iNdEx > l {
+		return io.ErrUnexpectedEOF
+	}
+	return nil
+}
+func (m *PermissionsTx) Unmarshal(dAtA []byte) error {
+	l := len(dAtA)
+	iNdEx := 0
+	for iNdEx < l {
+		preIndex := iNdEx
+		var wire uint64
+		for shift := uint(0); ; shift += 7 {
+			if shift >= 64 {
+				return ErrIntOverflowPayload
+			}
+			if iNdEx >= l {
+				return io.ErrUnexpectedEOF
+			}
+			b := dAtA[iNdEx]
+			iNdEx++
+			wire |= (uint64(b) & 0x7F) << shift
+			if b < 0x80 {
+				break
+			}
+		}
+		fieldNum := int32(wire >> 3)
+		wireType := int(wire & 0x7)
+		if wireType == 4 {
+			return fmt.Errorf("proto: PermissionsTx: wiretype end group for non-group")
+		}
+		if fieldNum <= 0 {
+			return fmt.Errorf("proto: PermissionsTx: illegal tag %d (wire type %d)", fieldNum, wire)
+		}
+		switch fieldNum {
+		case 1:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Input", wireType)
+			}
+			var msglen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowPayload
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				msglen |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if msglen < 0 {
+				return ErrInvalidLengthPayload
+			}
+			postIndex := iNdEx + msglen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			if m.Input == nil {
+				m.Input = &TxInput{}
+			}
+			if err := m.Input.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+				return err
+			}
+			iNdEx = postIndex
+		case 2:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field PermArgs", wireType)
+			}
+			var msglen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowPayload
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				msglen |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if msglen < 0 {
+				return ErrInvalidLengthPayload
+			}
+			postIndex := iNdEx + msglen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			if err := m.PermArgs.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+				return err
+			}
+			iNdEx = postIndex
+		default:
+			iNdEx = preIndex
+			skippy, err := skipPayload(dAtA[iNdEx:])
+			if err != nil {
+				return err
+			}
+			if skippy < 0 {
+				return ErrInvalidLengthPayload
+			}
+			if (iNdEx + skippy) > l {
+				return io.ErrUnexpectedEOF
+			}
+			iNdEx += skippy
+		}
+	}
+
+	if iNdEx > l {
+		return io.ErrUnexpectedEOF
+	}
+	return nil
+}
+func (m *NameTx) Unmarshal(dAtA []byte) error {
+	l := len(dAtA)
+	iNdEx := 0
+	for iNdEx < l {
+		preIndex := iNdEx
+		var wire uint64
+		for shift := uint(0); ; shift += 7 {
+			if shift >= 64 {
+				return ErrIntOverflowPayload
+			}
+			if iNdEx >= l {
+				return io.ErrUnexpectedEOF
+			}
+			b := dAtA[iNdEx]
+			iNdEx++
+			wire |= (uint64(b) & 0x7F) << shift
+			if b < 0x80 {
+				break
+			}
+		}
+		fieldNum := int32(wire >> 3)
+		wireType := int(wire & 0x7)
+		if wireType == 4 {
+			return fmt.Errorf("proto: NameTx: wiretype end group for non-group")
+		}
+		if fieldNum <= 0 {
+			return fmt.Errorf("proto: NameTx: illegal tag %d (wire type %d)", fieldNum, wire)
+		}
+		switch fieldNum {
+		case 1:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Input", wireType)
+			}
+			var msglen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowPayload
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				msglen |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if msglen < 0 {
+				return ErrInvalidLengthPayload
+			}
+			postIndex := iNdEx + msglen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			if m.Input == nil {
+				m.Input = &TxInput{}
+			}
+			if err := m.Input.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+				return err
+			}
+			iNdEx = postIndex
+		case 2:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType)
+			}
+			var stringLen uint64
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowPayload
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				stringLen |= (uint64(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			intStringLen := int(stringLen)
+			if intStringLen < 0 {
+				return ErrInvalidLengthPayload
+			}
+			postIndex := iNdEx + intStringLen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			m.Name = string(dAtA[iNdEx:postIndex])
+			iNdEx = postIndex
+		case 3:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Data", wireType)
+			}
+			var stringLen uint64
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowPayload
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				stringLen |= (uint64(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			intStringLen := int(stringLen)
+			if intStringLen < 0 {
+				return ErrInvalidLengthPayload
+			}
+			postIndex := iNdEx + intStringLen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			m.Data = string(dAtA[iNdEx:postIndex])
+			iNdEx = postIndex
+		case 4:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Fee", wireType)
+			}
+			m.Fee = 0
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowPayload
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				m.Fee |= (uint64(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+		default:
+			iNdEx = preIndex
+			skippy, err := skipPayload(dAtA[iNdEx:])
+			if err != nil {
+				return err
+			}
+			if skippy < 0 {
+				return ErrInvalidLengthPayload
+			}
+			if (iNdEx + skippy) > l {
+				return io.ErrUnexpectedEOF
+			}
+			iNdEx += skippy
+		}
+	}
+
+	if iNdEx > l {
+		return io.ErrUnexpectedEOF
+	}
+	return nil
+}
+func (m *BondTx) Unmarshal(dAtA []byte) error {
+	l := len(dAtA)
+	iNdEx := 0
+	for iNdEx < l {
+		preIndex := iNdEx
+		var wire uint64
+		for shift := uint(0); ; shift += 7 {
+			if shift >= 64 {
+				return ErrIntOverflowPayload
+			}
+			if iNdEx >= l {
+				return io.ErrUnexpectedEOF
+			}
+			b := dAtA[iNdEx]
+			iNdEx++
+			wire |= (uint64(b) & 0x7F) << shift
+			if b < 0x80 {
+				break
+			}
+		}
+		fieldNum := int32(wire >> 3)
+		wireType := int(wire & 0x7)
+		if wireType == 4 {
+			return fmt.Errorf("proto: BondTx: wiretype end group for non-group")
+		}
+		if fieldNum <= 0 {
+			return fmt.Errorf("proto: BondTx: illegal tag %d (wire type %d)", fieldNum, wire)
+		}
+		switch fieldNum {
+		case 1:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Inputs", wireType)
+			}
+			var msglen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowPayload
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				msglen |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if msglen < 0 {
+				return ErrInvalidLengthPayload
+			}
+			postIndex := iNdEx + msglen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			m.Inputs = append(m.Inputs, &TxInput{})
+			if err := m.Inputs[len(m.Inputs)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+				return err
+			}
+			iNdEx = postIndex
+		case 2:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field UnbondTo", wireType)
+			}
+			var msglen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowPayload
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				msglen |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if msglen < 0 {
+				return ErrInvalidLengthPayload
+			}
+			postIndex := iNdEx + msglen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			m.UnbondTo = append(m.UnbondTo, &TxOutput{})
+			if err := m.UnbondTo[len(m.UnbondTo)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+				return err
+			}
+			iNdEx = postIndex
+		default:
+			iNdEx = preIndex
+			skippy, err := skipPayload(dAtA[iNdEx:])
+			if err != nil {
+				return err
+			}
+			if skippy < 0 {
+				return ErrInvalidLengthPayload
+			}
+			if (iNdEx + skippy) > l {
+				return io.ErrUnexpectedEOF
+			}
+			iNdEx += skippy
+		}
+	}
+
+	if iNdEx > l {
+		return io.ErrUnexpectedEOF
+	}
+	return nil
+}
+func (m *UnbondTx) Unmarshal(dAtA []byte) error {
+	l := len(dAtA)
+	iNdEx := 0
+	for iNdEx < l {
+		preIndex := iNdEx
+		var wire uint64
+		for shift := uint(0); ; shift += 7 {
+			if shift >= 64 {
+				return ErrIntOverflowPayload
+			}
+			if iNdEx >= l {
+				return io.ErrUnexpectedEOF
+			}
+			b := dAtA[iNdEx]
+			iNdEx++
+			wire |= (uint64(b) & 0x7F) << shift
+			if b < 0x80 {
+				break
+			}
+		}
+		fieldNum := int32(wire >> 3)
+		wireType := int(wire & 0x7)
+		if wireType == 4 {
+			return fmt.Errorf("proto: UnbondTx: wiretype end group for non-group")
+		}
+		if fieldNum <= 0 {
+			return fmt.Errorf("proto: UnbondTx: illegal tag %d (wire type %d)", fieldNum, wire)
+		}
+		switch fieldNum {
+		case 1:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Input", wireType)
+			}
+			var msglen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowPayload
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				msglen |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if msglen < 0 {
+				return ErrInvalidLengthPayload
+			}
+			postIndex := iNdEx + msglen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			if m.Input == nil {
+				m.Input = &TxInput{}
+			}
+			if err := m.Input.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+				return err
+			}
+			iNdEx = postIndex
+		case 2:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Address", wireType)
+			}
+			var byteLen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowPayload
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				byteLen |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if byteLen < 0 {
+				return ErrInvalidLengthPayload
+			}
+			postIndex := iNdEx + byteLen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			if err := m.Address.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+				return err
+			}
+			iNdEx = postIndex
+		case 3:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Height", wireType)
+			}
+			m.Height = 0
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowPayload
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				m.Height |= (uint64(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+		default:
+			iNdEx = preIndex
+			skippy, err := skipPayload(dAtA[iNdEx:])
+			if err != nil {
+				return err
+			}
+			if skippy < 0 {
+				return ErrInvalidLengthPayload
+			}
+			if (iNdEx + skippy) > l {
+				return io.ErrUnexpectedEOF
+			}
+			iNdEx += skippy
+		}
+	}
+
+	if iNdEx > l {
+		return io.ErrUnexpectedEOF
+	}
+	return nil
+}
+func (m *GovernanceTx) Unmarshal(dAtA []byte) error {
+	l := len(dAtA)
+	iNdEx := 0
+	for iNdEx < l {
+		preIndex := iNdEx
+		var wire uint64
+		for shift := uint(0); ; shift += 7 {
+			if shift >= 64 {
+				return ErrIntOverflowPayload
+			}
+			if iNdEx >= l {
+				return io.ErrUnexpectedEOF
+			}
+			b := dAtA[iNdEx]
+			iNdEx++
+			wire |= (uint64(b) & 0x7F) << shift
+			if b < 0x80 {
+				break
+			}
+		}
+		fieldNum := int32(wire >> 3)
+		wireType := int(wire & 0x7)
+		if wireType == 4 {
+			return fmt.Errorf("proto: GovernanceTx: wiretype end group for non-group")
+		}
+		if fieldNum <= 0 {
+			return fmt.Errorf("proto: GovernanceTx: illegal tag %d (wire type %d)", fieldNum, wire)
+		}
+		switch fieldNum {
+		case 1:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Inputs", wireType)
+			}
+			var msglen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowPayload
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				msglen |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if msglen < 0 {
+				return ErrInvalidLengthPayload
+			}
+			postIndex := iNdEx + msglen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			m.Inputs = append(m.Inputs, &TxInput{})
+			if err := m.Inputs[len(m.Inputs)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+				return err
+			}
+			iNdEx = postIndex
+		case 2:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field AccountUpdates", wireType)
+			}
+			var msglen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowPayload
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				msglen |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if msglen < 0 {
+				return ErrInvalidLengthPayload
+			}
+			postIndex := iNdEx + msglen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			m.AccountUpdates = append(m.AccountUpdates, &spec.TemplateAccount{})
+			if err := m.AccountUpdates[len(m.AccountUpdates)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+				return err
+			}
+			iNdEx = postIndex
+		default:
+			iNdEx = preIndex
+			skippy, err := skipPayload(dAtA[iNdEx:])
+			if err != nil {
+				return err
+			}
+			if skippy < 0 {
+				return ErrInvalidLengthPayload
+			}
+			if (iNdEx + skippy) > l {
+				return io.ErrUnexpectedEOF
+			}
+			iNdEx += skippy
+		}
+	}
+
+	if iNdEx > l {
+		return io.ErrUnexpectedEOF
+	}
+	return nil
+}
+func skipPayload(dAtA []byte) (n int, err error) {
+	l := len(dAtA)
+	iNdEx := 0
+	for iNdEx < l {
+		var wire uint64
+		for shift := uint(0); ; shift += 7 {
+			if shift >= 64 {
+				return 0, ErrIntOverflowPayload
+			}
+			if iNdEx >= l {
+				return 0, io.ErrUnexpectedEOF
+			}
+			b := dAtA[iNdEx]
+			iNdEx++
+			wire |= (uint64(b) & 0x7F) << shift
+			if b < 0x80 {
+				break
+			}
+		}
+		wireType := int(wire & 0x7)
+		switch wireType {
+		case 0:
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return 0, ErrIntOverflowPayload
+				}
+				if iNdEx >= l {
+					return 0, io.ErrUnexpectedEOF
+				}
+				iNdEx++
+				if dAtA[iNdEx-1] < 0x80 {
+					break
+				}
+			}
+			return iNdEx, nil
+		case 1:
+			iNdEx += 8
+			return iNdEx, nil
+		case 2:
+			var length int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return 0, ErrIntOverflowPayload
+				}
+				if iNdEx >= l {
+					return 0, io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				length |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			iNdEx += length
+			if length < 0 {
+				return 0, ErrInvalidLengthPayload
+			}
+			return iNdEx, nil
+		case 3:
+			for {
+				var innerWire uint64
+				var start int = iNdEx
+				for shift := uint(0); ; shift += 7 {
+					if shift >= 64 {
+						return 0, ErrIntOverflowPayload
+					}
+					if iNdEx >= l {
+						return 0, io.ErrUnexpectedEOF
+					}
+					b := dAtA[iNdEx]
+					iNdEx++
+					innerWire |= (uint64(b) & 0x7F) << shift
+					if b < 0x80 {
+						break
+					}
+				}
+				innerWireType := int(innerWire & 0x7)
+				if innerWireType == 4 {
+					break
+				}
+				next, err := skipPayload(dAtA[start:])
+				if err != nil {
+					return 0, err
+				}
+				iNdEx = start + next
+			}
+			return iNdEx, nil
+		case 4:
+			return iNdEx, nil
+		case 5:
+			iNdEx += 4
+			return iNdEx, nil
+		default:
+			return 0, fmt.Errorf("proto: illegal wireType %d", wireType)
+		}
+	}
+	panic("unreachable")
+}
+
+var (
+	ErrInvalidLengthPayload = fmt.Errorf("proto: negative length found during unmarshaling")
+	ErrIntOverflowPayload   = fmt.Errorf("proto: integer overflow")
+)
+
+func init() { proto.RegisterFile("payload.proto", fileDescriptorPayload) }
+func init() { golang_proto.RegisterFile("payload.proto", fileDescriptorPayload) }
+
+var fileDescriptorPayload = []byte{
+	// 652 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x55, 0xbf, 0x6f, 0xd3, 0x40,
+	0x14, 0xee, 0x35, 0x6e, 0x62, 0x8e, 0x16, 0xca, 0x89, 0x56, 0x51, 0x86, 0x04, 0x75, 0x80, 0x22,
+	0xa8, 0x83, 0xf8, 0x25, 0x51, 0x21, 0xa1, 0xb8, 0x88, 0xb6, 0x08, 0x85, 0xea, 0xea, 0x2e, 0x6c,
+	0xfe, 0x71, 0x38, 0x16, 0xb1, 0xcf, 0xd8, 0x67, 0xb0, 0x37, 0x36, 0xd8, 0x59, 0x18, 0x3b, 0xf0,
+	0x87, 0x30, 0x66, 0x64, 0x66, 0xa8, 0x50, 0xfa, 0x67, 0xb0, 0xa0, 0x3b, 0x9f, 0x5d, 0x27, 0x40,
+	0x95, 0x82, 0xc4, 0x76, 0xef, 0x7d, 0xdf, 0xbb, 0xf7, 0xde, 0x77, 0xef, 0xd9, 0x70, 0x29, 0x34,
+	0xb3, 0x21, 0x35, 0x1d, 0x2d, 0x8c, 0x28, 0xa3, 0xa8, 0x21, 0xcd, 0xd6, 0x86, 0xeb, 0xb1, 0x41,
+	0x62, 0x69, 0x36, 0xf5, 0xbb, 0x2e, 0x75, 0x69, 0x57, 0xe0, 0x56, 0xf2, 0x52, 0x58, 0xc2, 0x10,
+	0xa7, 0x3c, 0xae, 0xb5, 0x1c, 0x92, 0xc8, 0xf7, 0xe2, 0xd8, 0xa3, 0x81, 0xf4, 0xc0, 0x38, 0x24,
+	0x76, 0x7e, 0x5e, 0x7b, 0x37, 0x0f, 0x61, 0x2f, 0xc8, 0xf6, 0xf2, 0xbb, 0xd1, 0x35, 0x58, 0xdf,
+	0x32, 0x87, 0x43, 0x23, 0x6d, 0x82, 0x2b, 0x60, 0xfd, 0xfc, 0xed, 0x8b, 0x5a, 0x51, 0x44, 0xee,
+	0xc6, 0x12, 0xe6, 0xc4, 0x7d, 0x12, 0x38, 0x46, 0xda, 0x9c, 0x9f, 0x22, 0xe6, 0x6e, 0x2c, 0x61,
+	0x4e, 0xec, 0x9b, 0x3e, 0x31, 0xd2, 0x66, 0x6d, 0x8a, 0x98, 0xbb, 0xb1, 0x84, 0xd1, 0x43, 0xb8,
+	0xb4, 0x57, 0x56, 0x1a, 0x1b, 0x69, 0x53, 0x11, 0xfc, 0xd5, 0x92, 0x3f, 0x81, 0xe2, 0x49, 0x32,
+	0x7a, 0x00, 0x17, 0xb7, 0xe9, 0x1b, 0x12, 0x05, 0x66, 0x60, 0xf3, 0x64, 0x0b, 0x22, 0x78, 0xa5,
+	0x0c, 0xae, 0x82, 0x78, 0x82, 0xba, 0xf6, 0x11, 0xc0, 0x86, 0x91, 0xee, 0x06, 0x61, 0xc2, 0x50,
+	0x1f, 0x36, 0x7a, 0x8e, 0x13, 0x91, 0x38, 0x16, 0x02, 0x2c, 0xea, 0x77, 0x47, 0x47, 0x9d, 0xb9,
+	0x6f, 0x47, 0x9d, 0x9b, 0x15, 0xd1, 0x07, 0x59, 0x48, 0xa2, 0x21, 0x71, 0x5c, 0x12, 0x75, 0xad,
+	0x24, 0x8a, 0xe8, 0xdb, 0xae, 0x1d, 0x65, 0x21, 0xa3, 0x9a, 0x8c, 0xc5, 0xc5, 0x25, 0x68, 0x15,
+	0xd6, 0x7b, 0x3e, 0x4d, 0x02, 0x26, 0x64, 0x52, 0xb0, 0xb4, 0x50, 0x0b, 0xaa, 0xfb, 0xe4, 0x75,
+	0x42, 0x02, 0x9b, 0x08, 0x5d, 0x14, 0x5c, 0xda, 0x9b, 0xca, 0xa7, 0xc3, 0xce, 0xdc, 0x5a, 0x0a,
+	0x55, 0x23, 0x7d, 0x9e, 0xb0, 0xff, 0x58, 0x95, 0xcc, 0xfc, 0x03, 0x14, 0x43, 0x80, 0xae, 0xc2,
+	0x05, 0xa1, 0x8b, 0x9c, 0x86, 0xe5, 0x52, 0x4e, 0xa9, 0x17, 0xce, 0x61, 0xf4, 0xf4, 0xa4, 0xc0,
+	0x79, 0x51, 0xe0, 0xad, 0xbf, 0x2f, 0xae, 0x05, 0xd5, 0x6d, 0x33, 0x7e, 0xe6, 0xf9, 0x1e, 0x2b,
+	0xa4, 0x29, 0x6c, 0xb4, 0x0c, 0x6b, 0x4f, 0x08, 0x11, 0x93, 0xa1, 0x60, 0x7e, 0x44, 0xbb, 0x50,
+	0x79, 0x6c, 0x32, 0x53, 0xbc, 0xf7, 0xa2, 0x7e, 0x4f, 0xea, 0xb2, 0x71, 0x7a, 0x6a, 0xcb, 0x0b,
+	0xcc, 0x28, 0xd3, 0x76, 0x48, 0xaa, 0x67, 0x8c, 0xc4, 0x58, 0x5c, 0x21, 0xbb, 0xf7, 0x8a, 0xc1,
+	0x46, 0xeb, 0xb0, 0x2e, 0xba, 0xe3, 0xa2, 0xd7, 0x7e, 0xdb, 0xbd, 0xc4, 0xd1, 0x0d, 0xd8, 0xc8,
+	0x5f, 0x8a, 0xb7, 0xcf, 0xa9, 0x97, 0x2a, 0xd4, 0x1c, 0xc1, 0x05, 0x63, 0x53, 0xfd, 0x70, 0xd8,
+	0x99, 0x13, 0xa9, 0x92, 0xa9, 0x89, 0x9f, 0x59, 0xee, 0xfb, 0x50, 0xe5, 0x81, 0xbd, 0xc8, 0x8d,
+	0xe5, 0xfa, 0x5d, 0xd6, 0x2a, 0x5b, 0x5e, 0x60, 0xba, 0xc2, 0xe5, 0xc0, 0x25, 0x57, 0x76, 0x18,
+	0x16, 0x1b, 0x39, 0x73, 0x3e, 0x04, 0x15, 0x1e, 0x21, 0x72, 0x9d, 0xc3, 0xe2, 0xcc, 0x7d, 0x42,
+	0xf8, 0x5a, 0xee, 0xe3, 0xe7, 0x5f, 0x9f, 0x47, 0x66, 0x7c, 0x05, 0xeb, 0x3a, 0x3d, 0xa3, 0xa6,
+	0x1b, 0x50, 0x3d, 0x08, 0x2c, 0x1e, 0x45, 0xff, 0x2c, 0x6a, 0x49, 0xa9, 0xa8, 0xfa, 0x19, 0x94,
+	0x91, 0xb3, 0x77, 0xd8, 0x9f, 0x1e, 0xe0, 0x7f, 0xdf, 0xb0, 0x1d, 0xe2, 0xb9, 0x83, 0x62, 0x84,
+	0xa5, 0x55, 0x29, 0xf3, 0x3d, 0x98, 0xfc, 0x62, 0x9d, 0x41, 0x9a, 0x2d, 0x78, 0xa1, 0x67, 0xdb,
+	0x7c, 0x63, 0x0f, 0x42, 0xc7, 0x64, 0xa4, 0x98, 0xba, 0x15, 0x4d, 0x7c, 0xd8, 0x0d, 0xe2, 0x87,
+	0x43, 0x93, 0x11, 0xc9, 0x11, 0x53, 0x00, 0xf0, 0x54, 0xc8, 0x49, 0x25, 0xfa, 0xa3, 0xd1, 0xb8,
+	0x0d, 0xbe, 0x8e, 0xdb, 0xe0, 0xfb, 0xb8, 0x0d, 0xbe, 0x1c, 0xb7, 0xc1, 0xe8, 0xb8, 0x0d, 0x5e,
+	0x5c, 0x3f, 0xbd, 0x71, 0x96, 0xc6, 0x5d, 0x59, 0x9f, 0x55, 0x17, 0xbf, 0x92, 0x3b, 0x3f, 0x03,
+	0x00, 0x00, 0xff, 0xff, 0xac, 0xa5, 0xe3, 0x1c, 0xb1, 0x06, 0x00, 0x00,
+}
diff --git a/txs/payload/permission_tx.go b/txs/payload/permission_tx.go
index 9c219eecb4dff48e00e6d63634ae8d657232727f..d22984f93d4b03efac04f0ff469f3a7d0335daa6 100644
--- a/txs/payload/permission_tx.go
+++ b/txs/payload/permission_tx.go
@@ -3,31 +3,26 @@ package payload
 import (
 	"fmt"
 
-	"github.com/hyperledger/burrow/account/state"
+	"github.com/hyperledger/burrow/acm/state"
 	"github.com/hyperledger/burrow/crypto"
-	"github.com/hyperledger/burrow/permission/snatives"
+	"github.com/hyperledger/burrow/permission"
 )
 
-type PermissionsTx struct {
-	Input    *TxInput
-	PermArgs snatives.PermArgs
-}
-
-func NewPermissionsTx(st state.AccountGetter, from crypto.PublicKey, args snatives.PermArgs) (*PermissionsTx, error) {
+func NewPermissionsTx(st state.AccountGetter, from crypto.PublicKey, args permission.PermArgs) (*PermissionsTx, error) {
 	addr := from.Address()
 	acc, err := st.GetAccount(addr)
 	if err != nil {
 		return nil, err
 	}
 	if acc == nil {
-		return nil, fmt.Errorf("Invalid address %s from pubkey %s", addr, from)
+		return nil, fmt.Errorf("invalid address %s from pubkey %s", addr, from)
 	}
 
 	sequence := acc.Sequence() + 1
 	return NewPermissionsTxWithSequence(from, args, sequence), nil
 }
 
-func NewPermissionsTxWithSequence(from crypto.PublicKey, args snatives.PermArgs, sequence uint64) *PermissionsTx {
+func NewPermissionsTxWithSequence(from crypto.PublicKey, args permission.PermArgs, sequence uint64) *PermissionsTx {
 	input := &TxInput{
 		Address:  from.Address(),
 		Amount:   1, // NOTE: amounts can't be 0 ...
diff --git a/txs/payload/send_tx.go b/txs/payload/send_tx.go
index 12dd7a54749d96359baf80d708130a53fa576296..f83fcf953956effa402bf5f0cbcdfe8d9f379fc6 100644
--- a/txs/payload/send_tx.go
+++ b/txs/payload/send_tx.go
@@ -3,15 +3,10 @@ package payload
 import (
 	"fmt"
 
-	"github.com/hyperledger/burrow/account/state"
+	"github.com/hyperledger/burrow/acm/state"
 	"github.com/hyperledger/burrow/crypto"
 )
 
-type SendTx struct {
-	Inputs  []*TxInput
-	Outputs []*TxOutput
-}
-
 func NewSendTx() *SendTx {
 	return &SendTx{
 		Inputs:  []*TxInput{},
diff --git a/txs/payload/tx_input.go b/txs/payload/tx_input.go
index f435475f5af95cc54b69c37b1fcd6bd25b2d657c..0a69fa2c401b79f76df1c659b835a66c1b094cef 100644
--- a/txs/payload/tx_input.go
+++ b/txs/payload/tx_input.go
@@ -6,12 +6,6 @@ import (
 	"github.com/hyperledger/burrow/crypto"
 )
 
-type TxInput struct {
-	Address  crypto.Address
-	Amount   uint64
-	Sequence uint64
-}
-
 func (txIn *TxInput) ValidateBasic() error {
 	if txIn.Address == crypto.ZeroAddress {
 		return ErrTxInvalidAddress
@@ -23,5 +17,5 @@ func (txIn *TxInput) ValidateBasic() error {
 }
 
 func (txIn *TxInput) String() string {
-	return fmt.Sprintf("TxInput{%s, Amt: %v, Seq:%v}", txIn.Address, txIn.Amount, txIn.Sequence)
+	return fmt.Sprintf("TxInput{%s, Amount: %v, Sequence:%v}", txIn.Address, txIn.Amount, txIn.Sequence)
 }
diff --git a/txs/payload/tx_output.go b/txs/payload/tx_output.go
index 0dbd6c6856578e811d2766585ef728956f409978..dcd6d73ce1604d1392e200a0d99aff62de51a31a 100644
--- a/txs/payload/tx_output.go
+++ b/txs/payload/tx_output.go
@@ -2,15 +2,8 @@ package payload
 
 import (
 	"fmt"
-
-	"github.com/hyperledger/burrow/crypto"
 )
 
-type TxOutput struct {
-	Address crypto.Address
-	Amount  uint64
-}
-
 func (txOut *TxOutput) ValidateBasic() error {
 	if len(txOut.Address) != 20 {
 		return ErrTxInvalidAddress
@@ -22,5 +15,5 @@ func (txOut *TxOutput) ValidateBasic() error {
 }
 
 func (txOut *TxOutput) String() string {
-	return fmt.Sprintf("TxOutput{%s,%v}", txOut.Address, txOut.Amount)
+	return fmt.Sprintf("TxOutput{%s, Amount: %v}", txOut.Address, txOut.Amount)
 }
diff --git a/txs/payload/unbond_tx.go b/txs/payload/unbond_tx.go
index 9975d590ceb481761fdf7c4efdbcfaa3a4dfdf56..c6fe036fa7bd07e813d8c1fe3cc3ece83df8ee82 100644
--- a/txs/payload/unbond_tx.go
+++ b/txs/payload/unbond_tx.go
@@ -6,15 +6,9 @@ import (
 	"github.com/hyperledger/burrow/crypto"
 )
 
-type UnbondTx struct {
-	Input   *TxInput
-	Address crypto.Address
-	Height  int
-}
-
-func NewUnbondTx(addr crypto.Address, height int) *UnbondTx {
+func NewUnbondTx(address crypto.Address, height uint64) *UnbondTx {
 	return &UnbondTx{
-		Address: addr,
+		Address: address,
 		Height:  height,
 	}
 }
diff --git a/txs/tx.go b/txs/tx.go
index d099c892d1354f46c53d2c1ffd70bdcfd7d40b8d..ee773c3cce87d2feaea4d4f18f29f52dfa10042f 100644
--- a/txs/tx.go
+++ b/txs/tx.go
@@ -18,9 +18,10 @@ import (
 	"encoding/json"
 	"fmt"
 
-	acm "github.com/hyperledger/burrow/account"
+	"github.com/hyperledger/burrow/acm"
 	"github.com/hyperledger/burrow/binary"
 	"github.com/hyperledger/burrow/crypto"
+	"github.com/hyperledger/burrow/event/query"
 	"github.com/hyperledger/burrow/txs/payload"
 	"golang.org/x/crypto/ripemd160"
 )
@@ -53,6 +54,7 @@ func (tx *Tx) Sign(signingAccounts ...acm.AddressableSigner) (*Envelope, error)
 	if err != nil {
 		return nil, err
 	}
+	tx.Rehash()
 	return env, nil
 }
 
@@ -105,6 +107,34 @@ func (tx *Tx) UnmarshalJSON(data []byte) error {
 	return json.Unmarshal(w.Payload, tx.Payload)
 }
 
+// Protobuf support
+func (tx *Tx) Marshal() ([]byte, error) {
+	if tx == nil {
+		return nil, nil
+	}
+	return tx.MarshalJSON()
+}
+
+func (tx *Tx) Unmarshal(data []byte) error {
+	if len(data) == 0 {
+		return nil
+	}
+	return tx.UnmarshalJSON(data)
+}
+
+func (tx *Tx) MarshalTo(data []byte) (int, error) {
+	bs, err := tx.Marshal()
+	if err != nil {
+		return 0, err
+	}
+	return copy(data, bs), nil
+}
+
+func (tx *Tx) Size() int {
+	bs, _ := tx.Marshal()
+	return len(bs)
+}
+
 func (tx *Tx) Type() payload.Type {
 	if tx == nil {
 		return payload.TypeUnknown
@@ -114,7 +144,7 @@ func (tx *Tx) Type() payload.Type {
 
 // Generate a Hash for this transaction based on the SignBytes. The hash is memoized over the lifetime
 // of the Tx so repeated calls to Hash() are effectively free
-func (tx *Tx) Hash() []byte {
+func (tx *Tx) Hash() binary.HexBytes {
 	if tx == nil {
 		return nil
 	}
@@ -139,17 +169,15 @@ func (tx *Tx) Rehash() []byte {
 	return tx.txHash
 }
 
-// BroadcastTx or Transaction receipt
-type Receipt struct {
-	TxHash          binary.HexBytes
-	CreatesContract bool
-	ContractAddress crypto.Address
+func (tx *Tx) Tagged() query.Tagged {
+	return query.MergeTags(query.MustReflectTags(tx), query.MustReflectTags(tx.Payload))
 }
 
 // Generate a transaction Receipt containing the Tx hash and other information if the Tx is call.
 // Returned by ABCI methods.
 func (tx *Tx) GenerateReceipt() *Receipt {
 	receipt := &Receipt{
+		TxType: tx.Type(),
 		TxHash: tx.Hash(),
 	}
 	if callTx, ok := tx.Payload.(*payload.CallTx); ok {
@@ -162,3 +190,18 @@ func (tx *Tx) GenerateReceipt() *Receipt {
 	}
 	return receipt
 }
+
+var cdc = NewAminoCodec()
+
+func DecodeReceipt(bs []byte) (*Receipt, error) {
+	receipt := new(Receipt)
+	err := cdc.UnmarshalBinary(bs, receipt)
+	if err != nil {
+		return nil, err
+	}
+	return receipt, nil
+}
+
+func (receipt *Receipt) Encode() ([]byte, error) {
+	return cdc.MarshalBinary(receipt)
+}
diff --git a/txs/tx_test.go b/txs/tx_test.go
index bb916e86ab3a144dfaf9d170d1a195a8b7ac01ed..4716bc28d5a356878a3592bdea62578d5bb48750 100644
--- a/txs/tx_test.go
+++ b/txs/tx_test.go
@@ -19,10 +19,12 @@ import (
 	"runtime/debug"
 	"testing"
 
-	acm "github.com/hyperledger/burrow/account"
+	"fmt"
+
+	"github.com/hyperledger/burrow/acm"
 	"github.com/hyperledger/burrow/crypto"
-	"github.com/hyperledger/burrow/permission/snatives"
-	ptypes "github.com/hyperledger/burrow/permission/types"
+	"github.com/hyperledger/burrow/event/query"
+	"github.com/hyperledger/burrow/permission"
 	"github.com/hyperledger/burrow/txs/payload"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
@@ -32,13 +34,13 @@ var chainID = "myChainID"
 
 var privateAccounts = make(map[crypto.Address]acm.AddressableSigner)
 
-func makePrivateAccount(str string) acm.PrivateAccount {
+func makePrivateAccount(str string) *acm.PrivateAccount {
 	acc := acm.GeneratePrivateAccountFromSecret(str)
 	privateAccounts[acc.Address()] = acc
 	return acc
 }
 
-func TestSendTxSignable(t *testing.T) {
+func TestSendTx(t *testing.T) {
 	sendTx := &payload.SendTx{
 		Inputs: []*payload.TxInput{
 			{
@@ -65,6 +67,16 @@ func TestSendTxSignable(t *testing.T) {
 	}
 	testTxMarshalJSON(t, sendTx)
 	testTxSignVerify(t, sendTx)
+
+	tx := Enclose("Foo", sendTx).Tx
+	value, ok := tx.Tagged().Get("Inputs")
+	require.True(t, ok)
+	assert.Equal(t, fmt.Sprintf("%v%s%v", sendTx.Inputs[0], query.MultipleValueTagSeparator, sendTx.Inputs[1]),
+		value)
+
+	value, ok = tx.Tagged().Get("ChainID")
+	require.True(t, ok)
+	assert.Equal(t, "Foo", value)
 }
 
 func TestCallTxSignable(t *testing.T) {
@@ -147,7 +159,7 @@ func TestPermissionsTxSignable(t *testing.T) {
 			Amount:   12345,
 			Sequence: 250,
 		},
-		PermArgs: snatives.SetBaseArgs(makePrivateAccount("address1").Address(), 1, true),
+		PermArgs: permission.SetBaseArgs(makePrivateAccount("address1").Address(), 1, true),
 	}
 
 	testTxMarshalJSON(t, permsTx)
@@ -169,11 +181,16 @@ func TestTxWrapper_MarshalJSON(t *testing.T) {
 	}
 	testTxMarshalJSON(t, callTx)
 	testTxSignVerify(t, callTx)
+
+	tx := Enclose("Foo", callTx).Tx
+	value, ok := tx.Tagged().Get("Input")
+	require.True(t, ok)
+	assert.Equal(t, callTx.Input.String(), value)
 }
 
 func TestNewPermissionsTxWithSequence(t *testing.T) {
 	privateAccount := makePrivateAccount("shhhhh")
-	args := snatives.SetBaseArgs(privateAccount.PublicKey().Address(), ptypes.HasRole, true)
+	args := permission.SetBaseArgs(privateAccount.PublicKey().Address(), permission.HasRole, true)
 	permTx := payload.NewPermissionsTxWithSequence(privateAccount.PublicKey(), args, 1)
 	testTxMarshalJSON(t, permTx)
 	testTxSignVerify(t, permTx)
diff --git a/txs/txs.pb.go b/txs/txs.pb.go
new file mode 100644
index 0000000000000000000000000000000000000000..ba524fc453f2da7f8d85e46d651d19c8145df44a
--- /dev/null
+++ b/txs/txs.pb.go
@@ -0,0 +1,878 @@
+// Code generated by protoc-gen-gogo. DO NOT EDIT.
+// source: txs.proto
+
+/*
+	Package txs is a generated protocol buffer package.
+
+	It is generated from these files:
+		txs.proto
+
+	It has these top-level messages:
+		Envelope
+		Signatory
+		Receipt
+*/
+package txs
+
+import proto "github.com/gogo/protobuf/proto"
+import golang_proto "github.com/golang/protobuf/proto"
+import fmt "fmt"
+import math "math"
+import _ "github.com/gogo/protobuf/gogoproto"
+import crypto "github.com/hyperledger/burrow/crypto"
+
+import github_com_hyperledger_burrow_crypto "github.com/hyperledger/burrow/crypto"
+import github_com_hyperledger_burrow_txs_payload "github.com/hyperledger/burrow/txs/payload"
+import github_com_hyperledger_burrow_binary "github.com/hyperledger/burrow/binary"
+
+import io "io"
+
+// Reference imports to suppress errors if they are not otherwise used.
+var _ = proto.Marshal
+var _ = golang_proto.Marshal
+var _ = fmt.Errorf
+var _ = math.Inf
+
+// This is a compile-time assertion to ensure that this generated file
+// is compatible with the proto package it is being compiled against.
+// A compilation error at this line likely means your copy of the
+// proto package needs to be updated.
+const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package
+
+// An envelope contains both the signable Tx and the signatures for each input (in signatories)
+type Envelope struct {
+	Signatories []Signatory `protobuf:"bytes,1,rep,name=Signatories" json:"Signatories"`
+	// Canonical bytes of the Tx ready to be signed
+	Tx *Tx `protobuf:"bytes,2,opt,name=Tx,proto3,customtype=Tx" json:"Tx,omitempty"`
+}
+
+func (m *Envelope) Reset()                    { *m = Envelope{} }
+func (*Envelope) ProtoMessage()               {}
+func (*Envelope) Descriptor() ([]byte, []int) { return fileDescriptorTxs, []int{0} }
+
+func (m *Envelope) GetSignatories() []Signatory {
+	if m != nil {
+		return m.Signatories
+	}
+	return nil
+}
+
+func (*Envelope) XXX_MessageName() string {
+	return "txs.Envelope"
+}
+
+// Signatory contains signature and one or both of Address and PublicKey to identify the signer
+type Signatory struct {
+	Address   *github_com_hyperledger_burrow_crypto.Address  `protobuf:"bytes,1,opt,name=Address,proto3,customtype=github.com/hyperledger/burrow/crypto.Address" json:"Address,omitempty"`
+	PublicKey *crypto.PublicKey                              `protobuf:"bytes,2,opt,name=PublicKey" json:"PublicKey,omitempty"`
+	Signature github_com_hyperledger_burrow_crypto.Signature `protobuf:"bytes,3,opt,name=Signature,proto3,customtype=github.com/hyperledger/burrow/crypto.Signature" json:"Signature"`
+}
+
+func (m *Signatory) Reset()                    { *m = Signatory{} }
+func (m *Signatory) String() string            { return proto.CompactTextString(m) }
+func (*Signatory) ProtoMessage()               {}
+func (*Signatory) Descriptor() ([]byte, []int) { return fileDescriptorTxs, []int{1} }
+
+func (m *Signatory) GetPublicKey() *crypto.PublicKey {
+	if m != nil {
+		return m.PublicKey
+	}
+	return nil
+}
+
+func (*Signatory) XXX_MessageName() string {
+	return "txs.Signatory"
+}
+
+// BroadcastTx or Transaction receipt
+type Receipt struct {
+	// Transaction type
+	TxType github_com_hyperledger_burrow_txs_payload.Type `protobuf:"varint,1,opt,name=TxType,proto3,casttype=github.com/hyperledger/burrow/txs/payload.Type" json:"TxType,omitempty"`
+	// The hash of the transaction that caused this event to be generated
+	TxHash github_com_hyperledger_burrow_binary.HexBytes `protobuf:"bytes,2,opt,name=TxHash,proto3,customtype=github.com/hyperledger/burrow/binary.HexBytes" json:"TxHash"`
+	// Whether the transaction creates a contract
+	CreatesContract bool `protobuf:"varint,3,opt,name=CreatesContract,proto3" json:"CreatesContract,omitempty"`
+	// The address of the contract being called
+	ContractAddress github_com_hyperledger_burrow_crypto.Address `protobuf:"bytes,4,opt,name=ContractAddress,proto3,customtype=github.com/hyperledger/burrow/crypto.Address" json:"ContractAddress"`
+}
+
+func (m *Receipt) Reset()                    { *m = Receipt{} }
+func (m *Receipt) String() string            { return proto.CompactTextString(m) }
+func (*Receipt) ProtoMessage()               {}
+func (*Receipt) Descriptor() ([]byte, []int) { return fileDescriptorTxs, []int{2} }
+
+func (m *Receipt) GetTxType() github_com_hyperledger_burrow_txs_payload.Type {
+	if m != nil {
+		return m.TxType
+	}
+	return 0
+}
+
+func (m *Receipt) GetCreatesContract() bool {
+	if m != nil {
+		return m.CreatesContract
+	}
+	return false
+}
+
+func (*Receipt) XXX_MessageName() string {
+	return "txs.Receipt"
+}
+func init() {
+	proto.RegisterType((*Envelope)(nil), "txs.Envelope")
+	golang_proto.RegisterType((*Envelope)(nil), "txs.Envelope")
+	proto.RegisterType((*Signatory)(nil), "txs.Signatory")
+	golang_proto.RegisterType((*Signatory)(nil), "txs.Signatory")
+	proto.RegisterType((*Receipt)(nil), "txs.Receipt")
+	golang_proto.RegisterType((*Receipt)(nil), "txs.Receipt")
+}
+func (m *Envelope) Marshal() (dAtA []byte, err error) {
+	size := m.Size()
+	dAtA = make([]byte, size)
+	n, err := m.MarshalTo(dAtA)
+	if err != nil {
+		return nil, err
+	}
+	return dAtA[:n], nil
+}
+
+func (m *Envelope) MarshalTo(dAtA []byte) (int, error) {
+	var i int
+	_ = i
+	var l int
+	_ = l
+	if len(m.Signatories) > 0 {
+		for _, msg := range m.Signatories {
+			dAtA[i] = 0xa
+			i++
+			i = encodeVarintTxs(dAtA, i, uint64(msg.Size()))
+			n, err := msg.MarshalTo(dAtA[i:])
+			if err != nil {
+				return 0, err
+			}
+			i += n
+		}
+	}
+	if m.Tx != nil {
+		dAtA[i] = 0x12
+		i++
+		i = encodeVarintTxs(dAtA, i, uint64(m.Tx.Size()))
+		n1, err := m.Tx.MarshalTo(dAtA[i:])
+		if err != nil {
+			return 0, err
+		}
+		i += n1
+	}
+	return i, nil
+}
+
+func (m *Signatory) Marshal() (dAtA []byte, err error) {
+	size := m.Size()
+	dAtA = make([]byte, size)
+	n, err := m.MarshalTo(dAtA)
+	if err != nil {
+		return nil, err
+	}
+	return dAtA[:n], nil
+}
+
+func (m *Signatory) MarshalTo(dAtA []byte) (int, error) {
+	var i int
+	_ = i
+	var l int
+	_ = l
+	if m.Address != nil {
+		dAtA[i] = 0xa
+		i++
+		i = encodeVarintTxs(dAtA, i, uint64(m.Address.Size()))
+		n2, err := m.Address.MarshalTo(dAtA[i:])
+		if err != nil {
+			return 0, err
+		}
+		i += n2
+	}
+	if m.PublicKey != nil {
+		dAtA[i] = 0x12
+		i++
+		i = encodeVarintTxs(dAtA, i, uint64(m.PublicKey.Size()))
+		n3, err := m.PublicKey.MarshalTo(dAtA[i:])
+		if err != nil {
+			return 0, err
+		}
+		i += n3
+	}
+	dAtA[i] = 0x1a
+	i++
+	i = encodeVarintTxs(dAtA, i, uint64(m.Signature.Size()))
+	n4, err := m.Signature.MarshalTo(dAtA[i:])
+	if err != nil {
+		return 0, err
+	}
+	i += n4
+	return i, nil
+}
+
+func (m *Receipt) Marshal() (dAtA []byte, err error) {
+	size := m.Size()
+	dAtA = make([]byte, size)
+	n, err := m.MarshalTo(dAtA)
+	if err != nil {
+		return nil, err
+	}
+	return dAtA[:n], nil
+}
+
+func (m *Receipt) MarshalTo(dAtA []byte) (int, error) {
+	var i int
+	_ = i
+	var l int
+	_ = l
+	if m.TxType != 0 {
+		dAtA[i] = 0x8
+		i++
+		i = encodeVarintTxs(dAtA, i, uint64(m.TxType))
+	}
+	dAtA[i] = 0x12
+	i++
+	i = encodeVarintTxs(dAtA, i, uint64(m.TxHash.Size()))
+	n5, err := m.TxHash.MarshalTo(dAtA[i:])
+	if err != nil {
+		return 0, err
+	}
+	i += n5
+	if m.CreatesContract {
+		dAtA[i] = 0x18
+		i++
+		if m.CreatesContract {
+			dAtA[i] = 1
+		} else {
+			dAtA[i] = 0
+		}
+		i++
+	}
+	dAtA[i] = 0x22
+	i++
+	i = encodeVarintTxs(dAtA, i, uint64(m.ContractAddress.Size()))
+	n6, err := m.ContractAddress.MarshalTo(dAtA[i:])
+	if err != nil {
+		return 0, err
+	}
+	i += n6
+	return i, nil
+}
+
+func encodeVarintTxs(dAtA []byte, offset int, v uint64) int {
+	for v >= 1<<7 {
+		dAtA[offset] = uint8(v&0x7f | 0x80)
+		v >>= 7
+		offset++
+	}
+	dAtA[offset] = uint8(v)
+	return offset + 1
+}
+func (m *Envelope) Size() (n int) {
+	var l int
+	_ = l
+	if len(m.Signatories) > 0 {
+		for _, e := range m.Signatories {
+			l = e.Size()
+			n += 1 + l + sovTxs(uint64(l))
+		}
+	}
+	if m.Tx != nil {
+		l = m.Tx.Size()
+		n += 1 + l + sovTxs(uint64(l))
+	}
+	return n
+}
+
+func (m *Signatory) Size() (n int) {
+	var l int
+	_ = l
+	if m.Address != nil {
+		l = m.Address.Size()
+		n += 1 + l + sovTxs(uint64(l))
+	}
+	if m.PublicKey != nil {
+		l = m.PublicKey.Size()
+		n += 1 + l + sovTxs(uint64(l))
+	}
+	l = m.Signature.Size()
+	n += 1 + l + sovTxs(uint64(l))
+	return n
+}
+
+func (m *Receipt) Size() (n int) {
+	var l int
+	_ = l
+	if m.TxType != 0 {
+		n += 1 + sovTxs(uint64(m.TxType))
+	}
+	l = m.TxHash.Size()
+	n += 1 + l + sovTxs(uint64(l))
+	if m.CreatesContract {
+		n += 2
+	}
+	l = m.ContractAddress.Size()
+	n += 1 + l + sovTxs(uint64(l))
+	return n
+}
+
+func sovTxs(x uint64) (n int) {
+	for {
+		n++
+		x >>= 7
+		if x == 0 {
+			break
+		}
+	}
+	return n
+}
+func sozTxs(x uint64) (n int) {
+	return sovTxs(uint64((x << 1) ^ uint64((int64(x) >> 63))))
+}
+func (m *Envelope) Unmarshal(dAtA []byte) error {
+	l := len(dAtA)
+	iNdEx := 0
+	for iNdEx < l {
+		preIndex := iNdEx
+		var wire uint64
+		for shift := uint(0); ; shift += 7 {
+			if shift >= 64 {
+				return ErrIntOverflowTxs
+			}
+			if iNdEx >= l {
+				return io.ErrUnexpectedEOF
+			}
+			b := dAtA[iNdEx]
+			iNdEx++
+			wire |= (uint64(b) & 0x7F) << shift
+			if b < 0x80 {
+				break
+			}
+		}
+		fieldNum := int32(wire >> 3)
+		wireType := int(wire & 0x7)
+		if wireType == 4 {
+			return fmt.Errorf("proto: Envelope: wiretype end group for non-group")
+		}
+		if fieldNum <= 0 {
+			return fmt.Errorf("proto: Envelope: illegal tag %d (wire type %d)", fieldNum, wire)
+		}
+		switch fieldNum {
+		case 1:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Signatories", wireType)
+			}
+			var msglen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowTxs
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				msglen |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if msglen < 0 {
+				return ErrInvalidLengthTxs
+			}
+			postIndex := iNdEx + msglen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			m.Signatories = append(m.Signatories, Signatory{})
+			if err := m.Signatories[len(m.Signatories)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+				return err
+			}
+			iNdEx = postIndex
+		case 2:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Tx", wireType)
+			}
+			var byteLen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowTxs
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				byteLen |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if byteLen < 0 {
+				return ErrInvalidLengthTxs
+			}
+			postIndex := iNdEx + byteLen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			var v Tx
+			m.Tx = &v
+			if err := m.Tx.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+				return err
+			}
+			iNdEx = postIndex
+		default:
+			iNdEx = preIndex
+			skippy, err := skipTxs(dAtA[iNdEx:])
+			if err != nil {
+				return err
+			}
+			if skippy < 0 {
+				return ErrInvalidLengthTxs
+			}
+			if (iNdEx + skippy) > l {
+				return io.ErrUnexpectedEOF
+			}
+			iNdEx += skippy
+		}
+	}
+
+	if iNdEx > l {
+		return io.ErrUnexpectedEOF
+	}
+	return nil
+}
+func (m *Signatory) Unmarshal(dAtA []byte) error {
+	l := len(dAtA)
+	iNdEx := 0
+	for iNdEx < l {
+		preIndex := iNdEx
+		var wire uint64
+		for shift := uint(0); ; shift += 7 {
+			if shift >= 64 {
+				return ErrIntOverflowTxs
+			}
+			if iNdEx >= l {
+				return io.ErrUnexpectedEOF
+			}
+			b := dAtA[iNdEx]
+			iNdEx++
+			wire |= (uint64(b) & 0x7F) << shift
+			if b < 0x80 {
+				break
+			}
+		}
+		fieldNum := int32(wire >> 3)
+		wireType := int(wire & 0x7)
+		if wireType == 4 {
+			return fmt.Errorf("proto: Signatory: wiretype end group for non-group")
+		}
+		if fieldNum <= 0 {
+			return fmt.Errorf("proto: Signatory: illegal tag %d (wire type %d)", fieldNum, wire)
+		}
+		switch fieldNum {
+		case 1:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Address", wireType)
+			}
+			var byteLen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowTxs
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				byteLen |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if byteLen < 0 {
+				return ErrInvalidLengthTxs
+			}
+			postIndex := iNdEx + byteLen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			var v github_com_hyperledger_burrow_crypto.Address
+			m.Address = &v
+			if err := m.Address.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+				return err
+			}
+			iNdEx = postIndex
+		case 2:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field PublicKey", wireType)
+			}
+			var msglen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowTxs
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				msglen |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if msglen < 0 {
+				return ErrInvalidLengthTxs
+			}
+			postIndex := iNdEx + msglen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			if m.PublicKey == nil {
+				m.PublicKey = &crypto.PublicKey{}
+			}
+			if err := m.PublicKey.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+				return err
+			}
+			iNdEx = postIndex
+		case 3:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Signature", wireType)
+			}
+			var byteLen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowTxs
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				byteLen |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if byteLen < 0 {
+				return ErrInvalidLengthTxs
+			}
+			postIndex := iNdEx + byteLen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			if err := m.Signature.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+				return err
+			}
+			iNdEx = postIndex
+		default:
+			iNdEx = preIndex
+			skippy, err := skipTxs(dAtA[iNdEx:])
+			if err != nil {
+				return err
+			}
+			if skippy < 0 {
+				return ErrInvalidLengthTxs
+			}
+			if (iNdEx + skippy) > l {
+				return io.ErrUnexpectedEOF
+			}
+			iNdEx += skippy
+		}
+	}
+
+	if iNdEx > l {
+		return io.ErrUnexpectedEOF
+	}
+	return nil
+}
+func (m *Receipt) Unmarshal(dAtA []byte) error {
+	l := len(dAtA)
+	iNdEx := 0
+	for iNdEx < l {
+		preIndex := iNdEx
+		var wire uint64
+		for shift := uint(0); ; shift += 7 {
+			if shift >= 64 {
+				return ErrIntOverflowTxs
+			}
+			if iNdEx >= l {
+				return io.ErrUnexpectedEOF
+			}
+			b := dAtA[iNdEx]
+			iNdEx++
+			wire |= (uint64(b) & 0x7F) << shift
+			if b < 0x80 {
+				break
+			}
+		}
+		fieldNum := int32(wire >> 3)
+		wireType := int(wire & 0x7)
+		if wireType == 4 {
+			return fmt.Errorf("proto: Receipt: wiretype end group for non-group")
+		}
+		if fieldNum <= 0 {
+			return fmt.Errorf("proto: Receipt: illegal tag %d (wire type %d)", fieldNum, wire)
+		}
+		switch fieldNum {
+		case 1:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field TxType", wireType)
+			}
+			m.TxType = 0
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowTxs
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				m.TxType |= (github_com_hyperledger_burrow_txs_payload.Type(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+		case 2:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field TxHash", wireType)
+			}
+			var byteLen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowTxs
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				byteLen |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if byteLen < 0 {
+				return ErrInvalidLengthTxs
+			}
+			postIndex := iNdEx + byteLen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			if err := m.TxHash.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+				return err
+			}
+			iNdEx = postIndex
+		case 3:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field CreatesContract", wireType)
+			}
+			var v int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowTxs
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				v |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			m.CreatesContract = bool(v != 0)
+		case 4:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field ContractAddress", wireType)
+			}
+			var byteLen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowTxs
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				byteLen |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if byteLen < 0 {
+				return ErrInvalidLengthTxs
+			}
+			postIndex := iNdEx + byteLen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			if err := m.ContractAddress.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+				return err
+			}
+			iNdEx = postIndex
+		default:
+			iNdEx = preIndex
+			skippy, err := skipTxs(dAtA[iNdEx:])
+			if err != nil {
+				return err
+			}
+			if skippy < 0 {
+				return ErrInvalidLengthTxs
+			}
+			if (iNdEx + skippy) > l {
+				return io.ErrUnexpectedEOF
+			}
+			iNdEx += skippy
+		}
+	}
+
+	if iNdEx > l {
+		return io.ErrUnexpectedEOF
+	}
+	return nil
+}
+func skipTxs(dAtA []byte) (n int, err error) {
+	l := len(dAtA)
+	iNdEx := 0
+	for iNdEx < l {
+		var wire uint64
+		for shift := uint(0); ; shift += 7 {
+			if shift >= 64 {
+				return 0, ErrIntOverflowTxs
+			}
+			if iNdEx >= l {
+				return 0, io.ErrUnexpectedEOF
+			}
+			b := dAtA[iNdEx]
+			iNdEx++
+			wire |= (uint64(b) & 0x7F) << shift
+			if b < 0x80 {
+				break
+			}
+		}
+		wireType := int(wire & 0x7)
+		switch wireType {
+		case 0:
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return 0, ErrIntOverflowTxs
+				}
+				if iNdEx >= l {
+					return 0, io.ErrUnexpectedEOF
+				}
+				iNdEx++
+				if dAtA[iNdEx-1] < 0x80 {
+					break
+				}
+			}
+			return iNdEx, nil
+		case 1:
+			iNdEx += 8
+			return iNdEx, nil
+		case 2:
+			var length int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return 0, ErrIntOverflowTxs
+				}
+				if iNdEx >= l {
+					return 0, io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				length |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			iNdEx += length
+			if length < 0 {
+				return 0, ErrInvalidLengthTxs
+			}
+			return iNdEx, nil
+		case 3:
+			for {
+				var innerWire uint64
+				var start int = iNdEx
+				for shift := uint(0); ; shift += 7 {
+					if shift >= 64 {
+						return 0, ErrIntOverflowTxs
+					}
+					if iNdEx >= l {
+						return 0, io.ErrUnexpectedEOF
+					}
+					b := dAtA[iNdEx]
+					iNdEx++
+					innerWire |= (uint64(b) & 0x7F) << shift
+					if b < 0x80 {
+						break
+					}
+				}
+				innerWireType := int(innerWire & 0x7)
+				if innerWireType == 4 {
+					break
+				}
+				next, err := skipTxs(dAtA[start:])
+				if err != nil {
+					return 0, err
+				}
+				iNdEx = start + next
+			}
+			return iNdEx, nil
+		case 4:
+			return iNdEx, nil
+		case 5:
+			iNdEx += 4
+			return iNdEx, nil
+		default:
+			return 0, fmt.Errorf("proto: illegal wireType %d", wireType)
+		}
+	}
+	panic("unreachable")
+}
+
+var (
+	ErrInvalidLengthTxs = fmt.Errorf("proto: negative length found during unmarshaling")
+	ErrIntOverflowTxs   = fmt.Errorf("proto: integer overflow")
+)
+
+func init() { proto.RegisterFile("txs.proto", fileDescriptorTxs) }
+func init() { golang_proto.RegisterFile("txs.proto", fileDescriptorTxs) }
+
+var fileDescriptorTxs = []byte{
+	// 422 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x92, 0xcf, 0x6e, 0xd4, 0x30,
+	0x10, 0xc6, 0xeb, 0xec, 0x6a, 0xdb, 0xf5, 0x16, 0x2a, 0x7c, 0x40, 0xab, 0x1e, 0x92, 0xb2, 0xa7,
+	0x3d, 0xd0, 0x04, 0x2d, 0x50, 0x24, 0x6e, 0xa4, 0x42, 0xaa, 0x8a, 0x90, 0x90, 0xc9, 0x89, 0x03,
+	0x22, 0x7f, 0x86, 0x6c, 0xa4, 0x10, 0x47, 0xb6, 0x03, 0xf6, 0x9b, 0x70, 0xe4, 0x09, 0x78, 0x06,
+	0x8e, 0x7b, 0xe4, 0xbc, 0x87, 0x08, 0x6d, 0xdf, 0x82, 0x13, 0x8a, 0x71, 0xb6, 0x55, 0x0f, 0x94,
+	0xde, 0x3c, 0xf6, 0x7c, 0xbf, 0xf9, 0x66, 0xc6, 0x78, 0x2c, 0x95, 0xf0, 0x6b, 0xce, 0x24, 0x23,
+	0x03, 0xa9, 0xc4, 0xe1, 0x71, 0x5e, 0xc8, 0x65, 0x93, 0xf8, 0x29, 0xfb, 0x14, 0xe4, 0x2c, 0x67,
+	0x81, 0x79, 0x4b, 0x9a, 0x8f, 0x26, 0x32, 0x81, 0x39, 0xfd, 0xd5, 0x1c, 0xee, 0xa7, 0x5c, 0xd7,
+	0xd2, 0x46, 0xb3, 0x0f, 0x78, 0xef, 0x65, 0xf5, 0x19, 0x4a, 0x56, 0x03, 0x39, 0xc1, 0x93, 0xb7,
+	0x45, 0x5e, 0xc5, 0x92, 0xf1, 0x02, 0xc4, 0x14, 0x1d, 0x0d, 0xe6, 0x93, 0xc5, 0x5d, 0xbf, 0x2b,
+	0xd7, 0xdf, 0xeb, 0x70, 0xb8, 0x6a, 0xbd, 0x1d, 0x7a, 0x35, 0x91, 0xdc, 0xc7, 0x4e, 0xa4, 0xa6,
+	0xce, 0x11, 0x9a, 0xef, 0x87, 0xa3, 0x75, 0xeb, 0x39, 0x91, 0xa2, 0x4e, 0xa4, 0x9e, 0x0f, 0xbf,
+	0x7e, 0xf3, 0x76, 0x66, 0x2d, 0xc2, 0xe3, 0xad, 0x9c, 0x9c, 0xe3, 0xdd, 0x17, 0x59, 0xc6, 0x41,
+	0x74, 0xfc, 0x4e, 0xf0, 0x68, 0xdd, 0x7a, 0x0f, 0xaf, 0x74, 0xb0, 0xd4, 0x35, 0xf0, 0x12, 0xb2,
+	0x1c, 0x78, 0x90, 0x34, 0x9c, 0xb3, 0x2f, 0x81, 0x35, 0x6c, 0x75, 0xb4, 0x07, 0x90, 0x00, 0x8f,
+	0xdf, 0x34, 0x49, 0x59, 0xa4, 0xaf, 0x40, 0x9b, 0xf2, 0x93, 0xc5, 0x3d, 0xdf, 0x26, 0x6f, 0x1f,
+	0xe8, 0x65, 0x0e, 0x89, 0x7a, 0x27, 0x0d, 0x87, 0xe9, 0xc0, 0x94, 0x3f, 0xe9, 0xda, 0x59, 0xb7,
+	0x9e, 0xff, 0x5f, 0x16, 0xb6, 0x6a, 0x7a, 0x09, 0x9a, 0x7d, 0x77, 0xf0, 0x2e, 0x85, 0x14, 0x8a,
+	0x5a, 0x92, 0x73, 0x3c, 0x8a, 0x54, 0xa4, 0x6b, 0x30, 0xdd, 0xdd, 0x09, 0x17, 0xbf, 0x6f, 0x44,
+	0x4b, 0x25, 0x82, 0x3a, 0xd6, 0x25, 0x8b, 0x33, 0xbf, 0x53, 0x52, 0x4b, 0x20, 0xaf, 0x3b, 0xd6,
+	0x59, 0x2c, 0x96, 0x76, 0xb4, 0x4f, 0xad, 0xd5, 0xe3, 0x7f, 0xf3, 0x92, 0xa2, 0x8a, 0xb9, 0xf6,
+	0xcf, 0x40, 0x85, 0x5a, 0x82, 0xa0, 0x16, 0x42, 0xe6, 0xf8, 0xe0, 0x94, 0x43, 0x2c, 0x41, 0x9c,
+	0xb2, 0x4a, 0xf2, 0x38, 0x95, 0x66, 0x04, 0x7b, 0xf4, 0xfa, 0x35, 0x79, 0x8f, 0x0f, 0xfa, 0x73,
+	0xbf, 0xab, 0xa1, 0x71, 0xf0, 0xc4, 0x3a, 0xb8, 0xdd, 0xbe, 0xae, 0xc3, 0xc2, 0x67, 0xab, 0x8d,
+	0x8b, 0x7e, 0x6e, 0x5c, 0xf4, 0x6b, 0xe3, 0xa2, 0x1f, 0x17, 0x2e, 0x5a, 0x5d, 0xb8, 0xe8, 0xdd,
+	0x83, 0x1b, 0xc7, 0x94, 0x8c, 0xcc, 0x9f, 0x7d, 0xfc, 0x27, 0x00, 0x00, 0xff, 0xff, 0xcd, 0x2f,
+	0x9b, 0x0b, 0x02, 0x03, 0x00, 0x00,
+}