diff --git a/Gopkg.lock b/Gopkg.lock
index 39bc61be055d7c67415bddc349cbad63666cebbc..f640389d9d3e7f6796090d4aa90d53bb4722ec31 100644
--- a/Gopkg.lock
+++ b/Gopkg.lock
@@ -487,12 +487,12 @@
   version = "0.10.1"
 
 [[projects]]
-  digest = "1:76c7684f6ff9b92dd8f934ad853838e207ab4b7d68927f95f5ba785d8bea56d2"
+  digest = "1:95454de4bf99bf62e6e3b59724a712e954e1c8d9956e0bc098699179ad1168c6"
   name = "github.com/tendermint/iavl"
   packages = ["."]
   pruneopts = "NUT"
-  revision = "e5726c0066ccdd299a2ec9262f93c7896cdfcd87"
-  version = "v0.10.0"
+  revision = "3acc91fb8811db2c5409a855ae1f8e441fe98e2d"
+  version = "v0.11.0"
 
 [[projects]]
   digest = "1:77fa9bc72848b93790fdad4f728f4ae36a905a51d6056dc72752889157fc37c0"
diff --git a/Gopkg.toml b/Gopkg.toml
index 6b27396f3916bd79b9cef92f69777ba7e76fd5e1..a31c4f7eeb5d5709c5447c029f611e0dd11e19fb 100644
--- a/Gopkg.toml
+++ b/Gopkg.toml
@@ -20,7 +20,7 @@
 
 [[constraint]]
   name = "github.com/tendermint/iavl"
-  version = "=0.10.0"
+  version = "=0.11.0"
 
 # Haven't made a release since 2016.
 [[constraint]]
