diff --git a/client/cmd/eris-client.go b/client/cmd/eris-client.go
index 48df67ab121460f278cd8c4144f1f7475e03aeb8..57e8d3ba4b8f7da97c2dc4d8adae4711c02c1a15 100644
--- a/client/cmd/eris-client.go
+++ b/client/cmd/eris-client.go
@@ -39,7 +39,7 @@ var ErisClientCmd = &cobra.Command{
 
 Made with <3 by Eris Industries.
 
-Complete documentation is available at https://docs.erisindustries.com
+Complete documentation is available at https://monax.io/docs/documentation
 ` + "\nVERSION:\n " + version.VERSION,
 	PersistentPreRun: func(cmd *cobra.Command, args []string) {
 		log.SetLevel(log.WarnLevel)
diff --git a/cmd/eris-db.go b/cmd/eris-db.go
index 4894bd295d3b01ede143a6b361ac7d670556a7bc..605b12060b4f669c249dd4a04b05937f6b568262 100644
--- a/cmd/eris-db.go
+++ b/cmd/eris-db.go
@@ -41,7 +41,7 @@ your needs.
 
 Made with <3 by Eris Industries.
 
-Complete documentation is available at https://docs.erisindustries.com
+Complete documentation is available at https://monax.io/docs/documentation
 ` + "\nVERSION:\n " + version.VERSION,
 	PersistentPreRun: func(cmd *cobra.Command, args []string) {
 
diff --git a/docs/generator.go b/docs/generator.go
index 09acab42729334eb2c89d5faad464b0d3adb659f..fb430fc067be744340d07c486593563e994a75fd 100644
--- a/docs/generator.go
+++ b/docs/generator.go
@@ -2,6 +2,7 @@ package main
 
 import (
 	"fmt"
+	"io/ioutil"
 	"os"
 	"strings"
 	"text/template"
@@ -9,9 +10,9 @@ import (
 	"github.com/eris-ltd/common/go/docs"
 	commands "github.com/eris-ltd/eris-db/cmd"
 
+	clientCommands "github.com/eris-ltd/eris-db/client/cmd"
 	"github.com/eris-ltd/eris-db/version"
 	"github.com/spf13/cobra"
-	clientCommands "github.com/eris-ltd/eris-db/client/cmd"
 )
 
 // Repository maintainers should customize the next two lines.
@@ -77,6 +78,40 @@ func RenderFiles(cmdRaw *cobra.Command, tmpl *template.Template) error {
 	return nil
 }
 
+func AddClientToDB(dbCmd, clientCmd *cobra.Command) error {
+	// formulate the filenames properly
+	dbFile := docs.GenerateFileName(RenderDir, dbCmd.CommandPath())
+	clFile := docs.GenerateFileName(RenderDir, clientCmd.CommandPath())
+
+	// get the manual additions sorted
+	dbAdditions := []byte(fmt.Sprintf("\n# Related Commands\n\n* [%s](%s)", "Eris Client", docs.GenerateURLFromFileName(clFile)))
+	clAdditions := []byte(fmt.Sprintf("\n# Related Commands\n\n* [%s](%s)", "Eris DB", docs.GenerateURLFromFileName(dbFile)))
+
+	// read and write the db file
+	dbTxt, err := ioutil.ReadFile(dbFile)
+	if err != nil {
+		return err
+	}
+	dbTxt = append(dbTxt, dbAdditions...)
+	err = ioutil.WriteFile(dbFile, dbTxt, 0644)
+	if err != nil {
+		return err
+	}
+
+	// read and write the client file
+	clTxt, err := ioutil.ReadFile(clFile)
+	if err != nil {
+		return err
+	}
+	clTxt = append(clTxt, clAdditions...)
+	err = ioutil.WriteFile(clFile, clTxt, 0644)
+	if err != nil {
+		return err
+	}
+
+	return nil
+}
+
 func main() {
 	// Repository maintainers should populate the top level command object.
 	erisDbCommand := commands.ErisDbCmd
@@ -87,7 +122,6 @@ func main() {
 	erisClientCommand := clientCommands.ErisClientCmd
 	clientCommands.InitErisClientInit()
 	clientCommands.AddClientCommands()
-	clientCommands.AddGlobalFlags()
 
 	// Make the proper directory.
 	var err error
@@ -122,4 +156,8 @@ func main() {
 	if err = RenderFiles(erisClientCommand, tmpl); err != nil {
 		panic(err)
 	}
+
+	if err = AddClientToDB(erisDbCommand, erisClientCommand); err != nil {
+		panic(err)
+	}
 }
diff --git a/docs/specs/api.md b/docs/specs/api.md
index 5af0164e50a0d1aca70f1698cb5d3c088af3373b..0946d9d20cf4485f544cd06280aa8050f3efc787 100644
--- a/docs/specs/api.md
+++ b/docs/specs/api.md
@@ -2,7 +2,7 @@
 
 ### for eris-db version 0.11.x
 
-Eris DB allows remote access to its functionality over http and websocket. It currently supports [JSON-RPC 2.0](http://www.jsonrpc.org/specification), and REST-like http. There is also javascript bindings available in the [erisdb-js](TODO) library.
+Eris DB allows remote access to its functionality over http and websocket. It currently supports [JSON-RPC 2.0](http://www.jsonrpc.org/specification), and REST-like http. There is also javascript bindings available in the [erisdb-js](/docs/documentation/db.js/) library.
 
 ## TOC
 
@@ -78,9 +78,9 @@ Request:
 
 ```
 {
-	jsonrpc: "2.0", 
-	method: "erisdb.getAccount", 
-	params: {address: "37236DF251AB70022B1DA351F08A20FB52443E37"}, 
+	jsonrpc: "2.0",
+	method: "erisdb.getAccount",
+	params: {address: "37236DF251AB70022B1DA351F08A20FB52443E37"},
 	id="25"
 }
 ```
@@ -107,10 +107,10 @@ The REST-like API provides the typical endpoint structure i.e. endpoints are nam
 ##Common objects and formatting
 
 This section contains some common objects and explanations of how they work.
-  
+
 ###Numbers and strings
 
-Numbers are always numbers, and never strings. This is different from Ethereum where currency values are so high they need string representations. The only thing hex strings are used for is to represent byte arrays. 
+Numbers are always numbers, and never strings. This is different from Ethereum where currency values are so high they need string representations. The only thing hex strings are used for is to represent byte arrays.
 
 Hex strings are never prefixed.
 
@@ -267,18 +267,18 @@ Tendermint events can be subscribed to regardless of what connection type is use
 - [EventSubscribe](#event-subscribe) is used to subscribe to a given event, using an event-id string as argument. The response will contain a `subscription ID`, which can be used to close down the subscription later, or poll for new events if using HTTP. More on event-ids below.
 - [EventUnsubscribe](#event-unsubscribe) is used to unsubscribe to an event. It requires you to pass the `subscription ID` as an argument.
 - [EventPoll](#event-poll) is used to get all the events that has accumulated since the last time the subscription was polled. It takes the `subscription ID` as a parameter. NOTE: This only works over HTTP. Websocket connections will automatically receive events as they happen. They are sent as regular JSON-RPC 2.0 responses with the `subscriber ID` as response id.
- 
+
 There is another slight difference between polling and websocket, and that is the data you receive. If using sockets, it will always be one event at a time, whereas polling will give you an array of events.
 
 ### Event types
 
-These are the type of events you can subscribe to. 
+These are the type of events you can subscribe to.
 
-The "Account" events are triggered when someone transacts with the given account, and can be used to keep track of account activity. 
+The "Account" events are triggered when someone transacts with the given account, and can be used to keep track of account activity.
 
-NewBlock and Fork happens when a new block is committed or a fork happens, respectively. 
+NewBlock and Fork happens when a new block is committed or a fork happens, respectively.
 
-The other events are directly related to consensus. You can find out more about the Tendermint consensus system in the Tendermint [white paper](http://tendermint.com/docs/tendermint.pdf). There is also information in the consensus [sources](https://github.com/tendermint/tendermint/blob/master/consensus/state.go), although a normal user would not be concerned with the consensus mechanisms, but would mostly just listen to account- and perhaps block-events. 
+The other events are directly related to consensus. You can find out more about the Tendermint consensus system in the Tendermint [white paper](http://tendermint.com/docs/tendermint.pdf). There is also information in the consensus [sources](https://github.com/tendermint/tendermint/blob/master/consensus/state.go), although a normal user would not be concerned with the consensus mechanisms, but would mostly just listen to account- and perhaps block-events.
 
 #### Account Input
 
@@ -314,9 +314,9 @@ Event object:
 
 #### Account Call
 
-This notifies you when an account is the target of a call. This event is emitted when `CallTx`s (transactions) that target the given account has been finalized. It is possible to listen to this event when creating new contracts as well; it will fire when the transaction is committed (or not, in which case the 'exception' field will explain why it failed). 
+This notifies you when an account is the target of a call. This event is emitted when `CallTx`s (transactions) that target the given account has been finalized. It is possible to listen to this event when creating new contracts as well; it will fire when the transaction is committed (or not, in which case the 'exception' field will explain why it failed).
 
-**NOTE: The naming here is a bit unfortunate. Ethereum uses 'transaction' for (state-changing) transactions to a contract account, and 'call' for read-only calls like is used for accessor functions and such. Tendermint on the other hand, which uses many types of transactions uses 'CallTx' for a transaction made to a contract account, since it calls the code in that contract, and refers to these simply as 'calls'. Read-only calls is normally referred to as 'simulated calls'.** 
+**NOTE: The naming here is a bit unfortunate. Ethereum uses 'transaction' for (state-changing) transactions to a contract account, and 'call' for read-only calls like is used for accessor functions and such. Tendermint on the other hand, which uses many types of transactions uses 'CallTx' for a transaction made to a contract account, since it calls the code in that contract, and refers to these simply as 'calls'. Read-only calls is normally referred to as 'simulated calls'.**
 
 Event ID: `Acc/<address>/Call`
 
@@ -470,7 +470,7 @@ See the [TransactNameReg](#transact-name-reg) method for more info about adding
 <a name="methods"></a>
 ##Methods
 
-###Accounts 
+###Accounts
 | Name | RPC method name | HTTP method | HTTP endpoint |
 | :--- | :-------------- | :---------: | :------------ |
 | [GetAccounts](#get-accounts) | erisdb.getAccounts | GET | `/accounts` |
@@ -560,12 +560,12 @@ In the case of **REST-like HTTP** GET requests, the params (and query) is provid
 **Unsafe** is methods that require a private key to be sent either to or from the client, and should therefore be used only during development/testing, or with extreme care. They may be phased out entirely.
 
 <a name="accounts"></a>
-###Accounts 
+###Accounts
 
 ***
 
 <a name="get-accounts"></a>
-####GetAccounts 
+####GetAccounts
 
 Get accounts will return a list of accounts. If no filtering is used, it will return all existing accounts.
 
@@ -617,7 +617,7 @@ Get an account by its address.
 
 #####HTTP
 
-Method: GET 
+Method: GET
 
 Endpoint: `/accounts/:address`
 
@@ -661,15 +661,15 @@ There are two types of objects used to represent accounts, one is public account
 ***
 
 <a name="get-storage"></a>
-####GetStorage 
+####GetStorage
 
-Get the complete storage of a contract account. Non-contract accounts has no storage. 
+Get the complete storage of a contract account. Non-contract accounts has no storage.
 
 NOTE: This is mainly used for debugging. In most cases the storage of an account would be accessed via public accessor functions defined in the contracts ABI.
 
 #####HTTP
 
-Method: GET 
+Method: GET
 
 Endpoint: `/accounts/:address/storage`
 
@@ -705,7 +705,7 @@ See `GetStorageAt` below for more info on the `StorageItem` object.
 <a name="get-storage-at"></a>
 ####GetStorageAt
 
-Get a particular entry in the storage of a contract account. Non-contract accounts has no storage. 
+Get a particular entry in the storage of a contract account. Non-contract accounts has no storage.
 
 NOTE: This is mainly used for debugging. In most cases the storage of an account would be accessed via public accessor functions defined in the contracts ABI.
 
@@ -751,7 +751,7 @@ Both `key` and `value` are hex strings.
 <a name="get-blockchain-info"></a>
 ####GetBlockchainInfo
 
-Get the current state of the blockchain. This includes things like chain-id and latest block height. There are individual getters for all fields as well. 
+Get the current state of the blockchain. This includes things like chain-id and latest block height. There are individual getters for all fields as well.
 
 #####HTTP
 
@@ -772,7 +772,7 @@ Parameter: -
 	chain_id:            <string>
 	genesis_hash:        <string>
 	latest_block:        <BlockMeta>
-	latest_block_height: <number> 
+	latest_block_height: <number>
 }
 ```
 
@@ -836,7 +836,7 @@ Parameter: -
 
 ```
 {
-	genesis_hash:        <string> 
+	genesis_hash:        <string>
 }
 ```
 
@@ -863,7 +863,7 @@ Parameter: -
 
 ```
 {
-	latest_block_height: <number> 
+	latest_block_height: <number>
 }
 ```
 
@@ -872,7 +872,7 @@ Parameter: -
 <a name="get-latest-block"></a>
 ####GetLatestBlock
 
-Gets the block that was added to the chain most recently. 
+Gets the block that was added to the chain most recently.
 
 #####HTTP
 
@@ -890,20 +890,20 @@ Parameter: -
 
 ```
 {
-	latest_block:        <BlockMeta> 
+	latest_block:        <BlockMeta>
 }
 ```
 
 #####Additional info
 
-See [GetBlock](#get-block) for more info on the `BlockMeta` type. 
+See [GetBlock](#get-block) for more info on the `BlockMeta` type.
 
 ***
 
 <a name="get-blocks"></a>
 ####GetBlocks
 
-Get a series of blocks from the chain. 
+Get a series of blocks from the chain.
 
 #####HTTP
 
@@ -915,7 +915,7 @@ Endpoint: `/blockchain/blocks`
 
 Method: `erisdb.getBlocks`
 
-Parameter: 
+Parameter:
 
 ```
 {
@@ -974,14 +974,14 @@ See the section on [Filters](#queries-filters) for info on the `FilterData` obje
 
 `min_height` and `max_height` is the two actual values used for min and max height when fetching the blocks. The reason they are included is because the heights might have been modified, like for example when the blockchain height is lower then the max height provided in the query.
 
-See [GetBlock](#get-block) for more info on the `BlockMeta` type. 
+See [GetBlock](#get-block) for more info on the `BlockMeta` type.
 
 ***
 
 <a name="get-block"></a>
 ####GetBlock
 
-Get the block at the given height. 
+Get the block at the given height.
 
 #####HTTP
 
@@ -997,7 +997,7 @@ Parameter:
 
 ```
 {
-	height: <number> 
+	height: <number>
 }
 ```
 
@@ -1005,7 +1005,7 @@ Parameter:
 
 ```
 {
-	
+
 	header: {
 		chain_id:        <string>
 		height:          <number>
@@ -1044,7 +1044,7 @@ The `Commit` object:
 
 TODO
 
-See [The transaction types](#the-transaction-types) for more info on the `Tx` types. 
+See [The transaction types](#the-transaction-types) for more info on the `Tx` types.
 
 ***
 
@@ -1056,7 +1056,7 @@ See [The transaction types](#the-transaction-types) for more info on the `Tx` ty
 <a name="get-consensus-state"></a>
 ####GetConsensusState
 
-Get the current consensus state. 
+Get the current consensus state.
 
 #####HTTP
 
@@ -1107,7 +1107,7 @@ See the GetValidators method right below for info about the `Validator` object.
 <a name="get-validators"></a>
 ####GetValidators
 
-Get the validators. 
+Get the validators.
 
 #####HTTP
 
@@ -1159,7 +1159,7 @@ TODO
 <a name="event-subscribe"></a>
 ####EventSubscribe
 
-Subscribe to a given type of event.  
+Subscribe to a given type of event.
 
 #####HTTP
 
@@ -1173,7 +1173,7 @@ Body: See JSON-RPC parameter.
 
 Method: `erisdb.eventSubscribe`
 
-Parameter: 
+Parameter:
 
 ```
 {
@@ -1198,7 +1198,7 @@ For more information about events and the event system, see the [Event system](#
 <a name="event-unsubscribe"></a>
 ####EventUnubscribe
 
-Unsubscribe to an event type.  
+Unsubscribe to an event type.
 
 #####HTTP
 
@@ -1317,7 +1317,7 @@ Get a namereg entry by its key.
 
 #####HTTP
 
-Method: GET 
+Method: GET
 
 Endpoint: `/namereg/:name`
 
@@ -1547,7 +1547,7 @@ Endpoint: `/network/peer/:address`
 
 Method: `erisdb.getPeer`
 
-Parameters: 
+Parameters:
 
 ```
 {
@@ -1579,16 +1579,16 @@ TODO
 ***
 
 <a name="transactions"></a>
-###Transactions 
+###Transactions
 
 ***
 
 <a name="broadcast-tx"></a>
-####BroadcastTx 
+####BroadcastTx
 
 Broadcast a given (signed) transaction to the node. It will be added to the tx pool if there are no issues, and if it is accepted by all validators it will eventually be committed to a block.
 
-WARNING: BroadcastTx will not be useful until we add a client-side signing solution. 
+WARNING: BroadcastTx will not be useful until we add a client-side signing solution.
 
 #####HTTP
 
@@ -1606,7 +1606,7 @@ Body:
 
 Method: `erisdb.BroadcastTx`
 
-Parameters: 
+Parameters:
 
 ```
 <Tx>
@@ -1630,7 +1630,7 @@ Parameters:
 
 If a contract was created, then `contract_addr` will contain the address. NOTE: This is no guarantee that the contract will actually be commited to the chain. This response is returned upon broadcasting, not when the transaction has been committed to a block.
 
-See [The transaction types](#the-transaction-types) for more info on the `Tx` types. 
+See [The transaction types](#the-transaction-types) for more info on the `Tx` types.
 
 ***
 
@@ -1662,19 +1662,19 @@ Parameters: -
 
 #####Additional info
 
-See [The transaction types](#the-transaction-types) for more info on the `Tx` types. 
+See [The transaction types](#the-transaction-types) for more info on the `Tx` types.
 
 ***
 
 <a name="calls"></a>
-###Code execution (calls) 
+###Code execution (calls)
 
 ***
 
 <a name="call"></a>
 ####Call
 
-Call a given (contract) account to execute its code with the given in-data. 
+Call a given (contract) account to execute its code with the given in-data.
 
 #####HTTP
 
@@ -1688,7 +1688,7 @@ Body: See JSON-RPC parameter.
 
 Method: `erisdb.call`
 
-Parameters: 
+Parameters:
 
 ```
 {
@@ -1729,7 +1729,7 @@ Body: See JSON-RPC parameter.
 
 Method: `erisdb.callCode`
 
-Parameters: 
+Parameters:
 
 ```
 {
@@ -1750,12 +1750,12 @@ Parameters:
 #####Additional info
 
 `code` is a hex-string representation of compiled contract code.
-`data` is a string of data formatted in accordance with the [contract ABI](TODO).
+`data` is a string of data formatted in accordance with the [contract ABI](/docs/documentation/contracts.js/).
 
 ***
 
 <a name="unsafe"></a>
-###Unsafe 
+###Unsafe
 
 These methods are unsafe because they require that a private key is either transmitted or received. They are supposed to be used only in development.
 
@@ -1783,7 +1783,7 @@ Body: See JSON-RPC parameters.
 
 Method: `erisdb.transact`
 
-Parameters: 
+Parameters:
 
 ```
 {
@@ -1811,7 +1811,7 @@ The same as with BroadcastTx:
 
 #####Additional info
 
-See [The transaction types](#the-transaction-types) for more info on the `CallTx` type. 
+See [The transaction types](#the-transaction-types) for more info on the `CallTx` type.
 
 If you want to hold the tx, use `/unsafe/txpool?hold=true`. See `TransactAndHold` below.
 
@@ -1826,7 +1826,7 @@ Convenience method for sending a transaction and holding until it's been committ
 * Use the other parameters to create a `CallTx` object.
 * Sign the transaction.
 * Broadcast the transaction.
-* Wait until the transaction is fully processed. 
+* Wait until the transaction is fully processed.
 
 When holding, the request will eventually timeout if the transaction is not processed nor produce an error. The response will then be an error that includes the transaction hash (which can be used for further investigation).
 
@@ -1844,7 +1844,7 @@ Body: See JSON-RPC parameters.
 
 Method: `erisdb.transactAndHold`
 
-Parameters: 
+Parameters:
 
 ```
 {
@@ -1878,7 +1878,7 @@ private key is the hex string only.
 
 #####Additional info
 
-See [The transaction types](#the-transaction-types) for more info on the `CallTx` type. 
+See [The transaction types](#the-transaction-types) for more info on the `CallTx` type.
 
 If you don't want to hold the tx, either use `/unsafe/txpool?hold=false` or omit the query entirely. See `Transact` for the regular version.
 
@@ -1906,7 +1906,7 @@ Body: See JSON-RPC parameters.
 
 Method: `erisdb.transactNameReg`
 
-Parameters: 
+Parameters:
 
 ```
 {
@@ -1932,7 +1932,7 @@ The same as with BroadcastTx:
 
 #####Additional info
 
-See [The transaction types](#the-transaction-types) for more info on the `NameTx` type. 
+See [The transaction types](#the-transaction-types) for more info on the `NameTx` type.
 
 ***
 
@@ -1985,7 +1985,7 @@ Filter:
 {
     field: <string>
     op:    <string>
-    value: <string> 
+    value: <string>
 }
 ```
 
@@ -2002,7 +2002,7 @@ We want an account filter that only includes accounts that has code in them (i.e
 {
     field: "code"
     op: "!="
-    value: "" 
+    value: ""
 }
 ```
 
@@ -2036,7 +2036,7 @@ We want an account filter that only includes accounts with a balance higher then
 
 The field `code` is supported by accounts. It allows for the `==` and `!=` operators. The value `""` means the empty hex string.
 
-If we wanted only non-contract accounts then we would have used the same object but changed it to `op: "=="`. 
+If we wanted only non-contract accounts then we would have used the same object but changed it to `op: "=="`.
 
 ###HTTP Queries
 
@@ -2047,13 +2047,13 @@ The structure of a normal query is: `q=field:[op]value+field2:[op2]value2+ ... `
 - `field` is the field name.
 - `:` is the field:relation separator.
 - `op` is the relational operator, `>, <, >=, <=, ==, !=`.
-- `value` is the value to compare against, e.g. `balance:>=5` or `language:==golang`. 
+- `value` is the value to compare against, e.g. `balance:>=5` or `language:==golang`.
 
 There is also support for [range queries](https://help.github.com/articles/search-syntax/): `A..B`, where `A` and `B` are number-strings. You may use the wildcard `*` instead of a number. The wildcard is context-sensitive; if it is put on the left-hand side it is the minimum value, and on the right-hand side it means the maximum value. Let `height` be an unsigned byte with no additional restrictions. `height:*..55` would then be the same as `height:0..55`, and `height:*..*` would be the same as `height:0..255`.
 
 NOTE: URL encoding applies as usual. Omitting it here for clarity.
 
-`op` will default to (`==`) if left out, meaning `balance:5` is the same as `balance:==5` 
+`op` will default to (`==`) if left out, meaning `balance:5` is the same as `balance:==5`
 
 `value` may be left out if the field accepts the empty string as input. This means if `code` is a supported string type,  `code:==` would check if the code field is empty. We could also use the inferred `==` meaning this would be equivalent: `code:`.  The system may be extended so that the empty string is automatically converted to the null-type of the underlying field, no matter what that type is. If balance is a number then `balance:` would be the same as `balance:==0` (and `balance:0`).
 
diff --git a/glide.lock b/glide.lock
index 04962b493df9f9c4e67b0904de39b88fc0e04fc2..a12154d9e835e4ad2b0f0157167a0e9450b4b32d 100644
--- a/glide.lock
+++ b/glide.lock
@@ -223,5 +223,5 @@ imports:
 - name: gopkg.in/yaml.v2
   version: a83829b6f1293c91addabc89d0571c246397bbf4
 - name: github.com/eris-ltd/common
-  version: 87c464f03bbc41e25a4abb27bf897931fc50be3e
+  version: 8d928eec1d46942444f81eaa33c06da1c6e48ed9
 devImports: []
diff --git a/manager/eris-mint/evm/opcodes.go b/manager/eris-mint/evm/opcodes/opcodes.go
similarity index 81%
rename from manager/eris-mint/evm/opcodes.go
rename to manager/eris-mint/evm/opcodes/opcodes.go
index ee125eaa7202f584e49a050ced61cac0910960b1..b4205f2fe9633a80643740da942fbc51b1ff5382 100644
--- a/manager/eris-mint/evm/opcodes.go
+++ b/manager/eris-mint/evm/opcodes/opcodes.go
@@ -1,4 +1,4 @@
-package vm
+package opcodes
 
 import (
 	"fmt"
@@ -355,3 +355,51 @@ func AnalyzeJumpDests(code []byte) (dests *set.Set) {
 	}
 	return
 }
+
+// Convenience function to allow us to mix bytes, ints, and OpCodes that
+// represent bytes in an EVM assembly code to make assembly more readable.
+// Also allows us to splice together assembly
+// fragments because any []byte arguments are flattened in the result.
+func Bytecode(bytelikes ...interface{}) []byte {
+	bytes := make([]byte, len(bytelikes))
+	for i, bytelike := range bytelikes {
+		switch b := bytelike.(type) {
+		case byte:
+			bytes[i] = b
+		case OpCode:
+			bytes[i] = byte(b)
+		case int:
+			bytes[i] = byte(b)
+			if int(bytes[i]) != b {
+				panic(fmt.Sprintf("The int %v does not fit inside a byte", b))
+			}
+		case int64:
+			bytes[i] = byte(b)
+			if int64(bytes[i]) != b {
+				panic(fmt.Sprintf("The int64 %v does not fit inside a byte", b))
+			}
+		case []byte:
+			// splice
+			return Concat(bytes[:i], b, Bytecode(bytelikes[i+1:]...))
+		default:
+			panic("Only byte-like codes (and []byte sequences) can be used to form bytecode")
+		}
+	}
+	return bytes
+}
+
+func Concat(bss ...[]byte) []byte {
+	offset := 0
+	for _, bs := range bss {
+		offset += len(bs)
+	}
+	bytes := make([]byte, offset)
+	offset = 0
+	for _, bs := range bss {
+		for i, b := range bs {
+			bytes[offset+i] = b
+		}
+		offset += len(bs)
+	}
+	return bytes
+}
diff --git a/manager/eris-mint/evm/test/log_event_test.go b/manager/eris-mint/evm/test/log_event_test.go
index 302f2912571e87d7f605f0370b81e7f66f32ec07..5f1eb2f463acfc0842878724c557d4f73d99ea6e 100644
--- a/manager/eris-mint/evm/test/log_event_test.go
+++ b/manager/eris-mint/evm/test/log_event_test.go
@@ -6,6 +6,7 @@ import (
 	"testing"
 
 	. "github.com/eris-ltd/eris-db/manager/eris-mint/evm"
+	. "github.com/eris-ltd/eris-db/manager/eris-mint/evm/opcodes"
 	"github.com/eris-ltd/eris-db/txs"
 	. "github.com/tendermint/go-common"
 	"github.com/tendermint/go-events"
diff --git a/manager/eris-mint/evm/test/vm_test.go b/manager/eris-mint/evm/test/vm_test.go
index 11686e63a9676e837511dccd87ef2476cbe721e8..53895c0da1b590c7754c290ed5922b086a437010 100644
--- a/manager/eris-mint/evm/test/vm_test.go
+++ b/manager/eris-mint/evm/test/vm_test.go
@@ -8,13 +8,21 @@ import (
 	"testing"
 	"time"
 
+	"errors"
+
 	. "github.com/eris-ltd/eris-db/manager/eris-mint/evm"
+	. "github.com/eris-ltd/eris-db/manager/eris-mint/evm/opcodes"
 	ptypes "github.com/eris-ltd/eris-db/permission/types"
 	"github.com/eris-ltd/eris-db/txs"
+	"github.com/stretchr/testify/assert"
 	. "github.com/tendermint/go-common"
 	"github.com/tendermint/go-events"
 )
 
+func init() {
+	SetDebug(true)
+}
+
 func newAppState() *FakeAppState {
 	fas := &FakeAppState{
 		accounts: make(map[string]*Account),
@@ -154,65 +162,164 @@ func TestSendCall(t *testing.T) {
 
 	//----------------------------------------------
 	// account2 has insufficient balance, should fail
-	fmt.Println("Should fail with insufficient balance")
-
-	exception := runVMWaitEvents(t, ourVm, account1, account2, addr, contractCode, 1000)
-	if exception == "" {
-		t.Fatal("Expected exception")
-	}
+	_, err := runVMWaitError(ourVm, account1, account2, addr, contractCode, 1000)
+	assert.Error(t, err, "Expected insufficient balance error")
 
 	//----------------------------------------------
 	// give account2 sufficient balance, should pass
-
 	account2.Balance = 100000
-	exception = runVMWaitEvents(t, ourVm, account1, account2, addr, contractCode, 1000)
-	if exception != "" {
-		t.Fatal("Unexpected exception", exception)
-	}
+	_, err = runVMWaitError(ourVm, account1, account2, addr, contractCode, 1000)
+	assert.NoError(t, err, "Should have sufficient balance")
 
 	//----------------------------------------------
 	// insufficient gas, should fail
-	fmt.Println("Should fail with insufficient gas")
 
 	account2.Balance = 100000
-	exception = runVMWaitEvents(t, ourVm, account1, account2, addr, contractCode, 100)
-	if exception == "" {
-		t.Fatal("Expected exception")
+	_, err = runVMWaitError(ourVm, account1, account2, addr, contractCode, 100)
+	assert.Error(t, err, "Expected insufficient gas error")
+}
+
+// This test was introduced to cover an issues exposed in our handling of the
+// gas limit passed from caller to callee on various forms of CALL
+// this ticket gives some background: https://github.com/eris-ltd/eris-pm/issues/212
+// The idea of this test is to implement a simple DelegateCall in EVM code
+// We first run the DELEGATECALL with _just_ enough gas expecting a simple return,
+// and then run it with 1 gas unit less, expecting a failure
+func TestDelegateCallGas(t *testing.T) {
+	appState := newAppState()
+	ourVm := NewVM(appState, newParams(), Zero256, nil)
+
+	inOff := 0
+	inSize := 0 // no call data
+	retOff := 0
+	retSize := 32
+	calleeReturnValue := int64(20)
+
+	// DELEGATECALL(retSize, refOffset, inSize, inOffset, addr, gasLimit)
+	// 6 pops
+	delegateCallCost := GasStackOp * 6
+	// 1 push
+	gasCost := GasStackOp
+	// 2 pops, 1 push
+	subCost := GasStackOp * 3
+	pushCost := GasStackOp
+
+	costBetweenGasAndDelegateCall := gasCost + subCost + delegateCallCost + pushCost
+
+	// Do a simple operation using 1 gas unit
+	calleeAccount, calleeAddress := makeAccountWithCode(appState, "callee",
+		Bytecode(PUSH1, calleeReturnValue, return1()))
+
+	// Here we split up the caller code so we can make a DELEGATE call with
+	// different amounts of gas. The value we sandwich in the middle is the amount
+	// we subtract from the available gas (that the caller has available), so:
+	// code := Bytecode(callerCodePrefix, <amount to subtract from GAS> , callerCodeSuffix)
+	// gives us the code to make the call
+	callerCodePrefix := Bytecode(PUSH1, retSize, PUSH1, retOff, PUSH1, inSize,
+		PUSH1, inOff, PUSH20, calleeAddress, PUSH1)
+	callerCodeSuffix := Bytecode(GAS, SUB, DELEGATECALL, returnWord())
+
+	// Perform a delegate call
+	callerAccount, _ := makeAccountWithCode(appState, "caller",
+		Bytecode(callerCodePrefix,
+			// Give just enough gas to make the DELEGATECALL
+			costBetweenGasAndDelegateCall,
+			callerCodeSuffix))
+
+	// Should pass
+	output, err := runVMWaitError(ourVm, callerAccount, calleeAccount, calleeAddress,
+		callerAccount.Code, 100)
+	assert.NoError(t, err, "Should have sufficient funds for call")
+	assert.Equal(t, Int64ToWord256(calleeReturnValue).Bytes(), output)
+
+	callerAccount.Code = Bytecode(callerCodePrefix,
+		// Shouldn't be enough gas to make call
+		costBetweenGasAndDelegateCall-1,
+		callerCodeSuffix)
+
+	// Should fail
+	_, err = runVMWaitError(ourVm, callerAccount, calleeAccount, calleeAddress,
+		callerAccount.Code, 100)
+	assert.Error(t, err, "Should have insufficient funds for call")
+}
+
+// Store the top element of the stack (which is a 32-byte word) in memory
+// and return it. Useful for a simple return value.
+func return1() []byte {
+	return Bytecode(PUSH1, 0, MSTORE, returnWord())
+}
+
+func returnWord() []byte {
+	// PUSH1 => return size, PUSH1 => return offset, RETURN
+	return Bytecode(PUSH1, 32, PUSH1, 0, RETURN)
+}
+
+func makeAccountWithCode(appState AppState, name string,
+	code []byte) (*Account, []byte) {
+	account := &Account{
+		Address: LeftPadWord256([]byte(name)),
+		Balance: 9999999,
+		Code:    code,
+		Nonce:   0,
+	}
+	account.Code = code
+	appState.UpdateAccount(account)
+	// Sanity check
+	address := new([20]byte)
+	for i, b := range account.Address.Postfix(20) {
+		address[i] = b
+	}
+	return account, address[:]
+}
+
+// Subscribes to an AccCall, runs the vm, returns the output any direct exception
+// and then waits for any exceptions transmitted by EventData 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(ourVm *VM, caller, callee *Account, subscribeAddr,
+	contractCode []byte, gas int64) (output []byte, err error) {
+	eventCh := make(chan txs.EventData)
+	output, err = runVM(eventCh, ourVm, caller, callee, subscribeAddr,
+		contractCode, gas)
+	if err != nil {
+		return
+	}
+	msg := <-eventCh
+	var errString string
+	switch ev := msg.(type) {
+	case txs.EventDataTx:
+		errString = ev.Exception
+	case txs.EventDataCall:
+		errString = ev.Exception
+	}
+
+	if errString != "" {
+		err = errors.New(errString)
 	}
+	return
 }
 
-// subscribes to an AccCall, runs the vm, returns the exception
-func runVMWaitEvents(t *testing.T, ourVm *VM, caller, callee *Account, subscribeAddr, contractCode []byte, gas int64) string {
+// Subscribes to an AccCall, runs the vm, returns the output and any direct
+// exception
+func runVM(eventCh chan txs.EventData, ourVm *VM, caller, callee *Account,
+	subscribeAddr, contractCode []byte, gas int64) ([]byte, error) {
+
 	// we need to catch the event from the CALL to check for exceptions
 	evsw := events.NewEventSwitch()
 	evsw.Start()
-	ch := make(chan interface{})
 	fmt.Printf("subscribe to %x\n", subscribeAddr)
-	evsw.AddListenerForEvent("test", txs.EventStringAccCall(subscribeAddr), func(msg events.EventData) {
-		ch <- msg
-	})
+	evsw.AddListenerForEvent("test", txs.EventStringAccCall(subscribeAddr),
+		func(msg events.EventData) {
+			eventCh <- msg.(txs.EventData)
+		})
 	evc := events.NewEventCache(evsw)
 	ourVm.SetFireable(evc)
-	go func() {
-		start := time.Now()
-		output, err := ourVm.Call(caller, callee, contractCode, []byte{}, 0, &gas)
-		fmt.Printf("Output: %v Error: %v\n", output, err)
-		fmt.Println("Call took:", time.Since(start))
-		if err != nil {
-			ch <- err.Error()
-		}
-		evc.Flush()
-	}()
-	msg := <-ch
-	switch ev := msg.(type) {
-	case txs.EventDataTx:
-		return ev.Exception
-	case txs.EventDataCall:
-		return ev.Exception
-	case string:
-		return ev
-	}
-	return ""
+	start := time.Now()
+	output, err := ourVm.Call(caller, callee, contractCode, []byte{}, 0, &gas)
+	fmt.Printf("Output: %v Error: %v\n", output, err)
+	fmt.Println("Call took:", time.Since(start))
+	go func() { evc.Flush() }()
+	return output, err
 }
 
 // this is code to call another contract (hardcoded as addr)
@@ -222,17 +329,42 @@ func callContractCode(addr []byte) []byte {
 	inOff, inSize := byte(0x0), byte(0x0) // no call data
 	retOff, retSize := byte(0x0), byte(0x20)
 	// this is the code we want to run (send funds to an account and return)
+	return Bytecode(PUSH1, retSize, PUSH1, retOff, PUSH1, inSize, PUSH1,
+		inOff, PUSH1, value, PUSH20, addr, PUSH2, gas1, gas2, CALL, PUSH1, retSize,
+		PUSH1, retOff, RETURN)
+}
+
+func TestBytecode(t *testing.T) {
+	assert.Equal(t,
+		Bytecode(1, 2, 3, 4, 5, 6),
+		Bytecode(1, 2, 3, Bytecode(4, 5, 6)))
+	assert.Equal(t,
+		Bytecode(1, 2, 3, 4, 5, 6, 7, 8),
+		Bytecode(1, 2, 3, Bytecode(4, Bytecode(5), 6), 7, 8))
+	assert.Equal(t,
+		Bytecode(PUSH1, 2),
+		Bytecode(byte(PUSH1), 0x02))
+	assert.Equal(t,
+		[]byte{},
+		Bytecode(Bytecode(Bytecode())))
+
+	contractAccount := &Account{Address: Int64ToWord256(102)}
+	addr := contractAccount.Address.Postfix(20)
+	gas1, gas2 := byte(0x1), byte(0x1)
+	value := byte(0x69)
+	inOff, inSize := byte(0x0), byte(0x0) // no call data
+	retOff, retSize := byte(0x0), byte(0x20)
+	contractCodeBytecode := Bytecode(PUSH1, retSize, PUSH1, retOff, PUSH1, inSize, PUSH1,
+		inOff, PUSH1, value, PUSH20, addr, PUSH2, gas1, gas2, CALL, PUSH1, retSize,
+		PUSH1, retOff, RETURN)
 	contractCode := []byte{0x60, retSize, 0x60, retOff, 0x60, inSize, 0x60, inOff, 0x60, value, 0x73}
 	contractCode = append(contractCode, addr...)
 	contractCode = append(contractCode, []byte{0x61, gas1, gas2, 0xf1, 0x60, 0x20, 0x60, 0x0, 0xf3}...)
-	return contractCode
+	assert.Equal(t, contractCode, contractCodeBytecode)
 }
 
-/*
-	// infinite loop
-	code := []byte{0x5B, 0x60, 0x00, 0x56}
-	// mstore
-	code := []byte{0x60, 0x00, 0x60, 0x20}
-	// mstore, mload
-	code := []byte{0x60, 0x01, 0x60, 0x20, 0x52, 0x60, 0x20, 0x51}
-*/
+func TestConcat(t *testing.T) {
+	assert.Equal(t,
+		[]byte{0x01, 0x02, 0x03, 0x04},
+		Concat([]byte{0x01, 0x02}, []byte{0x03, 0x04}))
+}
diff --git a/manager/eris-mint/evm/vm.go b/manager/eris-mint/evm/vm.go
index cb451f34a89256a61cb91447b9ed511e1779e887..a3f4d51eacf5809c96f966e2a67df25146bd63e3 100644
--- a/manager/eris-mint/evm/vm.go
+++ b/manager/eris-mint/evm/vm.go
@@ -6,6 +6,7 @@ import (
 	"fmt"
 	"math/big"
 
+	. "github.com/eris-ltd/eris-db/manager/eris-mint/evm/opcodes"
 	"github.com/eris-ltd/eris-db/manager/eris-mint/evm/sha3"
 	ptypes "github.com/eris-ltd/eris-db/permission/types"
 	"github.com/eris-ltd/eris-db/txs"
@@ -17,7 +18,7 @@ var (
 	ErrUnknownAddress      = errors.New("Unknown address")
 	ErrInsufficientBalance = errors.New("Insufficient balance")
 	ErrInvalidJumpDest     = errors.New("Invalid jump dest")
-	ErrInsufficientGas     = errors.New("Insuffient gas")
+	ErrInsufficientGas     = errors.New("Insufficient gas")
 	ErrMemoryOutOfBounds   = errors.New("Memory out of bounds")
 	ErrCodeOutOfBounds     = errors.New("Code out of bounds")
 	ErrInputOutOfBounds    = errors.New("Input out of bounds")
@@ -194,7 +195,6 @@ func (vm *VM) call(caller, callee *Account, code, input []byte, value int64, gas
 	)
 
 	for {
-
 		// Use BaseOp gas.
 		if useGasNegative(gas, GasBaseOp, &err) {
 			return nil, err
@@ -816,7 +816,7 @@ func (vm *VM) call(caller, callee *Account, code, input []byte, value int64, gas
 					exception = err.Error()
 				}
 				// NOTE: these fire call events and not particular events for eg name reg or permissions
-				vm.fireCallEvent(&exception, &ret, callee, &Account{Address: addr}, args, value, gas)
+				vm.fireCallEvent(&exception, &ret, callee, &Account{Address: addr}, args, value, &gasLimit)
 			} else {
 				// EVM contract
 				if useGasNegative(gas, GasGetAccount, &err) {
@@ -831,12 +831,12 @@ func (vm *VM) call(caller, callee *Account, code, input []byte, value int64, gas
 					if acc == nil {
 						return nil, firstErr(err, ErrUnknownAddress)
 					}
-					ret, err = vm.Call(callee, callee, acc.Code, args, value, gas)
+					ret, err = vm.Call(callee, callee, acc.Code, args, value, &gasLimit)
 				} else if op == DELEGATECALL {
 					if acc == nil {
 						return nil, firstErr(err, ErrUnknownAddress)
 					}
-					ret, err = vm.DelegateCall(caller, callee, acc.Code, args, value, gas)
+					ret, err = vm.DelegateCall(caller, callee, acc.Code, args, value, &gasLimit)
 				} else {
 					// nil account means we're sending funds to a new account
 					if acc == nil {
@@ -847,7 +847,7 @@ func (vm *VM) call(caller, callee *Account, code, input []byte, value int64, gas
 					}
 					// add account to the tx cache
 					vm.appState.UpdateAccount(acc)
-					ret, err = vm.Call(callee, acc, acc.Code, args, value, gas)
+					ret, err = vm.Call(callee, acc, acc.Code, args, value, &gasLimit)
 				}
 			}
 
@@ -906,7 +906,6 @@ func (vm *VM) call(caller, callee *Account, code, input []byte, value int64, gas
 		}
 
 		pc++
-
 	}
 }
 
diff --git a/manager/eris-mint/state/permissions_test.go b/manager/eris-mint/state/permissions_test.go
index 5c311405a0dec3288770b8cbd2e2b347b89ec6a3..523a5ffc8b2a75a13749c8ba924d4c6ded2e824a 100644
--- a/manager/eris-mint/state/permissions_test.go
+++ b/manager/eris-mint/state/permissions_test.go
@@ -14,6 +14,7 @@ import (
 	ptypes "github.com/eris-ltd/eris-db/permission/types"
 	"github.com/eris-ltd/eris-db/txs"
 
+	. "github.com/eris-ltd/eris-db/manager/eris-mint/evm/opcodes"
 	. "github.com/tendermint/go-common"
 	"github.com/tendermint/go-crypto"
 	dbm "github.com/tendermint/go-db"
@@ -1257,17 +1258,17 @@ func snativeRoleTestInputTx(name string, user *acm.PrivAccount, role string) (sn
 func callContractCode(contractAddr []byte) []byte {
 	// calldatacopy into mem and use as input to call
 	memOff, inputOff := byte(0x0), byte(0x0)
-	contractCode := []byte{0x36, 0x60, inputOff, 0x60, memOff, 0x37}
-
-	gas1, gas2 := byte(0x1), byte(0x1)
 	value := byte(0x1)
 	inOff := byte(0x0)
 	retOff, retSize := byte(0x0), byte(0x20)
+
 	// this is the code we want to run (call a contract and return)
-	contractCode = append(contractCode, []byte{0x60, retSize, 0x60, retOff, 0x36, 0x60, inOff, 0x60, value, 0x73}...)
-	contractCode = append(contractCode, contractAddr...)
-	contractCode = append(contractCode, []byte{0x61, gas1, gas2, 0xf1, 0x60, 0x20, 0x60, 0x0, 0xf3}...)
-	return contractCode
+	return Bytecode(CALLDATASIZE, PUSH1, inputOff, PUSH1, memOff,
+		CALLDATACOPY, PUSH1, retSize, PUSH1, retOff, CALLDATASIZE, PUSH1, inOff,
+		PUSH1, value, PUSH20, contractAddr,
+		// Zeno loves us - call with half of the available gas each time we CALL
+		PUSH1, 2, GAS, DIV, CALL,
+		PUSH1, 32, PUSH1, 0, RETURN)
 }
 
 // convenience function for contract that is a factory for the code that comes as call data
diff --git a/manager/eris-mint/state/state_test.go b/manager/eris-mint/state/state_test.go
index 7f8cb8f11258e167fd2fe99fe8bc0dc7c5d794e2..be619f3354ec8853285e842e11576fbade65c824 100644
--- a/manager/eris-mint/state/state_test.go
+++ b/manager/eris-mint/state/state_test.go
@@ -11,12 +11,13 @@ import (
 	// tmtypes "github.com/tendermint/tendermint/types"
 
 	core_types "github.com/eris-ltd/eris-db/core/types"
-	//evm "github.com/eris-ltd/eris-db/manager/eris-mint/evm"
 	"github.com/eris-ltd/eris-db/txs"
+	evm "github.com/eris-ltd/eris-db/manager/eris-mint/evm"
 )
 
 func init() {
 	tendermint_test.ResetConfig("state_test")
+	evm.SetDebug(true)
 }
 
 func execTxWithState(state *State, tx txs.Tx, runCall bool) error {
@@ -463,7 +464,7 @@ func TestCreates(t *testing.T) {
 			PubKey:   acc0PubKey,
 		},
 		Address:  acc1.Address,
-		GasLimit: 10000,
+		GasLimit: 100000,
 		Data:     createData,
 	}