diff --git a/txs/tx.go b/txs/tx.go
index ea5c374288a6f9d13c7ae41f918a31820e85bf1e..cc2005218704a18270633c31335e06fcc61eb27c 100644
--- a/txs/tx.go
+++ b/txs/tx.go
@@ -18,7 +18,7 @@ import (
 	"encoding/json"
 	"fmt"
 
-	"github.com/tendermint/tmlibs/merkle/tmhash"
+	"github.com/tendermint/tendermint/crypto/tmhash"
 
 	"github.com/hyperledger/burrow/acm"
 	"github.com/hyperledger/burrow/acm/state"
diff --git a/vendor/github.com/tendermint/iavl/immutable_tree.go b/vendor/github.com/tendermint/iavl/immutable_tree.go
index e334ef52b36b1946e65a08164a34c6e5fa2e0130..5abc91823adbf2636c7c679afd9f9652a1b049c8 100644
--- a/vendor/github.com/tendermint/iavl/immutable_tree.go
+++ b/vendor/github.com/tendermint/iavl/immutable_tree.go
@@ -39,11 +39,7 @@ func (t *ImmutableTree) String() string {
 }
 
 // Size returns the number of leaf nodes in the tree.
-func (t *ImmutableTree) Size() int {
-	return int(t.Size64())
-}
-
-func (t *ImmutableTree) Size64() int64 {
+func (t *ImmutableTree) Size() int64 {
 	if t.root == nil {
 		return 0
 	}
@@ -51,20 +47,12 @@ func (t *ImmutableTree) Size64() int64 {
 }
 
 // Version returns the version of the tree.
-func (t *ImmutableTree) Version() int {
-	return int(t.Version64())
-}
-
-func (t *ImmutableTree) Version64() int64 {
+func (t *ImmutableTree) Version() int64 {
 	return t.version
 }
 
 // Height returns the height of the tree.
-func (t *ImmutableTree) Height() int {
-	return int(t.Height8())
-}
-
-func (t *ImmutableTree) Height8() int8 {
+func (t *ImmutableTree) Height() int8 {
 	if t.root == nil {
 		return 0
 	}
@@ -98,12 +86,7 @@ func (t *ImmutableTree) hashWithCount() ([]byte, int64) {
 
 // Get returns the index and value of the specified key if it exists, or nil
 // and the next index, if it doesn't.
-func (t *ImmutableTree) Get(key []byte) (index int, value []byte) {
-	index64, value := t.Get64(key)
-	return int(index64), value
-}
-
-func (t *ImmutableTree) Get64(key []byte) (index int64, value []byte) {
+func (t *ImmutableTree) Get(key []byte) (index int64, value []byte) {
 	if t.root == nil {
 		return 0, nil
 	}
@@ -111,11 +94,7 @@ func (t *ImmutableTree) Get64(key []byte) (index int64, value []byte) {
 }
 
 // GetByIndex gets the key and value at the specified index.
-func (t *ImmutableTree) GetByIndex(index int) (key []byte, value []byte) {
-	return t.GetByIndex64(int64(index))
-}
-
-func (t *ImmutableTree) GetByIndex64(index int64) (key []byte, value []byte) {
+func (t *ImmutableTree) GetByIndex(index int64) (key []byte, value []byte) {
 	if t.root == nil {
 		return nil, nil
 	}
diff --git a/vendor/github.com/tendermint/iavl/key_format.go b/vendor/github.com/tendermint/iavl/key_format.go
new file mode 100644
index 0000000000000000000000000000000000000000..b63f9ea7b3896305e68246f7a2fa4d544346a2ba
--- /dev/null
+++ b/vendor/github.com/tendermint/iavl/key_format.go
@@ -0,0 +1,144 @@
+package iavl
+
+import (
+	"encoding/binary"
+	"fmt"
+)
+
+// Provides a fixed-width lexicographically sortable []byte key format
+type KeyFormat struct {
+	prefix byte
+	layout []int
+	length int
+}
+
+// Create a []byte key format based on a single byte prefix and fixed width key segments each of whose length is
+// specified by by the corresponding element of layout.
+//
+// For example, to store keys that could index some objects by a version number and their SHA256 hash using the form:
+// 'c<version uint64><hash [32]byte>' then you would define the KeyFormat with:
+//
+//  var keyFormat = NewKeyFormat('c', 8, 32)
+//
+// Then you can create a key with:
+//
+//  func ObjectKey(version uint64, objectBytes []byte) []byte {
+//  	hasher := sha256.New()
+//  	hasher.Sum(nil)
+//  	return keyFormat.Key(version, hasher.Sum(nil))
+//  }
+func NewKeyFormat(prefix byte, layout ...int) *KeyFormat {
+	// For prefix byte
+	length := 1
+	for _, l := range layout {
+		length += int(l)
+	}
+	return &KeyFormat{
+		prefix: prefix,
+		layout: layout,
+		length: length,
+	}
+}
+
+// Format the byte segments into the key format - will panic if the segment lengths do not match the layout.
+func (kf *KeyFormat) KeyBytes(segments ...[]byte) []byte {
+	key := make([]byte, kf.length)
+	key[0] = kf.prefix
+	n := 1
+	for i, s := range segments {
+		l := kf.layout[i]
+		if len(s) > l {
+			panic(fmt.Errorf("length of segment %X provided to KeyFormat.KeyBytes() is longer than the %d bytes "+
+				"required by layout for segment %d", s, l, i))
+		}
+		n += l
+		// Big endian so pad on left if not given the full width for this segment
+		copy(key[n-len(s):n], s)
+	}
+	return key[:n]
+}
+
+// Format the args passed into the key format - will panic if the arguments passed do not match the length
+// of the segment to which they correspond. When called with no arguments returns the raw prefix (useful as a start
+// element of the entire keys space when sorted lexicographically).
+func (kf *KeyFormat) Key(args ...interface{}) []byte {
+	if len(args) > len(kf.layout) {
+		panic(fmt.Errorf("KeyFormat.Key() is provided with %d args but format only has %d segments",
+			len(args), len(kf.layout)))
+	}
+	segments := make([][]byte, len(args))
+	for i, a := range args {
+		segments[i] = format(a)
+	}
+	return kf.KeyBytes(segments...)
+}
+
+// Reads out the bytes associated with each segment of the key format from key.
+func (kf *KeyFormat) ScanBytes(key []byte) [][]byte {
+	segments := make([][]byte, len(kf.layout))
+	n := 1
+	for i, l := range kf.layout {
+		n += l
+		if n > len(key) {
+			return segments[:i]
+		}
+		segments[i] = key[n-l : n]
+	}
+	return segments
+}
+
+// Extracts the segments into the values pointed to by each of args. Each arg must be a pointer to int64, uint64, or
+// []byte, and the width of the args must match layout.
+func (kf *KeyFormat) Scan(key []byte, args ...interface{}) {
+	segments := kf.ScanBytes(key)
+	if len(args) > len(segments) {
+		panic(fmt.Errorf("KeyFormat.Scan() is provided with %d args but format only has %d segments in key %X",
+			len(args), len(segments), key))
+	}
+	for i, a := range args {
+		scan(a, segments[i])
+	}
+}
+
+// Return the prefix as a string.
+func (kf *KeyFormat) Prefix() string {
+	return string([]byte{kf.prefix})
+}
+
+func scan(a interface{}, value []byte) {
+	switch v := a.(type) {
+	case *int64:
+		// Negative values will be mapped correctly when read in as uint64 and then type converted
+		*v = int64(binary.BigEndian.Uint64(value))
+	case *uint64:
+		*v = binary.BigEndian.Uint64(value)
+	case *[]byte:
+		*v = value
+	default:
+		panic(fmt.Errorf("KeyFormat scan() does not support scanning value of type %T: %v", a, a))
+	}
+}
+
+func format(a interface{}) []byte {
+	switch v := a.(type) {
+	case uint64:
+		return formatUint64(v)
+	case int64:
+		return formatUint64(uint64(v))
+	// Provide formatting from int,uint as a convenience to avoid casting arguments
+	case uint:
+		return formatUint64(uint64(v))
+	case int:
+		return formatUint64(uint64(v))
+	case []byte:
+		return v
+	default:
+		panic(fmt.Errorf("KeyFormat format() does not support formatting value of type %T: %v", a, a))
+	}
+}
+
+func formatUint64(v uint64) []byte {
+	bs := make([]byte, 8)
+	binary.BigEndian.PutUint64(bs, v)
+	return bs
+}
diff --git a/vendor/github.com/tendermint/iavl/mutable_tree.go b/vendor/github.com/tendermint/iavl/mutable_tree.go
index 8ad073345ce40c6957d6f5ec0c81efccb5b7cd8d..05b89cc32dbe76c303528d26884936e83b65a446 100644
--- a/vendor/github.com/tendermint/iavl/mutable_tree.go
+++ b/vendor/github.com/tendermint/iavl/mutable_tree.go
@@ -294,7 +294,7 @@ func (tree *MutableTree) Rollback() {
 
 // GetVersioned gets the value at the specified key and version.
 func (tree *MutableTree) GetVersioned(key []byte, version int64) (
-	index int, value []byte,
+	index int64, value []byte,
 ) {
 	if tree.versions[version] {
 		t, err := tree.GetImmutable(version)
diff --git a/vendor/github.com/tendermint/iavl/nodedb.go b/vendor/github.com/tendermint/iavl/nodedb.go
index a933b26628dcbd8fbfee84f86c64e2f0048e7bf3..1844ded057c0eccd319191a064b1473242d2cbfc 100644
--- a/vendor/github.com/tendermint/iavl/nodedb.go
+++ b/vendor/github.com/tendermint/iavl/nodedb.go
@@ -7,27 +7,29 @@ import (
 	"sort"
 	"sync"
 
+	"github.com/tendermint/tendermint/crypto/tmhash"
 	dbm "github.com/tendermint/tendermint/libs/db"
 )
 
+const (
+	int64Size = 8
+	hashSize  = tmhash.Size
+)
+
 var (
-	// All node keys are prefixed with this. This ensures no collision is
-	// possible with the other keys, and makes them easier to traverse.
-	nodePrefix = "n/"
-	nodeKeyFmt = "n/%X"
+	// All node keys are prefixed with the byte 'n'. This ensures no collision is
+	// possible with the other keys, and makes them easier to traverse. They are indexed by the node hash.
+	nodeKeyFormat = NewKeyFormat('n', hashSize) // n<hash>
 
 	// Orphans are keyed in the database by their expected lifetime.
 	// The first number represents the *last* version at which the orphan needs
 	// to exist, while the second number represents the *earliest* version at
 	// which it is expected to exist - which starts out by being the version
 	// of the node being orphaned.
-	orphanPrefix    = "o/"
-	orphanPrefixFmt = "o/%010d/"         // o/<last-version>/
-	orphanKeyFmt    = "o/%010d/%010d/%X" // o/<last-version>/<first-version>/<hash>
+	orphanKeyFormat = NewKeyFormat('o', int64Size, int64Size, hashSize) // o<last-version><first-version><hash>
 
-	// r/<version>
-	rootPrefix    = "r/"
-	rootPrefixFmt = "r/%010d"
+	// Root nodes are indexed separately by their version
+	rootKeyFormat = NewKeyFormat('r', int64Size) // r<version>
 )
 
 type nodeDB struct {
@@ -196,7 +198,7 @@ func (ndb *nodeDB) deleteOrphans(version int64) {
 
 		// See comment on `orphanKeyFmt`. Note that here, `version` and
 		// `toVersion` are always equal.
-		fmt.Sscanf(string(key), orphanKeyFmt, &toVersion, &fromVersion)
+		orphanKeyFormat.Scan(key, &toVersion, &fromVersion)
 
 		// Delete orphan key and reverse-lookup key.
 		ndb.batch.Delete(key)
@@ -218,15 +220,15 @@ func (ndb *nodeDB) deleteOrphans(version int64) {
 }
 
 func (ndb *nodeDB) nodeKey(hash []byte) []byte {
-	return []byte(fmt.Sprintf(nodeKeyFmt, hash))
+	return nodeKeyFormat.KeyBytes(hash)
 }
 
 func (ndb *nodeDB) orphanKey(fromVersion, toVersion int64, hash []byte) []byte {
-	return []byte(fmt.Sprintf(orphanKeyFmt, toVersion, fromVersion, hash))
+	return orphanKeyFormat.Key(toVersion, fromVersion, hash)
 }
 
 func (ndb *nodeDB) rootKey(version int64) []byte {
-	return []byte(fmt.Sprintf(rootPrefixFmt, version))
+	return rootKeyFormat.Key(version)
 }
 
 func (ndb *nodeDB) getLatestVersion() int64 {
@@ -244,20 +246,16 @@ func (ndb *nodeDB) updateLatestVersion(version int64) {
 
 func (ndb *nodeDB) getPreviousVersion(version int64) int64 {
 	itr := ndb.db.ReverseIterator(
-		[]byte(fmt.Sprintf(rootPrefixFmt, version-1)),
-		[]byte(fmt.Sprintf(rootPrefixFmt, 0)),
+		rootKeyFormat.Key(version-1),
+		rootKeyFormat.Key(0),
 	)
 	defer itr.Close()
 
 	pversion := int64(-1)
 	for ; itr.Valid(); itr.Next() {
 		k := itr.Key()
-		_, err := fmt.Sscanf(string(k), rootPrefixFmt, &pversion)
-		if err != nil {
-			panic(err)
-		} else {
-			return pversion
-		}
+		rootKeyFormat.Scan(k, &pversion)
+		return pversion
 	}
 
 	return 0
@@ -274,13 +272,12 @@ func (ndb *nodeDB) deleteRoot(version int64) {
 }
 
 func (ndb *nodeDB) traverseOrphans(fn func(k, v []byte)) {
-	ndb.traversePrefix([]byte(orphanPrefix), fn)
+	ndb.traversePrefix(orphanKeyFormat.Key(), fn)
 }
 
 // Traverse orphans ending at a certain version.
 func (ndb *nodeDB) traverseOrphansVersion(version int64, fn func(k, v []byte)) {
-	prefix := fmt.Sprintf(orphanPrefixFmt, version)
-	ndb.traversePrefix([]byte(prefix), fn)
+	ndb.traversePrefix(orphanKeyFormat.Key(version), fn)
 }
 
 // Traverse all keys.
@@ -339,9 +336,9 @@ func (ndb *nodeDB) getRoot(version int64) []byte {
 func (ndb *nodeDB) getRoots() (map[int64][]byte, error) {
 	roots := map[int64][]byte{}
 
-	ndb.traversePrefix([]byte(rootPrefix), func(k, v []byte) {
+	ndb.traversePrefix(rootKeyFormat.Key(), func(k, v []byte) {
 		var version int64
-		fmt.Sscanf(string(k), rootPrefixFmt, &version)
+		rootKeyFormat.Scan(k, &version)
 		roots[version] = v
 	})
 	return roots, nil
@@ -426,12 +423,12 @@ func (ndb *nodeDB) size() int {
 func (ndb *nodeDB) traverseNodes(fn func(hash []byte, node *Node)) {
 	nodes := []*Node{}
 
-	ndb.traversePrefix([]byte(nodePrefix), func(key, value []byte) {
+	ndb.traversePrefix(nodeKeyFormat.Key(), func(key, value []byte) {
 		node, err := MakeNode(value)
 		if err != nil {
 			panic(fmt.Sprintf("Couldn't decode node from database: %v", err))
 		}
-		fmt.Sscanf(string(key), nodeKeyFmt, &node.hash)
+		nodeKeyFormat.Scan(key, &node.hash)
 		nodes = append(nodes, node)
 	})
 
@@ -448,7 +445,7 @@ func (ndb *nodeDB) String() string {
 	var str string
 	index := 0
 
-	ndb.traversePrefix([]byte(rootPrefix), func(key, value []byte) {
+	ndb.traversePrefix(rootKeyFormat.Key(), func(key, value []byte) {
 		str += fmt.Sprintf("%s: %x\n", string(key), value)
 	})
 	str += "\n"
@@ -462,11 +459,13 @@ func (ndb *nodeDB) String() string {
 		if len(hash) == 0 {
 			str += fmt.Sprintf("<nil>\n")
 		} else if node == nil {
-			str += fmt.Sprintf("%s%40x: <nil>\n", nodePrefix, hash)
+			str += fmt.Sprintf("%s%40x: <nil>\n", nodeKeyFormat.Prefix(), hash)
 		} else if node.value == nil && node.height > 0 {
-			str += fmt.Sprintf("%s%40x: %s   %-16s h=%d version=%d\n", nodePrefix, hash, node.key, "", node.height, node.version)
+			str += fmt.Sprintf("%s%40x: %s   %-16s h=%d version=%d\n",
+				nodeKeyFormat.Prefix(), hash, node.key, "", node.height, node.version)
 		} else {
-			str += fmt.Sprintf("%s%40x: %s = %-16s h=%d version=%d\n", nodePrefix, hash, node.key, node.value, node.height, node.version)
+			str += fmt.Sprintf("%s%40x: %s = %-16s h=%d version=%d\n",
+				nodeKeyFormat.Prefix(), hash, node.key, node.value, node.height, node.version)
 		}
 		index++
 	})
diff --git a/vendor/github.com/tendermint/iavl/version.go b/vendor/github.com/tendermint/iavl/version.go
index f88f00abc7e5508da298d8235043a0446fc11839..aa993f09b624a595df384fabd6454100b086a894 100644
--- a/vendor/github.com/tendermint/iavl/version.go
+++ b/vendor/github.com/tendermint/iavl/version.go
@@ -1,4 +1,4 @@
 package iavl
 
 // Version of iavl.
-const Version = "0.10.0"
+const Version = "0.11.0"