diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md
new file mode 100644
index 0000000000000000000000000000000000000000..b4abbe9bd1cd21db3023d582cc922ca58973f574
--- /dev/null
+++ b/.github/CONTRIBUTING.md
@@ -0,0 +1,70 @@
+# Contributing to `eris-db`:
+Forked from Docker's [contributing guidelines](https://github.com/docker/docker/blob/master/CONTRIBUTING.md)
+
+## Bug Reporting
+
+A great way to contribute to the project is to send a detailed report when you encounter an issue. We always appreciate a well-written, thorough bug report, and will thank you for it!
+
+Check that the issue doesn't already exist before submitting an issue. If you find a match, you can use the "subscribe" button to get notified on updates. Add a :+1: if you've also encountered this issue. If you have ways to reproduce the issue or have additional information that may help resolving the issue, please leave a comment.
+
+Also include the steps required to reproduce the problem if possible and applicable. This information will help us review and fix your issue faster. When sending lengthy log-files, post them as a gist (https://gist.github.com). Don't forget to remove sensitive data from your log files before posting (you can replace those parts with "REDACTED").
+
+Our [ISSUE_TEMPLATE.md](ISSUE_TEMPLATE.md) will autopopulate the new issue.
+
+## Contribution Tips and Guidelines
+
+### Pull requests are always welcome (to `develop` rather than `master`).
+
+Not sure if that typo is worth a pull request? Found a bug and know how to fix it? Do it! We will appreciate it. Any significant improvement should be documented as a GitHub issue or discussed in [The Marmot Den](https://slack.monax.io) Slack community prior to beginning.
+
+We are always thrilled to receive pull requests (and bug reports!) and we do our best to process them quickly. 
+
+## Conventions
+
+Fork the repository and make changes on your fork in a feature branch (branched from develop), create an issue outlining your feature or a bug, or use an open one.
+
+    If it's a bug fix branch, name it something-XXXX where XXXX is the number of the issue.
+    If it's a feature branch, create an enhancement issue to announce your intentions, and name it something-XXXX where XXXX is the number of the issue.
+
+Submit unit tests for your changes. Go has a great test framework built in; use it! Take a look at existing tests for inspiration. Run the full test suite on your branch before submitting a pull request.
+
+Update the documentation when creating or modifying features. Test your documentation changes for clarity, concision, and correctness, as well as a clean documentation build. 
+
+Write clean code. Universally formatted code promotes ease of writing, reading, and maintenance. Always run `gofmt -s -w file.go` on each changed file before committing your changes. Most editors have plug-ins that do this automatically.
+
+Pull request descriptions should be as clear as possible and include a reference to all the issues that they address.
+
+Commit messages must start with a short summary (max. 50 chars) written in the imperative, followed by an optional, more detailed explanatory text which is separated from the summary by an empty line.
+
+Code review comments may be added to your pull request. Discuss, then make the suggested modifications and push additional commits to your feature branch. 
+
+Pull requests must be cleanly rebased on top of develop without multiple branches mixed into the PR.
+
+*Git tip:* If your PR no longer merges cleanly, use `git rebase develop` in your feature branch to update your pull request rather than merge develop.
+
+Before you make a pull request, squash your commits into logical units of work using `git rebase -i` and `git push -f`. A logical unit of work is a consistent set of patches that should be reviewed together: for example, upgrading the version of a vendored dependency and taking advantage of its now available new feature constitute two separate units of work. Implementing a new function and calling it in another file constitute a single logical unit of work. The very high majority of submissions should have a single commit, so if in doubt: squash down to one.
+
+After every commit, make sure the test suite passes. Include documentation changes in the same pull request so that a revert would remove all traces of the feature or fix.
+
+### Merge approval
+
+We use LGTM (Looks Good To Me) in commands on the code review to indicate acceptance. 
+
+## Errors and Log Messages Style
+
+TODO
+
+## Coding Style
+
+Unless explicitly stated, we follow all coding guidelines from the Go community. While some of these standards may seem arbitrary, they somehow seem to result in a solid, consistent codebase.
+
+It is possible that the code base does not currently comply with these guidelines. We are not looking for a massive PR that fixes this, since that goes against the spirit of the guidelines. All new contributions should make a best effort to clean up and make the code base better than they left it. Obviously, apply your best judgement. Remember, the goal here is to make the code base easier for humans to navigate and understand. Always keep that in mind when nudging others to comply.
+
+* All code should be formatted with `gofmt -s`.
+* All code should follow the guidelines covered in [Effective Go](https://golang.org/doc/effective_go.html) and [Go Code Review Comments](https://github.com/golang/go/wiki/CodeReviewComments).
+* Comment the code. Tell us the why, the history and the context.
+* Document all declarations and methods, even private ones. Declare expectations, caveats and anything else that may be important. If a type gets exported, having the comments already there will ensure it's ready.
+* Variable name length should be proportional to it's context and no longer. noCommaALongVariableNameLikeThisIsNotMoreClearWhenASimpleCommentWouldDo. In practice, short methods will have short variable names and globals will have longer names.
+* No underscores in package names. If you need a compound name, step back, and re-examine why you need a compound name. If you still think you need a compound name, lose the underscore.
+* No utils or helpers packages. If a function is not general enough to warrant its own package, it has not been written generally enough to be a part of a `util` package. Just leave it unexported and well-documented.
+* All tests should run with `go test` and outside tooling should not be required. No, we don't need another unit testing framework. Assertion packages are acceptable if they provide real incremental value.
diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md
new file mode 100644
index 0000000000000000000000000000000000000000..e3867662dde61707fc52857e4a110850585c352b
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE.md
@@ -0,0 +1,12 @@
+Please include in your bug report:
+
+- [ ] `eris-db version` (docker image tag or branch if built from source)
+- [ ] `eris version` (if applicable)
+- [ ] `go version` (if applicable)
+- [ ] `docker version` (if applicable)
+- [ ] operating system details (osx/windows/linux)
+- [ ] what you expected to happen
+- [ ] what actually happened
+- [ ] steps to reproduction
+
+If issue is a feature request, tell us why this feature is useful.
diff --git a/.gitignore b/.gitignore
index d2482dea1fddf517c65e3d27012dfaffb6fcb809..12be4236c891d5077c99a4a556c9813fc1b86284 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,6 +1,11 @@
 # do not vendor in dependencies
 vendor
+
+# build target
+target
+
 # Temporary / cached
 *.swp
 debug
 .idea
+.vscode
diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
index 0000000000000000000000000000000000000000..6ab5699c9d45c45fe520221497e62c526f46dcbf
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,66 @@
+# Eris-db changelog
+## v0.16.0
+This is a consolidation release that fixes various bugs and improves elements
+of the architecture across the Eris Platform to support a quicker release
+cadence.
+
+#### Features and improvements (among others)
+- [pull-510](https://github.com/eris-ltd/eris-db/pull/510) upgrade consensus engine to Tendermint v0.8.0
+- [pull-507](https://github.com/eris-ltd/eris-db/pull/507) use sha3 for snative addresses for future-proofing
+- [pull-506](https://github.com/eris-ltd/eris-db/pull/506) alignment and consolidation for genesis and config between tooling and chains
+- [pull-504](https://github.com/eris-ltd/eris-db/pull/504) relicense eris-db to Apache 2.0
+- [pull-500](https://github.com/eris-ltd/eris-db/pull/500) introduce more strongly types secure native contracts
+- [pull-499](https://github.com/eris-ltd/eris-db/pull/499) introduce word256 and remove dependency on tendermint/go-common
+- [pull-493](https://github.com/eris-ltd/eris-db/pull/493) re-introduce GenesisTime in GenesisDoc
+
+- Logging system overhauled based on the central logging interface of go-kit log. Configuration lacking in this release but should be in 0.16.1. Allows powerful routing, filtering, and output options for better operations and increasing the observability of an eris blockchain. More to follow.
+- Genesis making is improved and moved into eris-db.
+- Config templating is moved into eris-db for better synchronisation of server config between the consumer of it (eris-db) and the producers of it (eris cli and other tools).
+- Some documentation updates in code and in specs.
+- [pull-462](https://github.com/eris-ltd/eris-db/pull/499) Makefile added to capture conventions around building and testing and replicate them across different environments such as continuous integration systems.
+
+#### Bugfixes (among others)
+- [pull-516](https://github.com/eris-ltd/eris-db/pull/516) Organize and add unit tests for rpc/v0
+- [pull-453](https://github.com/eris-ltd/eris-db/pull/453) Fix deserialisation for BroadcastTx on rpc/v0
+- [pull-476](https://github.com/eris-ltd/eris-db/pull/476) patch EXTCODESIZE for native contracts as solc ^v0.4 performs a safety check for non-zero contract code
+- [pull-468](https://github.com/eris-ltd/eris-db/pull/468) correct specifications for params on unsubscribe on rpc/tendermint
+- [pull-465](https://github.com/eris-ltd/eris-db/pull/465) fix divergence from JSON-RPC spec for Response object
+- [pull-366](https://github.com/eris-ltd/eris-db/pull/366) correction to circle ci script
+- [pull-379](https://github.com/eris-ltd/eris-db/pull/379) more descriptive error message for eris-client
+
+## v0.12.0
+This release marks the start of Eris-DB as the full permissioned blockchain node
+ of the Eris platform with the Tendermint permissioned consensus engine.
+ This involved significant refactoring of almost all parts of the code,
+ but provides a solid foundation to build the next generation of advanced
+ permissioned smart contract blockchains.
+
+ Many changes are under the hood but here are the main externally
+ visible changes:
+
+- Features and improvements
+  - Upgrade to Tendermint 0.6.0 in-process consensus
+  - Support DELEGATECALL opcode in Ethereum Virtual Machine (important for solidity library calls)
+  - ARM support
+  - Docker image size reduced
+  - Introduction of eris-client companion library for interacting with
+  eris:db
+  - Improved single configuration file for all components written by eris-cm
+  - Allow multiple event subscriptions from same host under rpc/tendermint
+
+
+- Tool changes  
+  - Use glide instead of godeps for dependencies
+
+
+- Testing
+  - integration tests over simulated RPC calls
+  - significantly improved unit tests
+  - the ethereum virtual machine and the consensus engine are now top-level
+  components and are exposed to continuous integration tests
+
+
+- Bugfixes (incomplete list)
+  - [EVM] Fix calculation of child CALL gaslimit (allowing solidity library calls to work properly)
+  - [RPC/v0] Fix blocking event subscription in transactAndHold (preventing return in Javascript libraries)
+  - [Blockchain] Fix getBlocks to respect block height cap
diff --git a/Dockerfile.armhf b/Dockerfile.armhf
index 1663f53ac126503e3b68aaad7f611f69e85f1ef1..9f8249d9f14c6386647a55eb62980863fd538e6f 100644
--- a/Dockerfile.armhf
+++ b/Dockerfile.armhf
@@ -1,6 +1,6 @@
 # Pull base image.
 FROM quay.io/eris/build:arm
-MAINTAINER Eris Industries <support@erisindustries.com>
+MAINTAINER Monax Industries <support@monax.io>
 
 # Expose ports for 1337:eris-db API; 46656:tendermint-peer; 46657:tendermint-rpc
 EXPOSE 1337
diff --git a/Dockerfile.deploy b/Dockerfile.deploy
index c264cef4a2d67273b3140331791a9a6e78d84ef2..dfe3b3e8a632a1c8af4c5590592202b60f7edaa4 100644
--- a/Dockerfile.deploy
+++ b/Dockerfile.deploy
@@ -3,13 +3,8 @@ MAINTAINER Monax <support@monax.io>
 
 ENV TARGET eris-db
 
-# runtime customization start here
-COPY ./eris-client $INSTALL_BASE/eris-client
-COPY ./bin/start_eris_db $INSTALL_BASE/erisdb-wrapper
-# runtime customization end here
-
-# Get the binary from the artifact in pwd
-COPY ./"$TARGET"_build_artifact $INSTALL_BASE/$TARGET
+# Get the binary from the artefact in pwd/target/docker
+COPY ./target/docker/"$TARGET".dockerartefact $INSTALL_BASE/$TARGET
 RUN chmod +x --recursive $INSTALL_BASE
 
 # Finalize
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..a05fe57e210c74affc132397a405f4cee63813fb
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,161 @@
+# ----------------------------------------------------------
+# REQUIREMENTS
+
+# - go installed locally
+# - for build_docker: docker installed locally
+
+# ----------------------------------------------------------
+
+SHELL := /bin/bash
+REPO := $(shell pwd)
+GOFILES_NOVENDOR := $(shell find ${REPO} -type f -name '*.go' -not -path "${REPO}/vendor/*")
+PACKAGES_NOVENDOR := $(shell go list github.com/eris-ltd/eris-db/... | grep -v /vendor/)
+VERSION := $(shell cat ${REPO}/version/version.go | tail -n 1 | cut -d \  -f 4 | tr -d '"')
+VERSION_MIN := $(shell echo ${VERSION} | cut -d . -f 1-2)
+COMMIT_SHA := $(shell echo `git rev-parse --short --verify HEAD`)
+
+DOCKER_NAMESPACE := quay.io/eris
+
+
+.PHONY: greet
+greet:
+	@echo "Hi! I'm the marmot that will help you with eris-db v${VERSION}"
+
+### Formatting, linting and vetting
+
+# check the code for style standards; currently enforces go formatting.
+# display output first, then check for success	
+.PHONY: check
+check:
+	@echo "Checking code for formatting style compliance."
+	@gofmt -l -d ${GOFILES_NOVENDOR}
+	@gofmt -l ${GOFILES_NOVENDOR} | read && echo && echo "Your marmot has found a problem with the formatting style of the code." 1>&2 && exit 1 || true
+
+# fmt runs gofmt -w on the code, modifying any files that do not match
+# the style guide.
+.PHONY: fmt
+fmt:
+	@echo "Correcting any formatting style corrections."
+	@gofmt -l -w ${GOFILES_NOVENDOR}
+
+# lint installs golint and prints recommendations for coding style.
+lint: 
+	@echo "Running lint checks."
+	go get -u github.com/golang/lint/golint
+	@for file in $(GOFILES_NOVENDOR); do \
+		echo; \
+		golint --set_exit_status $${file}; \
+	done
+
+# vet runs extended compilation checks to find recommendations for
+# suspicious code constructs.
+.PHONY: vet
+vet:
+	@echo "Running go vet."
+	@go vet ${PACKAGES_NOVENDOR}
+
+### Dependency management for github.com/eris-ltd/eris-db
+
+# erase vendor wipes the full vendor directory
+.PHONY: erase_vendor
+erase_vendor:
+	rm -rf ${REPO}/vendor/
+
+# install vendor uses glide to install vendored dependencies
+.PHONY: install_vendor
+install_vendor:
+	go get github.com/Masterminds/glide
+	glide install
+
+# hell runs utility tool hell to selectively update glide dependencies
+.PHONY: hell
+hell:
+	go build -o ${REPO}/target/hell ./util/hell/cmd/hell/main.go
+	./target/hell $(filter-out $@,$(MAKECMDGOALS))
+
+# Dumps Solidity interface contracts for SNatives
+.PHONY: snatives
+snatives:
+	@go run ./util/snatives/cmd/main.go
+
+### Building github.com/eris-ltd/eris-db
+
+# build all targets in github.com/eris-ltd/eris-db
+.PHONY: build
+build:	check build_db build_client build_keys
+
+# build all targets in github.com/eris-ltd/eris-db with checks for race conditions
+.PHONY: build_race
+build_race:	check build_race_db build_race_client build_race_keys
+
+# build eris-db
+.PHONY: build_db
+build_db:
+	go build -o ${REPO}/target/eris-db-${COMMIT_SHA} ./cmd/eris-db
+
+# build eris-client
+.PHONY: build_client
+build_client:
+	go build -o ${REPO}/target/eris-client-${COMMIT_SHA} ./client/cmd/eris-client
+
+# build eris-keys
+.PHONY: build_keys
+build_keys:
+	@echo "Marmots need to complete moving repository eris-keys into eris-db."
+
+# build eris-db with checks for race conditions
+.PHONY: build_race_db
+build_race_db:
+	go build -race -o ${REPO}/target/eris-db-${COMMIT_SHA} ./cmd/eris-db
+
+# build eris-client with checks for race conditions
+.PHONY: build_race_client
+build_race_client:
+	go build -race -o ${REPO}/target/eris-client-${COMMIT_SHA} ./client/cmd/eris-client
+
+# build eris-keys with checks for race conditions
+.PHONY: build_race_keys
+build_race_keys:
+	@echo "Marmots need to complete moving repository eris-keys into eris-db."
+
+### Testing github.com/eris-ltd/eris-db
+
+# test eris-db
+.PHONY: test
+test: build
+	@go test ${PACKAGES_NOVENDOR} -tags integration
+
+# test eris-db with checks for race conditions
+.PHONY: test_race
+test_race: build_race
+	@go test -race ${PACKAGES_NOVENDOR}
+
+### Build docker images for github.com/eris-ltd/eris-db
+
+# build docker image for eris-db
+.PHONY: build_docker_db
+build_docker_db: check
+	@mkdir -p ${REPO}/target/docker
+	docker build -t ${DOCKER_NAMESPACE}/db:build-${COMMIT_SHA} ${REPO}
+	docker run --rm --entrypoint cat ${DOCKER_NAMESPACE}/db:build-${COMMIT_SHA} /usr/local/bin/eris-db > ${REPO}/target/docker/eris-db.dockerartefact
+	docker run --rm --entrypoint cat ${DOCKER_NAMESPACE}/db:build-${COMMIT_SHA} /usr/local/bin/eris-client > ${REPO}/target/docker/eris-client.dockerartefact
+	docker build -t ${DOCKER_NAMESPACE}/db:${VERSION} -f Dockerfile.deploy ${REPO}
+
+	@rm ${REPO}/target/docker/eris-db.dockerartefact
+	@rm ${REPO}/target/docker/eris-client.dockerartefact
+	docker rmi ${DOCKER_NAMESPACE}/db:build-${COMMIT_SHA}
+
+### Test docker images for github.com/eris-ltd/eris-db
+
+# test docker image for eris-db
+.PHONY: test_docker_db
+test_docker_db: check
+	docker build -t ${DOCKER_NAMESPACE}/db:build-${COMMIT_SHA} ${REPO}
+	docker run ${DOCKER_NAMESPACE}/db:build-${COMMIT_SHA} glide nv | xargs go test -tags integration
+
+### Clean up
+
+# clean removes the target folder containing build artefacts
+.PHONY: clean
+clean:
+	-rm -r ./target 
\ No newline at end of file
diff --git a/README.md b/README.md
index 923114c13dbb4df8cd7dd83e704d3b8198d2faa7..10c36f2c0c5162a225aa65934561b18efafd6c98 100644
--- a/README.md
+++ b/README.md
@@ -1,48 +1,65 @@
-# Eris DB
+# Eris-DB v0.16
 
 |[![GoDoc](https://godoc.org/github.com/eris-db?status.png)](https://godoc.org/github.com/eris-ltd/eris-db) | Linux |
 |---|-------|
 | Master | [![Circle CI](https://circleci.com/gh/eris-ltd/eris-db/tree/master.svg?style=svg)](https://circleci.com/gh/eris-ltd/eris-db/tree/master) |
 | Develop | [![Circle CI (develop)](https://circleci.com/gh/eris-ltd/eris-db/tree/develop.svg?style=svg)](https://circleci.com/gh/eris-ltd/eris-db/tree/develop) |
 
-Eris DB is Eris' blockchain client. It includes a permissions layer, an implementation of the Ethereum Virtual Machine, and uses Tendermint Consensus. Most functionality is provided by `eris chains`, exposed through [eris-cli](https://monax.io/docs/documentation/cli), the entry point for the Eris Platform.
+Eris-db is Monax' permissioned blockchain client. It executes Ethereum smart contracts on a permissioned virtual machine. Eris-db provides transaction finality and high transaction throughput on proof-of-stake Tendermint consensus engine. For smart contract development most functionality is provided by `eris chains`, exposed through [eris](https://monax.io/docs/documentation/cli), the entry point for the Eris Platform.
 
 ## Table of Contents
 
-- [Background](#background)
+- [What is Eris-db](#what-is-eris-db)
 - [Installation](#installation)
+- [For developers](#for-developers)
 - [Usage](#usage)
-  - [Security](#security)
+- [Configuration](#configuration)
 - [Contribute](#contribute)
 - [License](#license)
+- [Future work](#future-work)
 
-## Background
+## What is Eris-db ?
+
+Eris-db is a permissioned blockchain node that executes smart contract code following the Ethereum specification.  Eris-db is built for a multi-chain universe with application specific optimization in mind. Eris-db as a node is constructed out of three main components; the consensus engine, the permissioned Ethereum virtual machine and the rpc gateway.  More specifically Eris-db consists of the following:
+
+- **Consensus Engine:** transactions are ordered and finalised with the Byzantine fault-tolerant Tendermint protocol.  The Tendermint protocol provides high transaction throughput over a set of known validators and prevents the blockchain from forking.
+- **Application Blockchain Interface (ABCI):** The smart contract application interfaces with the consensus engine over the ABCI. The ABCI allows for the consensus engine to remain agnostic from the smart contract application.
+- **Smart Contract Application:** transactions are validated and applied to the application state in the order that the consensus engine has finalised them.  The application state consists of all accounts, the validator set and the name registry. Accounts in eris-db have permissions and either contain smart contract code or correspond to a public-private key pair. A transaction that calls on the smart contract code in a given account will activate the execution of that account’s code in a permissioned virtual machine.
+- **Permissioned Ethereum Virtual Machine:** This virtual machine is built to observe the Ethereum operation code specification and additionally asserts the correct permissions have been granted. Permissioning is enforced through secure native functions and underlies all smart contract code. An arbitrary but finite amount of gas is handed out for every execution to ensure a finite execution duration - “You don’t need money to play, when you have permission to play”.
+- **Application Binary Interface (ABI):** transactions need to be formulated in a binary format that can be processed by the blockchain node.  Currently tooling provides functionality to compile, deploy and link solidity smart contracts and formulate transactions to call smart contracts on the chain.  For proof-of-concept purposes we provide a eris-contracts.js library that automatically mirrors the smart contracts deployed on the chain and to develop middleware solutions against the blockchain network.  Future work on the light client will be aware of the ABI to natively translate calls on the API into signed transactions that can be broadcast on the network.
+- **API Gateway:** eris-db exposes REST and JSON-RPC endpoints to interact with the blockchain network and the application state through broadcasting transactions, or querying the current state of the application. Websockets allow to subscribe to events, which is particularly valuable as the consensus engine and smart contract application can give unambiguously finalised results to transactions within one blocktime of about one second.
+
+Eris-db has been architected with a longer term vision on security and data privacy from the outset:
+
+- **Cryptographically Secured Consensus:** proof-of-stake Tendermint protocol achieves consensus over a known set of validators where every block is closed with cryptographic signatures from a majority of validators only.  No unknown variables come into play while reaching consensus on the network (as is the case for proof-of-work consensus). This guarantees that all actions on the network are fully cryptographically verified and traceable.
+- **Remote Signing:** transactions can be signed by elliptic curve cryptographic algorithms, either ed25519/sha512 or secp256k1/sha256 are currently supported. Eris-db connects to a remote signing solution to generate key pairs and request signatures. Eris-keys is a placeholder for a reverse proxy into your secure signing solution. This has always been the case for transaction formulation and work continues to enable remote signing for the validator block signatures too.
+- **Secure Signing:** Monax is a legal engineering company; we partner with expert companies to natively support secure signing solutions going forward.
+- **Multi-chain Universe (Step 1 of 3):** from the start the eris platform has been conceived for orchestrating many chains, as exemplified by the command “eris chains make” or by that transactions are only valid on the intended chain. Separating state into different chains is only the first of three steps towards privacy on smart contract chains (see future work below).
 
 See the [eris-db documentation](https://monax.io/docs/documentation/db/) for more information.
 
 ## Installation
 
-`eris-db` is intended to be used by the `eris chains` command via [eris-cli](https://monax.io/docs/documentation/cli/latest/eris_chains). Available commands such as `make | start | stop | logs | inspect | update` are used for chain lifecycle management.
+`eris-db` is intended to be used by the `eris chains` command via [eris](https://monax.io/docs/documentation/cli/latest/eris_chains). Available commands such as `make | start | stop | logs | inspect | update` are used for chain lifecycle management.
 
 ### For Developers
 Dependency management for eris-db is managed with [glide](github.com/Masterminds/glide), and you can build eris-db from source by following
 
-1. [Install go](https://golang.org/doc/install)
-2. Ensure you have `gmp` installed (`sudo apt-get install libgmp3-dev || brew install gmp`)
-3. and execute following commands in a terminal:
-```
-go get github.com/Masterminds/glide
-go get -d github.com/eris-ltd/eris-db
-REPO=$($GOPATH/src/github.com/eris-ltd/eris-db)
-cd $REPO && glide install
-cd $REPO/cmd/eris-db && go install
-```
+- [Install go](https://golang.org/doc/install)
+- Ensure you have `gmp` installed (`sudo apt-get install libgmp3-dev || brew install gmp`)
+- and execute following commands in a terminal:
+- `go get github.com/Masterminds/glide`
+- `go get -d github.com/eris-ltd/eris-db`
+- `REPO=$($GOPATH/src/github.com/eris-ltd/eris-db)`
+- `cd $REPO && glide install`
+- `cd $REPO/cmd/eris-db && go install`
 
 
-To run `eris-db`, just type `$ eris-db serve --work-dir <path to chain directory>`, where the chain directory needs to contain the configuration files as generated by `eris chains make`.
+To run `eris-db`, just type `$ eris-db serve --work-dir <path to chain directory>`, where the chain directory needs to contain the configuration, genesis file, and private validator file as generated by `eris chains make`.
 
-This will start the node using the provided folder as working dir. If the path is omitted it defaults to `~/.erisdb`
+This will start the node using the provided folder as working dir. If the path is omitted it defaults to `~/.erisdb`.
 
+For a Vagrant file see [eris-vagrant](https://github.com/eris-ltd/eris-vagrant) for drafts or soon this repo for [Vagrant](https://github.com/eris-ltd/eris-db/issues/514) and Packer files.
 
 ## Usage
 
@@ -54,8 +71,18 @@ A commented template config will be written as part of the `eris chains make` [p
 
 ## Contribute
 
-See the [eris platform contributing file here](https://github.com/eris-ltd/coding/blob/master/github/CONTRIBUTING.md).
+We welcome all contributions and have submitted the code base to the Hyperledger project governance during incubation phase.  As an integral part of this effort we want to invite new contributors, not just to maintain but also to steer the future direction of the code in an active and open process.
+
+You can find us on:
+- [the Marmot Den (slack)](http://slack.monax.io)
+- [here on Github](http://github.com/eris-ltd/eris-db/issues)
+- [support.monax.io](http://support.monax.io)
+- read the [Contributor file](.github/CONTRIBUTING.md)
+
+## Future work
+
+Some burrows marmots have already started digging to build the enterprise ecosystem applications of the future are listed in [docs/proposals](./docs/PROPOSALS.md).  Marmots live in groups we welcome your help on these or other improvement proposals. Please help us by joining the conversation on what features matter to you.
 
 ## License
 
-[GPL-3](license.md)
+[Apache 2.0](license.md)
diff --git a/account/account.go b/account/account.go
index 99b545f212a8c3be9322eecdf74fe6d8ad3b4f10..d2f80c97cea0f46799374491247d3fc39524fe42 100644
--- a/account/account.go
+++ b/account/account.go
@@ -1,32 +1,31 @@
-// Copyright 2015, 2016 Eris Industries (UK) Ltd.
-// This file is part of Eris-RT
+// 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.
 
-// Eris-RT is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-
-// Eris-RT is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License
-// along with Eris-RT.  If not, see <http://www.gnu.org/licenses/>.
+package account
 
 // TODO: [ben] Account and PrivateAccount need to become a pure interface
 // and then move the implementation to the manager types.
 // Eg, Geth has its accounts, different from ErisMint
 
-package account
-
 import (
 	"bytes"
 	"fmt"
 	"io"
 
+	"github.com/eris-ltd/eris-db/common/sanity"
 	ptypes "github.com/eris-ltd/eris-db/permission/types"
-	. "github.com/tendermint/go-common"
+
 	"github.com/tendermint/go-crypto"
 	"github.com/tendermint/go-wire"
 )
@@ -42,7 +41,7 @@ func SignBytes(chainID string, o Signable) []byte {
 	buf, n, err := new(bytes.Buffer), new(int), new(error)
 	o.WriteSignBytes(chainID, buf, n, err)
 	if *err != nil {
-		PanicCrisis(err)
+		sanity.PanicCrisis(err)
 	}
 
 	return buf.Bytes()
diff --git a/account/priv_account.go b/account/priv_account.go
index 52c0ab7710f40bb5708bb5b1cd4a44f413d76d58..6a738445b269ae6f1b511ce7c340ecae0ddb259c 100644
--- a/account/priv_account.go
+++ b/account/priv_account.go
@@ -1,28 +1,29 @@
-// Copyright 2015, 2016 Eris Industries (UK) Ltd.
-// This file is part of Eris-RT
+// 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.
 
-// Eris-RT is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-
-// Eris-RT is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License
-// along with Eris-RT.  If not, see <http://www.gnu.org/licenses/>.
+package account
 
 // TODO: [ben] Account and PrivateAccount need to become a pure interface
 // and then move the implementation to the manager types.
 // Eg, Geth has its accounts, different from ErisMint
 
-package account
-
 import (
+	"fmt"
+
+	"github.com/eris-ltd/eris-db/common/sanity"
+
 	"github.com/tendermint/ed25519"
-	. "github.com/tendermint/go-common"
 	"github.com/tendermint/go-crypto"
 	"github.com/tendermint/go-wire"
 )
@@ -49,7 +50,7 @@ func (pA *PrivAccount) Sign(chainID string, o Signable) crypto.Signature {
 }
 
 func (pA *PrivAccount) String() string {
-	return Fmt("PrivAccount{%X}", pA.Address)
+	return fmt.Sprintf("PrivAccount{%X}", pA.Address)
 }
 
 //----------------------------------------
@@ -90,7 +91,7 @@ func GenPrivAccountFromSecret(secret string) *PrivAccount {
 
 func GenPrivAccountFromPrivKeyBytes(privKeyBytes []byte) *PrivAccount {
 	if len(privKeyBytes) != 64 {
-		PanicSanity(Fmt("Expected 64 bytes but got %v", len(privKeyBytes)))
+		sanity.PanicSanity(fmt.Sprintf("Expected 64 bytes but got %v", len(privKeyBytes)))
 	}
 	var privKeyArray [64]byte
 	copy(privKeyArray[:], privKeyBytes)
diff --git a/blockchain/filter.go b/blockchain/filter.go
index 06743a64a9842c9f5eeae20780479016dc128ff9..26ff58d107ce903a02709820f41e795c2363f0e3 100644
--- a/blockchain/filter.go
+++ b/blockchain/filter.go
@@ -1,3 +1,17 @@
+// 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 blockchain
 
 import (
diff --git a/blockchain/types/blockchain.go b/blockchain/types/blockchain.go
index 80ef14dbcdba92607fa21faa159420ce3cd6d1e5..317e2a9f8680a4e4b4cff10420f098beb7d3c3bd 100644
--- a/blockchain/types/blockchain.go
+++ b/blockchain/types/blockchain.go
@@ -1,25 +1,23 @@
 // +build !arm
 
-// Copyright 2015, 2016 Eris Industries (UK) Ltd.
-// This file is part of Eris-RT
+// 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.
 
-// Eris-RT is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-
-// Eris-RT is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License
-// along with Eris-RT.  If not, see <http://www.gnu.org/licenses/>.
+package types
 
 // Blockchain is part of the pipe for ErisMint and provides the implementation
 // for the pipe to call into the ErisMint application
-package types
-
 type Blockchain interface {
 	BlockStore
 	ChainId() string
diff --git a/blockchain/types/blockstore.go b/blockchain/types/blockstore.go
index 41b426a4816978b8929edeb9ce7d60f018071b08..6c992e258a232e9dc52d88d9b970f65d6787596e 100644
--- a/blockchain/types/blockstore.go
+++ b/blockchain/types/blockstore.go
@@ -1,3 +1,17 @@
+// 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 types
 
 import tendermint_types "github.com/tendermint/tendermint/types"
diff --git a/circle.yml b/circle.yml
index f2cc9173abdedf6a000600d403a381bc9ab635fe..12e7160c86c7b8b536bceb55f01f0d5a63246c4b 100644
--- a/circle.yml
+++ b/circle.yml
@@ -55,6 +55,13 @@ deployment:
       - docker push quay.io/eris/db
       # push the updated documentation
       - docs/build.sh
+  develop:
+    branch: develop
+    commands:
+      - docker login -e $DOCKER_EMAIL -u $DOCKER_USER -p $DOCKER_PASS quay.io
+      # build docker image and tag the image with the version
+      - tests/build_tool.sh
+      - docker push quay.io/eris/db
   master:
     branch: master
     commands:
diff --git a/client/cmd/eris-client.go b/client/cmd/eris-client.go
index 57e8d3ba4b8f7da97c2dc4d8adae4711c02c1a15..681dc525b3dccfc7806f38e6de9bb256524934d7 100644
--- a/client/cmd/eris-client.go
+++ b/client/cmd/eris-client.go
@@ -1,18 +1,16 @@
-// Copyright 2015, 2016 Eris Industries (UK) Ltd.
-// This file is part of Eris-RT
-
-// Eris-RT is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-
-// Eris-RT is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License
-// along with Eris-RT.  If not, see <http://www.gnu.org/licenses/>.
+// 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
 
@@ -23,8 +21,6 @@ import (
 
 	"github.com/spf13/cobra"
 
-	log "github.com/eris-ltd/eris-logger"
-
 	"github.com/eris-ltd/eris-db/definitions"
 	"github.com/eris-ltd/eris-db/version"
 )
@@ -37,18 +33,10 @@ var ErisClientCmd = &cobra.Command{
 	Short: "Eris-client interacts with a running Eris chain.",
 	Long: `Eris-client interacts with a running Eris chain.
 
-Made with <3 by Eris Industries.
+Made with <3 by Monax Industries.
 
 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)
-		if clientDo.Verbose {
-			log.SetLevel(log.InfoLevel)
-		} else if clientDo.Debug {
-			log.SetLevel(log.DebugLevel)
-		}
-	},
 	Run: func(cmd *cobra.Command, args []string) { cmd.Help() },
 }
 
@@ -70,11 +58,12 @@ func AddGlobalFlags() {
 }
 
 func AddClientCommands() {
-	buildTransactionCommand()
-	ErisClientCmd.AddCommand(TransactionCmd)
+	ErisClientCmd.AddCommand(buildTransactionCommand())
+	ErisClientCmd.AddCommand(buildStatusCommand())
+
+	buildGenesisGenCommand()
+	ErisClientCmd.AddCommand(GenesisGenCmd)
 
-	buildStatusCommand()
-	ErisClientCmd.AddCommand(StatusCmd)
 }
 
 //------------------------------------------------------------------------------
diff --git a/client/cmd/eris-client/main.go b/client/cmd/eris-client/main.go
index 8219af99a32a54afdbeff73b10d13f88cf38f3a3..7dd05955cc42c71affe202f9ba9ece27d10919ac 100644
--- a/client/cmd/eris-client/main.go
+++ b/client/cmd/eris-client/main.go
@@ -1,18 +1,16 @@
-// Copyright 2015, 2016 Eris Industries (UK) Ltd.
-// This file is part of Eris-RT
-
-// Eris-RT is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-
-// Eris-RT is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License
-// along with Eris-RT.  If not, see <http://www.gnu.org/licenses/>.
+// 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
 
diff --git a/client/cmd/genesis.go b/client/cmd/genesis.go
new file mode 100644
index 0000000000000000000000000000000000000000..5b480e0818935ecf00d7991759fbbaabf3295a5b
--- /dev/null
+++ b/client/cmd/genesis.go
@@ -0,0 +1,54 @@
+// 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 (
+	"fmt"
+
+	"github.com/eris-ltd/eris-db/common/sanity"
+	"github.com/eris-ltd/eris-db/genesis"
+
+	"github.com/spf13/cobra"
+)
+
+// TODO refactor these vars into a struct?
+var (
+	AccountsPathFlag   string
+	ValidatorsPathFlag string
+)
+
+var GenesisGenCmd = &cobra.Command{
+	Use:   "make-genesis",
+	Short: "eris-client make-genesis creates a genesis.json with known inputs",
+	Long:  "eris-client make-genesis creates a genesis.json with known inputs",
+
+	Run: func(cmd *cobra.Command, args []string) {
+		// TODO refactor to not panic
+		genesisFile, err := genesis.GenerateKnown(args[0], AccountsPathFlag, ValidatorsPathFlag)
+		if err != nil {
+			sanity.PanicSanity(err)
+		}
+		fmt.Println(genesisFile) // may want to save somewhere instead
+	},
+}
+
+func buildGenesisGenCommand() {
+	addGenesisPersistentFlags()
+}
+
+func addGenesisPersistentFlags() {
+	GenesisGenCmd.Flags().StringVarP(&AccountsPathFlag, "accounts", "", "", "path to accounts.csv with the following params: (pubkey, starting balance, name, permissions, setbit")
+	GenesisGenCmd.Flags().StringVarP(&ValidatorsPathFlag, "validators", "", "", "path to validators.csv with the following params: (pubkey, starting balance, name, permissions, setbit")
+}
diff --git a/client/cmd/status.go b/client/cmd/status.go
index 5b29803d848fba681b028bcc0cae3cf969853968..4b5b11afb47105ca3aa506c5e4910ba2f4bacd29 100644
--- a/client/cmd/status.go
+++ b/client/cmd/status.go
@@ -1,18 +1,16 @@
-// Copyright 2015, 2016 Eris Industries (UK) Ltd.
-// This file is part of Eris-RT
-
-// Eris-RT is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-
-// Eris-RT is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License
-// along with Eris-RT.  If not, see <http://www.gnu.org/licenses/>.
+// 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
 
@@ -20,24 +18,23 @@ import (
 	"github.com/spf13/cobra"
 
 	"github.com/eris-ltd/eris-db/client/methods"
+	"github.com/eris-ltd/eris-db/util"
 )
 
-var StatusCmd = &cobra.Command{
-	Use:   "status",
-	Short: "eris-client status returns the current status from a chain.",
-	Long: `eris-client status returns the current status from a chain.
+func buildStatusCommand() *cobra.Command {
+	statusCmd := &cobra.Command{
+		Use:   "status",
+		Short: "eris-client status returns the current status from a chain.",
+		Long: `eris-client status returns the current status from a chain.
 `,
-	Run: func(cmd *cobra.Command, args []string) {
-		methods.Status(clientDo)
-	},
-}
-
-func buildStatusCommand() {
-	addStatusPersistentFlags()
-}
-
-func addStatusPersistentFlags() {
-	StatusCmd.PersistentFlags().StringVarP(&clientDo.NodeAddrFlag, "node-addr", "", defaultNodeRpcAddress(), "set the eris-db node rpc server address (default respects $ERIS_CLIENT_NODE_ADDRESS)")
+		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 eris-db node rpc server address (default respects $ERIS_CLIENT_NODE_ADDRESS)")
 	// TransactionCmd.PersistentFlags().StringVarP(&clientDo.PubkeyFlag, "pubkey", "", defaultPublicKey(), "specify the public key to sign with (defaults to $ERIS_CLIENT_PUBLIC_KEY)")
 	// TransactionCmd.PersistentFlags().StringVarP(&clientDo.AddrFlag, "addr", "", defaultAddress(), "specify the account address (for which the public key can be found at eris-keys) (default respects $ERIS_CLIENT_ADDRESS)")
 	// TransactionCmd.PersistentFlags().StringVarP(&clientDo.ChainidFlag, "chain-id", "", defaultChainId(), "specify the chainID (default respects $CHAIN_ID)")
@@ -46,4 +43,6 @@ func addStatusPersistentFlags() {
 	// // TransactionCmd.PersistentFlags().BoolVarP(&clientDo.SignFlag, "sign", "s", false, "sign the transaction using the eris-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
index 87a3e10c5ee99aeb84a97062280d98c4047d0016..28af969f90cde0adff6f2a73abfd3aed4bb62294 100644
--- a/client/cmd/transaction.go
+++ b/client/cmd/transaction.go
@@ -1,53 +1,50 @@
-// Copyright 2015, 2016 Eris Industries (UK) Ltd.
-// This file is part of Eris-RT
-
-// Eris-RT is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-
-// Eris-RT is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License
-// along with Eris-RT.  If not, see <http://www.gnu.org/licenses/>.
+// 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"
 	"strings"
 
 	"github.com/spf13/cobra"
 
-	log "github.com/eris-ltd/eris-logger"
-
-	"github.com/eris-ltd/eris-db/client/transaction"
+	"github.com/eris-ltd/eris-db/client/methods"
+	"github.com/eris-ltd/eris-db/util"
 )
 
-var TransactionCmd = &cobra.Command{
-	Use:   "tx",
-	Short: "eris-client tx formulates and signs a transaction to a chain",
-	Long: `eris-client tx formulates and signs a transaction to a chain.
-`,
-	Run: func(cmd *cobra.Command, args []string) { cmd.Help() },
-}
-
-func buildTransactionCommand() {
+func buildTransactionCommand() *cobra.Command {
 	// Transaction command has subcommands send, name, call, bond,
 	// unbond, rebond, permissions. Dupeout transaction is not accessible through the command line.
+	transactionCmd := &cobra.Command{
+		Use:   "tx",
+		Short: "eris-client tx formulates and signs a transaction to a chain",
+		Long:  "eris-client tx formulates and signs a transaction to a chain.",
+		Run:   func(cmd *cobra.Command, args []string) { cmd.Help() },
+	}
 
-	addTransactionPersistentFlags()
+	addTransactionPersistentFlags(transactionCmd)
 
 	// SendTx
-	var sendCmd = &cobra.Command{
+	sendCmd := &cobra.Command{
 		Use:   "send",
 		Short: "eris-client tx send --amt <amt> --to <addr>",
 		Long:  "eris-client tx send --amt <amt> --to <addr>",
 		Run: func(cmd *cobra.Command, args []string) {
-			transaction.Send(clientDo)
+			err := methods.Send(clientDo)
+			if err != nil {
+				util.Fatalf("Could not complete send: %s", err)
+			}
 		},
 		PreRun: assertParameters,
 	}
@@ -55,7 +52,7 @@ func buildTransactionCommand() {
 	sendCmd.Flags().StringVarP(&clientDo.ToFlag, "to", "t", "", "specify an address to send to")
 
 	// NameTx
-	var nameCmd = &cobra.Command{
+	nameCmd := &cobra.Command{
 		Use:   "name",
 		Short: "eris-client tx name --amt <amt> --name <name> --data <data>",
 		Long:  "eris-client tx name --amt <amt> --name <name> --data <data>",
@@ -71,12 +68,15 @@ func buildTransactionCommand() {
 	nameCmd.Flags().StringVarP(&clientDo.FeeFlag, "fee", "f", "", "specify the fee to send")
 
 	// CallTx
-	var callCmd = &cobra.Command{
+	callCmd := &cobra.Command{
 		Use:   "call",
 		Short: "eris-client tx call --amt <amt> --fee <fee> --gas <gas> --to <contract addr> --data <data>",
 		Long:  "eris-client tx call --amt <amt> --fee <fee> --gas <gas> --to <contract addr> --data <data>",
 		Run: func(cmd *cobra.Command, args []string) {
-			transaction.Call(clientDo)
+			err := methods.Call(clientDo)
+			if err != nil {
+				util.Fatalf("Could not complete call: %s", err)
+			}
 		},
 		PreRun: assertParameters,
 	}
@@ -87,7 +87,7 @@ func buildTransactionCommand() {
 	callCmd.Flags().StringVarP(&clientDo.GasFlag, "gas", "g", "", "specify the gas limit for a CallTx")
 
 	// BondTx
-	var bondCmd = &cobra.Command{
+	bondCmd := &cobra.Command{
 		Use:   "bond",
 		Short: "eris-client tx bond --pubkey <pubkey> --amt <amt> --unbond-to <address>",
 		Long:  "eris-client tx bond --pubkey <pubkey> --amt <amt> --unbond-to <address>",
@@ -100,7 +100,7 @@ func buildTransactionCommand() {
 	bondCmd.Flags().StringVarP(&clientDo.UnbondtoFlag, "to", "t", "", "specify an address to unbond to")
 
 	// UnbondTx
-	var unbondCmd = &cobra.Command{
+	unbondCmd := &cobra.Command{
 		Use:   "unbond",
 		Short: "eris-client tx unbond --addr <address> --height <block_height>",
 		Long:  "eris-client tx unbond --addr <address> --height <block_height>",
@@ -126,7 +126,7 @@ func buildTransactionCommand() {
 	rebondCmd.Flags().StringVarP(&clientDo.HeightFlag, "height", "n", "", "specify a height to unbond at")
 
 	// PermissionsTx
-	var permissionsCmd = &cobra.Command{
+	permissionsCmd := &cobra.Command{
 		Use:   "permission",
 		Short: "eris-client tx perm <function name> <args ...>",
 		Long:  "eris-client tx perm <function name> <args ...>",
@@ -136,20 +136,21 @@ func buildTransactionCommand() {
 		PreRun: assertParameters,
 	}
 
-	TransactionCmd.AddCommand(sendCmd, nameCmd, callCmd, bondCmd, unbondCmd, rebondCmd, permissionsCmd)
+	transactionCmd.AddCommand(sendCmd, nameCmd, callCmd, bondCmd, unbondCmd, rebondCmd, permissionsCmd)
+	return transactionCmd
 }
 
-func addTransactionPersistentFlags() {
-	TransactionCmd.PersistentFlags().StringVarP(&clientDo.SignAddrFlag, "sign-addr", "", defaultKeyDaemonAddress(), "set eris-keys daemon address (default respects $ERIS_CLIENT_SIGN_ADDRESS)")
-	TransactionCmd.PersistentFlags().StringVarP(&clientDo.NodeAddrFlag, "node-addr", "", defaultNodeRpcAddress(), "set the eris-db node rpc server address (default respects $ERIS_CLIENT_NODE_ADDRESS)")
-	TransactionCmd.PersistentFlags().StringVarP(&clientDo.PubkeyFlag, "pubkey", "", defaultPublicKey(), "specify the public key to sign with (defaults to $ERIS_CLIENT_PUBLIC_KEY)")
-	TransactionCmd.PersistentFlags().StringVarP(&clientDo.AddrFlag, "addr", "", defaultAddress(), "specify the account address (for which the public key can be found at eris-keys) (default respects $ERIS_CLIENT_ADDRESS)")
-	TransactionCmd.PersistentFlags().StringVarP(&clientDo.ChainidFlag, "chain-id", "", defaultChainId(), "specify the chainID (default respects $CHAIN_ID)")
-	TransactionCmd.PersistentFlags().StringVarP(&clientDo.NonceFlag, "nonce", "", "", "specify the nonce to use for the transaction (should equal the sender account's nonce + 1)")
-
-	// TransactionCmd.PersistentFlags().BoolVarP(&clientDo.SignFlag, "sign", "s", false, "sign the transaction using the eris-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")
+func addTransactionPersistentFlags(transactionCmd *cobra.Command) {
+	transactionCmd.PersistentFlags().StringVarP(&clientDo.SignAddrFlag, "sign-addr", "", defaultKeyDaemonAddress(), "set eris-keys daemon address (default respects $ERIS_CLIENT_SIGN_ADDRESS)")
+	transactionCmd.PersistentFlags().StringVarP(&clientDo.NodeAddrFlag, "node-addr", "", defaultNodeRpcAddress(), "set the eris-db node rpc server address (default respects $ERIS_CLIENT_NODE_ADDRESS)")
+	transactionCmd.PersistentFlags().StringVarP(&clientDo.PubkeyFlag, "pubkey", "", defaultPublicKey(), "specify the public key to sign with (defaults to $ERIS_CLIENT_PUBLIC_KEY)")
+	transactionCmd.PersistentFlags().StringVarP(&clientDo.AddrFlag, "addr", "", defaultAddress(), "specify the account address (for which the public key can be found at eris-keys) (default respects $ERIS_CLIENT_ADDRESS)")
+	transactionCmd.PersistentFlags().StringVarP(&clientDo.ChainidFlag, "chain-id", "", defaultChainId(), "specify the chainID (default respects $CHAIN_ID)")
+	transactionCmd.PersistentFlags().StringVarP(&clientDo.NonceFlag, "nonce", "", "", "specify the nonce to use for the transaction (should equal the sender account's nonce + 1)")
+
+	// transactionCmd.PersistentFlags().BoolVarP(&clientDo.SignFlag, "sign", "s", false, "sign the transaction using the eris-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")
 }
 
 //------------------------------------------------------------------------------
@@ -180,26 +181,21 @@ func defaultAddress() string {
 
 func assertParameters(cmd *cobra.Command, args []string) {
 	if clientDo.ChainidFlag == "" {
-		log.Fatal(`Please provide a chain id either through the flag --chain-id or environment variable $CHAIN_ID.`)
-		os.Exit(1)
+		util.Fatalf(`Please provide a chain id either through the flag --chain-id or environment variable $CHAIN_ID.`)
 	}
 
 	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;
-		log.Warn(`Please use fully formed listening address for the node, including the tcp:// or unix:// prefix.`)
+		// 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
-		log.WithFields(log.Fields{
-			"signing address": clientDo.SignAddrFlag,
-		}).Warn(`Please use fully formed listening address for the key server; adding http:// prefix`)
 	}
-	log.WithFields(log.Fields{
-		"signing address": clientDo.SignAddrFlag,
-		"node address":    clientDo.NodeAddrFlag,
-		"chain id":        clientDo.ChainidFlag,
-	}).Debug("Asserted parameters")
 }
diff --git a/client/methods/call.go b/client/methods/call.go
new file mode 100644
index 0000000000000000000000000000000000000000..86c793983fdde5b09b685fd3b939c71d7ad59932
--- /dev/null
+++ b/client/methods/call.go
@@ -0,0 +1,53 @@
+// 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/eris-ltd/eris-db/client"
+	"github.com/eris-ltd/eris-db/client/rpc"
+	"github.com/eris-ltd/eris-db/definitions"
+	"github.com/eris-ltd/eris-db/keys"
+)
+
+func Call(do *definitions.ClientDo) 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 ClientDo: %s", err)
+	}
+	erisKeyClient := keys.NewErisKeyClient(do.SignAddrFlag, logger)
+	erisNodeClient := client.NewErisNodeClient(do.NodeAddrFlag, logger)
+	// form the call transaction
+	callTransaction, err := rpc.Call(erisNodeClient, erisKeyClient,
+		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)
+	}
+	// 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(do.ChainidFlag, erisNodeClient, erisKeyClient,
+		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
new file mode 100644
index 0000000000000000000000000000000000000000..a97c92c104bdf3ee08f1d3d99c9d7c281eb21b36
--- /dev/null
+++ b/client/methods/helpers.go
@@ -0,0 +1,54 @@
+// 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/eris-ltd/eris-db/client/rpc"
+	"github.com/eris-ltd/eris-db/core"
+	"github.com/eris-ltd/eris-db/definitions"
+	"github.com/eris-ltd/eris-db/logging"
+	"github.com/eris-ltd/eris-db/logging/lifecycle"
+	"github.com/eris-ltd/eris-db/logging/loggers"
+)
+
+func unpackSignAndBroadcast(result *rpc.TxResult, logger loggers.InfoTraceLogger) {
+	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,
+		)
+	}
+
+	logging.InfoMsg(logger, "SignAndBroadcast result")
+}
+
+func loggerFromClientDo(do *definitions.ClientDo, scope string) (loggers.InfoTraceLogger, error) {
+	lc, err := core.LoadLoggingConfigFromClientDo(do)
+	if err != nil {
+		return nil, err
+	}
+	return logging.WithScope(lifecycle.NewLoggerFromLoggingConfig(lc), scope), nil
+}
diff --git a/client/methods/send.go b/client/methods/send.go
new file mode 100644
index 0000000000000000000000000000000000000000..8fa10230200098111a282e43696c591118c93e8b
--- /dev/null
+++ b/client/methods/send.go
@@ -0,0 +1,51 @@
+// 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/eris-ltd/eris-db/client"
+	"github.com/eris-ltd/eris-db/client/rpc"
+	"github.com/eris-ltd/eris-db/definitions"
+	"github.com/eris-ltd/eris-db/keys"
+)
+
+func Send(do *definitions.ClientDo) 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 ClientDo: %s", err)
+	}
+	erisKeyClient := keys.NewErisKeyClient(do.SignAddrFlag, logger)
+	erisNodeClient := client.NewErisNodeClient(do.NodeAddrFlag, logger)
+	// form the send transaction
+	sendTransaction, err := rpc.Send(erisNodeClient, erisKeyClient,
+		do.PubkeyFlag, do.AddrFlag, do.ToFlag, do.AmtFlag, do.NonceFlag)
+	if err != nil {
+		fmt.Errorf("Failed on forming Send Transaction: %s", 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(do.ChainidFlag, erisNodeClient, erisKeyClient,
+		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
index ba2470e7645ba0759445daed1042211c8f184401..f1fb6348495fa962818d8d4dd27e1dab20fe0167 100644
--- a/client/methods/status.go
+++ b/client/methods/status.go
@@ -1,53 +1,51 @@
-// Copyright 2015, 2016 Eris Industries (UK) Ltd.
-// This file is part of Eris-RT
-
-// Eris-RT is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-
-// Eris-RT is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License
-// along with Eris-RT.  If not, see <http://www.gnu.org/licenses/>.
+// 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"
 
-	log "github.com/eris-ltd/eris-logger"
-
 	"github.com/eris-ltd/eris-db/client"
 	"github.com/eris-ltd/eris-db/definitions"
 )
 
-func Status(do *definitions.ClientDo) {
-	erisNodeClient := client.NewErisNodeClient(do.NodeAddrFlag)
+func Status(do *definitions.ClientDo) error {
+	logger, err := loggerFromClientDo(do, "Status")
+	if err != nil {
+		return fmt.Errorf("Could not generate logging config from ClientDo: %s", err)
+	}
+	erisNodeClient := client.NewErisNodeClient(do.NodeAddrFlag, logger)
 	genesisHash, validatorPublicKey, latestBlockHash, latestBlockHeight, latestBlockTime, err := erisNodeClient.Status()
 	if err != nil {
-		log.Errorf("Error requesting status from chain at (%s): %s", do.NodeAddrFlag, err)
-		return
+		return fmt.Errorf("Error requesting status from chain at (%s): %s", do.NodeAddrFlag, err)
 	}
 
 	chainName, chainId, genesisHashfromChainId, err := erisNodeClient.ChainId()
 	if err != nil {
-		log.Errorf("Error requesting chainId from chain at (%s): %s", do.NodeAddrFlag, err)
-		return
+		return fmt.Errorf("Error requesting chainId from chain at (%s): %s", do.NodeAddrFlag, err)
 	}
 
-	log.WithFields(log.Fields{
-		"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,
-	}).Info("status")
+	logger.Info("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
index 12cdd76cf9b15f9575898224889a1528eb8a58b7..f1e80895ff184f0f39ffd9dec3d5004d83afc852 100644
--- a/client/mock/client_mock.go
+++ b/client/mock/client_mock.go
@@ -1,18 +1,16 @@
-// Copyright 2015, 2016 Eris Industries (UK) Ltd.
-// This file is part of Eris-RT
-
-// Eris-RT is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-
-// Eris-RT is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License
-// along with Eris-RT.  If not, see <http://www.gnu.org/licenses/>.
+// 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
 
@@ -23,6 +21,7 @@ import (
 	. "github.com/eris-ltd/eris-db/client"
 	consensus_types "github.com/eris-ltd/eris-db/consensus/types"
 	core_types "github.com/eris-ltd/eris-db/core/types"
+	"github.com/eris-ltd/eris-db/logging/loggers"
 	"github.com/eris-ltd/eris-db/txs"
 )
 
@@ -117,3 +116,7 @@ func (mock *MockNodeClient) GetName(name string) (owner []byte, data string, exp
 func (mock *MockNodeClient) ListValidators() (blockHeight int, bondedValidators, unbondingValidators []consensus_types.Validator, err error) {
 	return 0, nil, nil, nil
 }
+
+func (mock *MockNodeClient) Logger() loggers.InfoTraceLogger {
+	return loggers.NewNoopInfoTraceLogger()
+}
diff --git a/client/client.go b/client/node_client.go
similarity index 79%
rename from client/client.go
rename to client/node_client.go
index 24eeb0338629fdbaae0aa28367a074e436e1d415..56dd425e22498741cb6efae6c6e381111a20e24d 100644
--- a/client/client.go
+++ b/client/node_client.go
@@ -1,18 +1,16 @@
-// Copyright 2015, 2016 Eris Industries (UK) Ltd.
-// This file is part of Eris-RT
-
-// Eris-RT is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-
-// Eris-RT is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License
-// along with Eris-RT.  If not, see <http://www.gnu.org/licenses/>.
+// 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
 
@@ -21,18 +19,16 @@ import (
 	// "strings"
 
 	"github.com/tendermint/go-rpc/client"
-	// Note [ben]: this is included to silence the logger from tendermint/go-rpc/client
-	// see func init()
-	tendermint_log "github.com/tendermint/log15"
-
-	log "github.com/eris-ltd/eris-logger"
 
 	acc "github.com/eris-ltd/eris-db/account"
 	consensus_types "github.com/eris-ltd/eris-db/consensus/types"
 	core_types "github.com/eris-ltd/eris-db/core/types"
+	"github.com/eris-ltd/eris-db/logging"
+	"github.com/eris-ltd/eris-db/logging/loggers"
 	tendermint_client "github.com/eris-ltd/eris-db/rpc/tendermint/client"
 	tendermint_types "github.com/eris-ltd/eris-db/rpc/tendermint/core/types"
 	"github.com/eris-ltd/eris-db/txs"
+	tmLog15 "github.com/tendermint/log15"
 )
 
 type NodeClient interface {
@@ -48,6 +44,9 @@ type NodeClient interface {
 	DumpStorage(address []byte) (storage *core_types.Storage, err error)
 	GetName(name string) (owner []byte, data string, expirationBlock int, err error)
 	ListValidators() (blockHeight int, bondedValidators, unbondingValidators []consensus_types.Validator, err error)
+
+	// Logging context for this NodeClient
+	Logger() loggers.InfoTraceLogger
 }
 
 type NodeWebsocketClient interface {
@@ -58,29 +57,30 @@ type NodeWebsocketClient interface {
 	Close()
 }
 
-// NOTE [ben] Compiler check to ensure ErisNodeClient successfully implements
+// NOTE [ben] Compiler check to ensure erisNodeClient successfully implements
 // eris-db/client.NodeClient
-var _ NodeClient = (*ErisNodeClient)(nil)
+var _ NodeClient = (*erisNodeClient)(nil)
 
 // Eris-Client is a simple struct exposing the client rpc methods
-
-type ErisNodeClient struct {
+type erisNodeClient struct {
 	broadcastRPC string
+	logger       loggers.InfoTraceLogger
 }
 
 // ErisKeyClient.New returns a new eris-keys client for provided rpc location
 // Eris-keys connects over http request-responses
-func NewErisNodeClient(rpcString string) *ErisNodeClient {
-	return &ErisNodeClient{
+func NewErisNodeClient(rpcString string, logger loggers.InfoTraceLogger) *erisNodeClient {
+	return &erisNodeClient{
 		broadcastRPC: rpcString,
+		logger:       logging.WithScope(logger, "ErisNodeClient"),
 	}
 }
 
 // Note [Ben]: This is a hack to silence Tendermint logger from tendermint/go-rpc
 // it needs to be initialised before go-rpc, hence it's placement here.
 func init() {
-	h := tendermint_log.LvlFilterHandler(tendermint_log.LvlWarn, tendermint_log.StdoutHandler)
-    tendermint_log.Root().SetHandler(h)
+	h := tmLog15.LvlFilterHandler(tmLog15.LvlWarn, tmLog15.StdoutHandler)
+	tmLog15.Root().SetHandler(h)
 }
 
 //------------------------------------------------------------------------------------
@@ -88,7 +88,7 @@ func init() {
 // NOTE: [ben] Eris Client first continues from tendermint rpc, but will have handshake to negotiate
 // protocol version for moving towards rpc/v1
 
-func (erisNodeClient *ErisNodeClient) Broadcast(tx txs.Tx) (*txs.Receipt, error) {
+func (erisNodeClient *erisNodeClient) Broadcast(tx txs.Tx) (*txs.Receipt, error) {
 	client := rpcclient.NewClientURI(erisNodeClient.broadcastRPC)
 	receipt, err := tendermint_client.BroadcastTx(client, tx)
 	if err != nil {
@@ -97,7 +97,7 @@ func (erisNodeClient *ErisNodeClient) Broadcast(tx txs.Tx) (*txs.Receipt, error)
 	return &receipt, nil
 }
 
-func (erisNodeClient *ErisNodeClient) DeriveWebsocketClient() (nodeWsClient NodeWebsocketClient, err error) {
+func (erisNodeClient *erisNodeClient) DeriveWebsocketClient() (nodeWsClient NodeWebsocketClient, err error) {
 	var wsAddr string
 	// TODO: clean up this inherited mess on dealing with the address prefixes.
 	nodeAddr := erisNodeClient.broadcastRPC
@@ -115,16 +115,17 @@ func (erisNodeClient *ErisNodeClient) DeriveWebsocketClient() (nodeWsClient Node
 	// }
 	// wsAddr = "ws://" + wsAddr
 	wsAddr = nodeAddr
-	log.WithFields(log.Fields{
-		"websocket address": wsAddr,
-		"endpoint":          "/websocket",
-	}).Debug("Subscribing to websocket address")
+	logging.TraceMsg(erisNodeClient.logger, "Subscribing to websocket address",
+		"websocket address", wsAddr,
+		"endpoint", "/websocket",
+	)
 	wsClient := rpcclient.NewWSClient(wsAddr, "/websocket")
 	if _, err = wsClient.Start(); err != nil {
 		return nil, err
 	}
-	derivedErisNodeWebsocketClient := &ErisNodeWebsocketClient{
+	derivedErisNodeWebsocketClient := &erisNodeWebsocketClient{
 		tendermintWebsocket: wsClient,
+		logger:              logging.WithScope(erisNodeClient.logger, "ErisNodeWebsocketClient"),
 	}
 	return derivedErisNodeWebsocketClient, nil
 }
@@ -134,7 +135,7 @@ func (erisNodeClient *ErisNodeClient) DeriveWebsocketClient() (nodeWsClient Node
 
 // Status returns the ChainId (GenesisHash), validator's PublicKey, latest block hash
 // the block height and the latest block time.
-func (erisNodeClient *ErisNodeClient) Status() (GenesisHash []byte, ValidatorPublicKey []byte, LatestBlockHash []byte, LatestBlockHeight int, LatestBlockTime int64, err error) {
+func (erisNodeClient *erisNodeClient) Status() (GenesisHash []byte, ValidatorPublicKey []byte, LatestBlockHash []byte, LatestBlockHeight int, LatestBlockTime int64, err error) {
 	client := rpcclient.NewClientJSONRPC(erisNodeClient.broadcastRPC)
 	res, err := tendermint_client.Status(client)
 	if err != nil {
@@ -152,7 +153,7 @@ func (erisNodeClient *ErisNodeClient) Status() (GenesisHash []byte, ValidatorPub
 	return
 }
 
-func (erisNodeClient *ErisNodeClient) ChainId() (ChainName, ChainId string, GenesisHash []byte, err error) {
+func (erisNodeClient *erisNodeClient) ChainId() (ChainName, ChainId string, GenesisHash []byte, err error) {
 	client := rpcclient.NewClientJSONRPC(erisNodeClient.broadcastRPC)
 	chainIdResult, err := tendermint_client.ChainId(client)
 	if err != nil {
@@ -170,7 +171,7 @@ func (erisNodeClient *ErisNodeClient) ChainId() (ChainName, ChainId string, Gene
 
 // QueryContract executes the contract code at address with the given data
 // NOTE: there is no check on the caller;
-func (erisNodeClient *ErisNodeClient) QueryContract(callerAddress, calleeAddress, data []byte) (ret []byte, gasUsed int64, err error) {
+func (erisNodeClient *erisNodeClient) QueryContract(callerAddress, calleeAddress, data []byte) (ret []byte, gasUsed int64, err error) {
 	client := rpcclient.NewClientJSONRPC(erisNodeClient.broadcastRPC)
 	callResult, err := tendermint_client.Call(client, callerAddress, calleeAddress, data)
 	if err != nil {
@@ -182,7 +183,7 @@ func (erisNodeClient *ErisNodeClient) QueryContract(callerAddress, calleeAddress
 }
 
 // QueryContractCode executes the contract code at address with the given data but with provided code
-func (erisNodeClient *ErisNodeClient) QueryContractCode(address, code, data []byte) (ret []byte, gasUsed int64, err error) {
+func (erisNodeClient *erisNodeClient) QueryContractCode(address, code, data []byte) (ret []byte, gasUsed int64, err error) {
 	client := rpcclient.NewClientJSONRPC(erisNodeClient.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.
@@ -196,7 +197,7 @@ func (erisNodeClient *ErisNodeClient) QueryContractCode(address, code, data []by
 }
 
 // GetAccount returns a copy of the account
-func (erisNodeClient *ErisNodeClient) GetAccount(address []byte) (*acc.Account, error) {
+func (erisNodeClient *erisNodeClient) GetAccount(address []byte) (*acc.Account, error) {
 	client := rpcclient.NewClientJSONRPC(erisNodeClient.broadcastRPC)
 	account, err := tendermint_client.GetAccount(client, address)
 	if err != nil {
@@ -213,7 +214,7 @@ func (erisNodeClient *ErisNodeClient) GetAccount(address []byte) (*acc.Account,
 }
 
 // DumpStorage returns the full storage for an account.
-func (erisNodeClient *ErisNodeClient) DumpStorage(address []byte) (storage *core_types.Storage, err error) {
+func (erisNodeClient *erisNodeClient) DumpStorage(address []byte) (storage *core_types.Storage, err error) {
 	client := rpcclient.NewClientJSONRPC(erisNodeClient.broadcastRPC)
 	resultStorage, err := tendermint_client.DumpStorage(client, address)
 	if err != nil {
@@ -231,7 +232,7 @@ func (erisNodeClient *ErisNodeClient) DumpStorage(address []byte) (storage *core
 //--------------------------------------------------------------------------------------------
 // Name registry
 
-func (erisNodeClient *ErisNodeClient) GetName(name string) (owner []byte, data string, expirationBlock int, err error) {
+func (erisNodeClient *erisNodeClient) GetName(name string) (owner []byte, data string, expirationBlock int, err error) {
 	client := rpcclient.NewClientJSONRPC(erisNodeClient.broadcastRPC)
 	entryResult, err := tendermint_client.GetName(client, name)
 	if err != nil {
@@ -248,7 +249,7 @@ func (erisNodeClient *ErisNodeClient) GetName(name string) (owner []byte, data s
 
 //--------------------------------------------------------------------------------------------
 
-func (erisNodeClient *ErisNodeClient) ListValidators() (blockHeight int,
+func (erisNodeClient *erisNodeClient) ListValidators() (blockHeight int,
 	bondedValidators []consensus_types.Validator, unbondingValidators []consensus_types.Validator, err error) {
 	client := rpcclient.NewClientJSONRPC(erisNodeClient.broadcastRPC)
 	validatorsResult, err := tendermint_client.ListValidators(client)
@@ -263,3 +264,7 @@ func (erisNodeClient *ErisNodeClient) ListValidators() (blockHeight int,
 	unbondingValidators = validatorsResult.UnbondingValidators
 	return
 }
+
+func (erisNodeClient *erisNodeClient) Logger() loggers.InfoTraceLogger {
+	return erisNodeClient.logger
+}
diff --git a/client/core/transaction_factory.go b/client/rpc/client.go
similarity index 81%
rename from client/core/transaction_factory.go
rename to client/rpc/client.go
index 569e1d8a2cd3fb5131ca42f9c96d4e6a5633a613..d82a5f9448065f970525b5624ac969b1da8bd4ad 100644
--- a/client/core/transaction_factory.go
+++ b/client/rpc/client.go
@@ -1,40 +1,31 @@
-// Copyright 2015, 2016 Eris Industries (UK) Ltd.
-// This file is part of Eris-RT
-
-// Eris-RT is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-
-// Eris-RT is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License
-// along with Eris-RT.  If not, see <http://www.gnu.org/licenses/>.
-
-package core
+// 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"
 
-	log "github.com/eris-ltd/eris-logger"
-
 	ptypes "github.com/eris-ltd/eris-db/permission/types"
 
-	"github.com/eris-ltd/eris-db/account"
 	"github.com/eris-ltd/eris-db/client"
 	"github.com/eris-ltd/eris-db/keys"
 	"github.com/eris-ltd/eris-db/txs"
 )
 
-var (
-	MaxCommitWaitTimeSeconds = 20
-)
-
 //------------------------------------------------------------------------------------
 // core functions with string args.
 // validates strings and forms transaction
@@ -106,19 +97,6 @@ func Name(nodeClient client.NodeClient, keyClient keys.KeyClient, pubkey, addr,
 	return tx, nil
 }
 
-type PermFunc struct {
-	Name string
-	Args string
-}
-
-var PermsFuncs = []PermFunc{
-	{"set_base", "address, permission flag, value"},
-	{"unset_base", "address, permission flag"},
-	{"set_global", "permission flag, value"},
-	{"add_role", "address, role"},
-	{"rm_role", "address, role"},
-}
-
 func Permissions(nodeClient client.NodeClient, keyClient keys.KeyClient, pubkey, addrS, nonceS, permFunc string, argsS []string) (*txs.PermissionsTx, error) {
 	pub, _, nonce, err := checkCommon(nodeClient, keyClient, pubkey, addrS, "0", nonceS)
 	if err != nil {
@@ -126,13 +104,13 @@ func Permissions(nodeClient client.NodeClient, keyClient keys.KeyClient, pubkey,
 	}
 	var args ptypes.PermArgs
 	switch permFunc {
-	case "set_base":
+	case "setBase":
 		addr, pF, err := decodeAddressPermFlag(argsS[0], argsS[1])
 		if err != nil {
 			return nil, err
 		}
 		if len(argsS) != 3 {
-			return nil, fmt.Errorf("set_base also takes a value (true or false)")
+			return nil, fmt.Errorf("setBase also takes a value (true or false)")
 		}
 		var value bool
 		if argsS[2] == "true" {
@@ -143,13 +121,13 @@ func Permissions(nodeClient client.NodeClient, keyClient keys.KeyClient, pubkey,
 			return nil, fmt.Errorf("Unknown value %s", argsS[2])
 		}
 		args = &ptypes.SetBaseArgs{addr, pF, value}
-	case "unset_base":
+	case "unsetBase":
 		addr, pF, err := decodeAddressPermFlag(argsS[0], argsS[1])
 		if err != nil {
 			return nil, err
 		}
 		args = &ptypes.UnsetBaseArgs{addr, pF}
-	case "set_global":
+	case "setGlobal":
 		pF, err := ptypes.PermStringToFlag(argsS[0])
 		if err != nil {
 			return nil, err
@@ -163,13 +141,13 @@ func Permissions(nodeClient client.NodeClient, keyClient keys.KeyClient, pubkey,
 			return nil, fmt.Errorf("Unknown value %s", argsS[1])
 		}
 		args = &ptypes.SetGlobalArgs{pF, value}
-	case "add_role":
+	case "addRole":
 		addr, err := hex.DecodeString(argsS[0])
 		if err != nil {
 			return nil, err
 		}
 		args = &ptypes.AddRoleArgs{addr, argsS[1]}
-	case "rm_role":
+	case "removeRole":
 		addr, err := hex.DecodeString(argsS[0])
 		if err != nil {
 			return nil, err
@@ -272,16 +250,14 @@ type TxResult struct {
 }
 
 // Preserve
-func SignAndBroadcast(chainID string, nodeClient client.NodeClient, keyClient keys.KeyClient, tx txs.Tx, sign, broadcast, wait bool) (txResult *TxResult, err error) {
+func SignAndBroadcast(chainID string, nodeClient client.NodeClient, keyClient keys.KeyClient, tx txs.Tx, sign,
+	broadcast, wait bool) (txResult *TxResult, err error) {
 	var inputAddr []byte
 	if sign {
 		inputAddr, tx, err = signTx(keyClient, chainID, tx)
 		if err != nil {
 			return nil, err
 		}
-		log.WithFields(log.Fields{
-			"transaction": string(account.SignBytes(chainID, tx)),
-		}).Debug("Signed transaction")
 	}
 
 	if broadcast {
@@ -300,23 +276,19 @@ func SignAndBroadcast(chainID string, nodeClient client.NodeClient, keyClient ke
 						// if broadcast threw an error, just return
 						return
 					}
-					log.Debug("Waiting for transaction to be confirmed.")
 					confirmation := <-confirmationChannel
 					if confirmation.Error != nil {
-						log.Errorf("Encountered error waiting for event: %s\n", confirmation.Error)
-						err = confirmation.Error
+						err = fmt.Errorf("Encountered error waiting for event: %s", confirmation.Error)
 						return
 					}
 					if confirmation.Exception != nil {
-						log.Errorf("Encountered Exception from chain: %s\n", confirmation.Exception)
-						err = confirmation.Exception
+						err = fmt.Errorf("Encountered Exception from chain: %s", confirmation.Exception)
 						return
 					}
 					txResult.BlockHash = confirmation.BlockHash
 					txResult.Exception = ""
 					eventDataTx, ok := confirmation.Event.(*txs.EventDataTx)
 					if !ok {
-						log.Errorf("Received wrong event type.")
 						err = fmt.Errorf("Received wrong event type.")
 						return
 					}
diff --git a/client/core/transaction_factory_test.go b/client/rpc/client_test.go
similarity index 77%
rename from client/core/transaction_factory_test.go
rename to client/rpc/client_test.go
index 4544655e1d045332e07678a772b09a1c267b155b..b0806910fe73f91547a3b15b7d5c1f1163974567 100644
--- a/client/core/transaction_factory_test.go
+++ b/client/rpc/client_test.go
@@ -1,20 +1,18 @@
-// Copyright 2015, 2016 Eris Industries (UK) Ltd.
-// This file is part of Eris-RT
-
-// Eris-RT is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-
-// Eris-RT is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License
-// along with Eris-RT.  If not, see <http://www.gnu.org/licenses/>.
-
-package core
+// 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 (
 	"fmt"
@@ -26,19 +24,19 @@ import (
 	mockkeys "github.com/eris-ltd/eris-db/keys/mock"
 )
 
-func TestTransactionFactory(t *testing.T) {
+func Test(t *testing.T) {
 	mockKeyClient := mockkeys.NewMockKeyClient()
 	mockNodeClient := mockclient.NewMockNodeClient()
-	testTransactionFactorySend(t, mockNodeClient, mockKeyClient)
-	testTransactionFactoryCall(t, mockNodeClient, mockKeyClient)
-	testTransactionFactoryName(t, mockNodeClient, mockKeyClient)
-	testTransactionFactoryPermissions(t, mockNodeClient, mockKeyClient)
+	testSend(t, mockNodeClient, mockKeyClient)
+	testCall(t, mockNodeClient, mockKeyClient)
+	testName(t, mockNodeClient, mockKeyClient)
+	testPermissions(t, mockNodeClient, mockKeyClient)
 	// t.Run("BondTransaction", )
 	// t.Run("UnbondTransaction", )
 	// t.Run("RebondTransaction", )
 }
 
-func testTransactionFactorySend(t *testing.T,
+func testSend(t *testing.T,
 	nodeClient *mockclient.MockNodeClient, keyClient *mockkeys.MockKeyClient) {
 
 	// generate an ED25519 key and ripemd160 address
@@ -66,7 +64,7 @@ func testTransactionFactorySend(t *testing.T,
 	// TODO: test content of Transaction
 }
 
-func testTransactionFactoryCall(t *testing.T,
+func testCall(t *testing.T,
 	nodeClient *mockclient.MockNodeClient, keyClient *mockkeys.MockKeyClient) {
 
 	// generate an ED25519 key and ripemd160 address
@@ -99,7 +97,7 @@ func testTransactionFactoryCall(t *testing.T,
 	// TODO: test content of Transaction
 }
 
-func testTransactionFactoryName(t *testing.T,
+func testName(t *testing.T,
 	nodeClient *mockclient.MockNodeClient, keyClient *mockkeys.MockKeyClient) {
 
 	// generate an ED25519 key and ripemd160 address
@@ -130,7 +128,7 @@ func testTransactionFactoryName(t *testing.T,
 	// TODO: test content of Transaction
 }
 
-func testTransactionFactoryPermissions(t *testing.T,
+func testPermissions(t *testing.T,
 	nodeClient *mockclient.MockNodeClient, keyClient *mockkeys.MockKeyClient) {
 
 	// generate an ED25519 key and ripemd160 address
@@ -147,7 +145,7 @@ func testTransactionFactoryPermissions(t *testing.T,
 	nonceString := ""
 
 	_, err := Permissions(nodeClient, keyClient, publicKeyString, addressString,
-		nonceString, "set_base", []string{permAddressString, "root", "true"})
+		nonceString, "setBase", []string{permAddressString, "root", "true"})
 	if err != nil {
 		t.Logf("Error in PermissionsTx: %s", err)
 		t.Fail()
diff --git a/client/core/transaction_factory_util.go b/client/rpc/client_util.go
similarity index 79%
rename from client/core/transaction_factory_util.go
rename to client/rpc/client_util.go
index 3ad64a6ba36ad88ad5c11b6a0d70584285239095..f086c68b2329866c17f6c5c92a128e5e255cc974 100644
--- a/client/core/transaction_factory_util.go
+++ b/client/rpc/client_util.go
@@ -1,33 +1,30 @@
-// Copyright 2015, 2016 Eris Industries (UK) Ltd.
-// This file is part of Eris-RT
-
-// Eris-RT is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-
-// Eris-RT is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License
-// along with Eris-RT.  If not, see <http://www.gnu.org/licenses/>.
-
-package core
+// 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"
 
-	log "github.com/eris-ltd/eris-logger"
-
 	"github.com/tendermint/go-crypto"
 
 	acc "github.com/eris-ltd/eris-db/account"
 	"github.com/eris-ltd/eris-db/client"
 	"github.com/eris-ltd/eris-db/keys"
+	"github.com/eris-ltd/eris-db/logging"
 	ptypes "github.com/eris-ltd/eris-db/permission/types"
 	"github.com/eris-ltd/eris-db/txs"
 )
@@ -101,10 +98,10 @@ func checkCommon(nodeClient client.NodeClient, keyClient keys.KeyClient, pubkey,
 		return
 	} else if pubkey != "" {
 		if addr != "" {
-			log.WithFields(log.Fields{
-				"public key": pubkey,
-				"address":    addr,
-			}).Info("you have specified both a pubkey and an address. the pubkey takes precedent")
+			logging.InfoMsg(nodeClient.Logger(), "Both a public key and an address have been specified. The public key takes precedent.",
+				"public_key", pubkey,
+				"address", addr,
+			)
 		}
 		pubKeyBytes, err = hex.DecodeString(pubkey)
 		if err != nil {
@@ -151,10 +148,10 @@ func checkCommon(nodeClient client.NodeClient, keyClient keys.KeyClient, pubkey,
 			return pub, amt, nonce, err2
 		}
 		nonce = int64(account.Sequence) + 1
-		log.WithFields(log.Fields{
-			"nonce":           nonce,
-			"account address": fmt.Sprintf("%X", addrBytes),
-		}).Debug("Fetch nonce from node")
+		logging.TraceMsg(nodeClient.Logger(), "Fetch nonce from node",
+			"nonce", nonce,
+			"account address", addrBytes,
+		)
 	} else {
 		nonce, err = strconv.ParseInt(nonceS, 10, 64)
 		if err != nil {
diff --git a/client/transaction/transaction.go b/client/transaction/transaction.go
deleted file mode 100644
index e9840d244cacff3bb8b88d90d6dd23bf4eb00974..0000000000000000000000000000000000000000
--- a/client/transaction/transaction.go
+++ /dev/null
@@ -1,96 +0,0 @@
-// Copyright 2015, 2016 Eris Industries (UK) Ltd.
-// This file is part of Eris-RT
-
-// Eris-RT is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-
-// Eris-RT is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License
-// along with Eris-RT.  If not, see <http://www.gnu.org/licenses/>.
-
-package transaction
-
-import (
-	"fmt"
-	"os"
-
-	log "github.com/eris-ltd/eris-logger"
-
-	"github.com/eris-ltd/eris-db/client"
-	"github.com/eris-ltd/eris-db/client/core"
-	"github.com/eris-ltd/eris-db/definitions"
-	"github.com/eris-ltd/eris-db/keys"
-)
-
-func Send(do *definitions.ClientDo) {
-	// construct two clients to call out to keys server and
-	// blockchain node.
-	erisKeyClient := keys.NewErisKeyClient(do.SignAddrFlag)
-	erisNodeClient := client.NewErisNodeClient(do.NodeAddrFlag)
-	// form the send transaction
-	sendTransaction, err := core.Send(erisNodeClient, erisKeyClient,
-		do.PubkeyFlag, do.AddrFlag, do.ToFlag, do.AmtFlag, do.NonceFlag)
-	if err != nil {
-		log.Fatalf("Failed on forming Send Transaction: %s", err)
-		return
-	}
-	// 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.
-	unpackSignAndBroadcast(
-		core.SignAndBroadcast(do.ChainidFlag, erisNodeClient,
-			erisKeyClient, sendTransaction, true, do.BroadcastFlag, do.WaitFlag))
-}
-
-func Call(do *definitions.ClientDo) {
-	// construct two clients to call out to keys server and
-	// blockchain node.
-	erisKeyClient := keys.NewErisKeyClient(do.SignAddrFlag)
-	erisNodeClient := client.NewErisNodeClient(do.NodeAddrFlag)
-	// form the call transaction
-	callTransaction, err := core.Call(erisNodeClient, erisKeyClient,
-		do.PubkeyFlag, do.AddrFlag, do.ToFlag, do.AmtFlag, do.NonceFlag,
-		do.GasFlag, do.FeeFlag, do.DataFlag)
-	if err != nil {
-		log.Fatalf("Failed on forming Call Transaction: %s", err)
-		return
-	}
-	// 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.
-	unpackSignAndBroadcast(
-		core.SignAndBroadcast(do.ChainidFlag, erisNodeClient,
-			erisKeyClient, callTransaction, true, do.BroadcastFlag, do.WaitFlag))
-}
-
-//----------------------------------------------------------------------
-// Helper functions
-
-func unpackSignAndBroadcast(result *core.TxResult, err error) {
-	if err != nil {
-		log.Fatalf("Failed on signing (and broadcasting) transaction: %s", err)
-		os.Exit(1)
-	}
-	if result == nil {
-		// if we don't provide --sign or --broadcast
-		return
-	}
-	printResult := log.Fields{
-		"transaction hash": fmt.Sprintf("%X", result.Hash),
-	}
-	if result.Address != nil {
-		printResult["Contract Address"] = fmt.Sprintf("%X", result.Address)
-	}
-	if result.Return != nil {
-		printResult["Block Hash"] = fmt.Sprintf("%X", result.BlockHash)
-		printResult["Return Value"] = fmt.Sprintf("%X", result.Return)
-		printResult["Exception"] = fmt.Sprintf("%s", result.Exception)
-	}
-	log.WithFields(printResult).Warn("Result")
-}
diff --git a/client/websocket_client.go b/client/websocket_client.go
index 42f1bf37d384f999cb5d913cbf741124e71f1736..d3949e652f2ab40ee357bdb95910f9032626e938 100644
--- a/client/websocket_client.go
+++ b/client/websocket_client.go
@@ -1,18 +1,16 @@
-// Copyright 2015, 2016 Eris Industries (UK) Ltd.
-// This file is part of Eris-RT
-
-// Eris-RT is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-
-// Eris-RT is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License
-// along with Eris-RT.  If not, see <http://www.gnu.org/licenses/>.
+// 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
 
@@ -24,8 +22,8 @@ import (
 	"github.com/tendermint/go-rpc/client"
 	"github.com/tendermint/go-wire"
 
-	log "github.com/eris-ltd/eris-logger"
-
+	"github.com/eris-ltd/eris-db/logging"
+	"github.com/eris-ltd/eris-db/logging/loggers"
 	ctypes "github.com/eris-ltd/eris-db/rpc/tendermint/core/types"
 	"github.com/eris-ltd/eris-db/txs"
 )
@@ -41,29 +39,30 @@ type Confirmation struct {
 	Error     error
 }
 
-// NOTE [ben] Compiler check to ensure ErisNodeClient successfully implements
+// NOTE [ben] Compiler check to ensure erisNodeClient successfully implements
 // eris-db/client.NodeClient
-var _ NodeWebsocketClient = (*ErisNodeWebsocketClient)(nil)
+var _ NodeWebsocketClient = (*erisNodeWebsocketClient)(nil)
 
-type ErisNodeWebsocketClient struct {
+type erisNodeWebsocketClient struct {
 	// TODO: assert no memory leak on closing with open websocket
 	tendermintWebsocket *rpcclient.WSClient
+	logger              loggers.InfoTraceLogger
 }
 
 // Subscribe to an eventid
-func (erisNodeWebsocketClient *ErisNodeWebsocketClient) Subscribe(eventid string) error {
+func (erisNodeWebsocketClient *erisNodeWebsocketClient) Subscribe(eventid string) error {
 	// TODO we can in the background listen to the subscription id and remember it to ease unsubscribing later.
 	return erisNodeWebsocketClient.tendermintWebsocket.Subscribe(eventid)
 }
 
 // Unsubscribe from an eventid
-func (erisNodeWebsocketClient *ErisNodeWebsocketClient) Unsubscribe(subscriptionId string) error {
+func (erisNodeWebsocketClient *erisNodeWebsocketClient) Unsubscribe(subscriptionId string) error {
 	return erisNodeWebsocketClient.tendermintWebsocket.Unsubscribe(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 (erisNodeWebsocketClient *ErisNodeWebsocketClient) WaitForConfirmation(tx txs.Tx, chainId string, inputAddr []byte) (chan Confirmation, error) {
+func (erisNodeWebsocketClient *erisNodeWebsocketClient) WaitForConfirmation(tx txs.Tx, chainId string, inputAddr []byte) (chan Confirmation, error) {
 	// check no errors are reported on the websocket
 	if err := erisNodeWebsocketClient.assertNoErrors(); err != nil {
 		return nil, err
@@ -88,7 +87,8 @@ func (erisNodeWebsocketClient *ErisNodeWebsocketClient) WaitForConfirmation(tx t
 			result := new(ctypes.ErisDBResult)
 			if wire.ReadJSONPtr(result, resultBytes, &err); err != nil {
 				// keep calm and carry on
-				log.Errorf("[eris-client] Failed to unmarshal json bytes for websocket event: %s", err)
+				logging.InfoMsg(erisNodeWebsocketClient.logger, "Failed to unmarshal json bytes for websocket event",
+					"error", err)
 				continue
 			}
 
@@ -97,36 +97,41 @@ func (erisNodeWebsocketClient *ErisNodeWebsocketClient) WaitForConfirmation(tx t
 				// Received confirmation of subscription to event streams
 				// TODO: collect subscription IDs, push into channel and on completion
 				// unsubscribe
-				log.Infof("[eris-client] recceived confirmation for event (%s) with subscription id (%s).",
-					subscription.Event, subscription.SubscriptionId)
+				logging.InfoMsg(erisNodeWebsocketClient.logger, "Received confirmation for event",
+					"event", subscription.Event,
+					"subscription_id", subscription.SubscriptionId)
 				continue
 			}
 
 			event, ok := (*result).(*ctypes.ResultEvent)
 			if !ok {
 				// keep calm and carry on
-				log.Warnf("[eris-client] Failed to cast to ResultEvent for websocket event: %s", *result)
+				logging.InfoMsg(erisNodeWebsocketClient.logger, "Failed to cast to ResultEvent for websocket event",
+					"event", event.Event)
 				continue
 			}
 
 			blockData, ok := event.Data.(txs.EventDataNewBlock)
 			if ok {
 				latestBlockHash = blockData.Block.Hash()
-				log.WithFields(log.Fields{
-					"new block":   blockData.Block,
-					"latest hash": latestBlockHash,
-				}).Debug("Registered new block")
+				logging.TraceMsg(erisNodeWebsocketClient.logger, "Registered new block",
+					"block", blockData.Block,
+					"latest_block_hash", latestBlockHash,
+				)
 				continue
 			}
 
 			// we don't accept events unless they came after a new block (ie. in)
 			if latestBlockHash == nil {
-				log.Infof("[eris-client] no first block has been registered, so ignoring event: %s", event.Event)
+				logging.InfoMsg(erisNodeWebsocketClient.logger, "First block has not been registered so ignoring event",
+					"event", event.Event)
 				continue
 			}
 
 			if event.Event != eid {
-				log.Warnf("[eris-client] received unsolicited event! Got %s, expected %s\n", event.Event, eid)
+				logging.InfoMsg(erisNodeWebsocketClient.logger, "Received unsolicited event",
+					"event_received", event.Event,
+					"event_expected", eid)
 				continue
 			}
 
@@ -143,10 +148,9 @@ func (erisNodeWebsocketClient *ErisNodeWebsocketClient) WaitForConfirmation(tx t
 			}
 
 			if !bytes.Equal(txs.TxHash(chainId, data.Tx), txs.TxHash(chainId, tx)) {
-				log.WithFields(log.Fields{
+				logging.TraceMsg(erisNodeWebsocketClient.logger, "Received different event",
 					// TODO: consider re-implementing TxID again, or other more clear debug
-					"received transaction event": txs.TxHash(chainId, data.Tx),
-				}).Debug("Received different event")
+					"received transaction event", txs.TxHash(chainId, data.Tx))
 				continue
 			}
 
@@ -188,13 +192,13 @@ func (erisNodeWebsocketClient *ErisNodeWebsocketClient) WaitForConfirmation(tx t
 	return confirmationChannel, nil
 }
 
-func (erisNodeWebsocketClient *ErisNodeWebsocketClient) Close() {
+func (erisNodeWebsocketClient *erisNodeWebsocketClient) Close() {
 	if erisNodeWebsocketClient.tendermintWebsocket != nil {
 		erisNodeWebsocketClient.tendermintWebsocket.Stop()
 	}
 }
 
-func (erisNodeWebsocketClient *ErisNodeWebsocketClient) assertNoErrors() error {
+func (erisNodeWebsocketClient *erisNodeWebsocketClient) assertNoErrors() error {
 	if erisNodeWebsocketClient.tendermintWebsocket != nil {
 		select {
 		case err := <-erisNodeWebsocketClient.tendermintWebsocket.ErrorsCh:
diff --git a/client/ws_client.go b/client/ws_client.go
index d60986b6f9a41575642dbf963aaceb281d52dfe5..cdcb0b570af2b87926e888d0ef009b125d89e8f5 100644
--- a/client/ws_client.go
+++ b/client/ws_client.go
@@ -1,4 +1,17 @@
-// Websocket client implementation. This will be used in tests.
+// 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,
@@ -6,6 +19,7 @@ package client
 // 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"
diff --git a/cmd/eris-db.go b/cmd/eris-db.go
index 605b12060b4f669c249dd4a04b05937f6b568262..c0f6e582441b707f9655a4809cca054e4f66c136 100644
--- a/cmd/eris-db.go
+++ b/cmd/eris-db.go
@@ -1,18 +1,16 @@
-// Copyright 2015, 2016 Eris Industries (UK) Ltd.
-// This file is part of Eris-RT
-
-// Eris-RT is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-
-// Eris-RT is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License
-// along with Eris-RT.  If not, see <http://www.gnu.org/licenses/>.
+// 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
 
@@ -21,17 +19,12 @@ import (
 	"strconv"
 	"strings"
 
-	cobra "github.com/spf13/cobra"
+	"github.com/spf13/cobra"
 
-	log "github.com/eris-ltd/eris-logger"
-
-	definitions "github.com/eris-ltd/eris-db/definitions"
-	version "github.com/eris-ltd/eris-db/version"
+	"github.com/eris-ltd/eris-db/definitions"
+	"github.com/eris-ltd/eris-db/version"
 )
 
-// Global Do struct
-var do *definitions.Do
-
 var ErisDbCmd = &cobra.Command{
 	Use:   "eris-db",
 	Short: "Eris-DB is the server side of the eris chain.",
@@ -39,42 +32,30 @@ var ErisDbCmd = &cobra.Command{
 a modular consensus engine and application manager to run a chain to suit
 your needs.
 
-Made with <3 by Eris Industries.
+Made with <3 by Monax Industries.
 
 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)
-		if do.Verbose {
-			log.SetLevel(log.InfoLevel)
-		} else if do.Debug {
-			log.SetLevel(log.DebugLevel)
-		}
-	},
 	Run: func(cmd *cobra.Command, args []string) { cmd.Help() },
 }
 
 func Execute() {
-	InitErisDbCli()
-	AddGlobalFlags()
-	AddCommands()
+	do := definitions.NewDo()
+	AddGlobalFlags(do)
+	AddCommands(do)
 	ErisDbCmd.Execute()
 }
 
-func InitErisDbCli() {
-	// initialise an empty Do struct for command execution
-	do = definitions.NewDo()
-}
-
-func AddGlobalFlags() {
-	ErisDbCmd.PersistentFlags().BoolVarP(&do.Verbose, "verbose", "v", defaultVerbose(), "verbose output; more output than no output flags; less output than debug level; default respects $ERIS_DB_VERBOSE")
-	ErisDbCmd.PersistentFlags().BoolVarP(&do.Debug, "debug", "d", defaultDebug(), "debug level output; the most output available for eris-db; if it is too chatty use verbose flag; default respects $ERIS_DB_DEBUG")
+func AddGlobalFlags(do *definitions.Do) {
+	ErisDbCmd.PersistentFlags().BoolVarP(&do.Verbose, "verbose", "v",
+		defaultVerbose(),
+		"verbose output; more output than no output flags; less output than debug level; default respects $ERIS_DB_VERBOSE")
+	ErisDbCmd.PersistentFlags().BoolVarP(&do.Debug, "debug", "d", defaultDebug(),
+		"debug level output; the most output available for eris-db; if it is too chatty use verbose flag; default respects $ERIS_DB_DEBUG")
 }
 
-func AddCommands() {
-	buildServeCommand()
-	ErisDbCmd.AddCommand(ServeCmd)
+func AddCommands(do *definitions.Do) {
+	ErisDbCmd.AddCommand(buildServeCommand(do))
 }
 
 //------------------------------------------------------------------------------
diff --git a/cmd/eris-db/main.go b/cmd/eris-db/main.go
index 47870377f4123834fe8b1c99474c08819da54c12..d293b374f4e5c8919860293a9534e63b576f9bf6 100644
--- a/cmd/eris-db/main.go
+++ b/cmd/eris-db/main.go
@@ -1,18 +1,16 @@
-// Copyright 2015, 2016 Eris Industries (UK) Ltd.
-// This file is part of Eris-RT
-
-// Eris-RT is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-
-// Eris-RT is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License
-// along with Eris-RT.  If not, see <http://www.gnu.org/licenses/>.
+// 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
 
diff --git a/cmd/serve.go b/cmd/serve.go
index eccf3388ab0c14bc167c8211ce3a9e82208a39f4..4eceefc3810603f8fb3e091ce09317a1606b2c1b 100644
--- a/cmd/serve.go
+++ b/cmd/serve.go
@@ -1,35 +1,33 @@
-// Copyright 2015, 2016 Eris Industries (UK) Ltd.
-// This file is part of Eris-RT
-
-// Eris-RT is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-
-// Eris-RT is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License
-// along with Eris-RT.  If not, see <http://www.gnu.org/licenses/>.
+// 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 (
+	"fmt"
 	"os"
 	"os/signal"
 	"path"
 	"syscall"
 
-	cobra "github.com/spf13/cobra"
-
-	log "github.com/eris-ltd/eris-logger"
-
-	"fmt"
+	"github.com/eris-ltd/eris-db/core"
+	"github.com/eris-ltd/eris-db/definitions"
+	"github.com/eris-ltd/eris-db/logging"
+	"github.com/eris-ltd/eris-db/logging/lifecycle"
+	"github.com/eris-ltd/eris-db/util"
 
-	core "github.com/eris-ltd/eris-db/core"
-	util "github.com/eris-ltd/eris-db/util"
+	"github.com/spf13/cobra"
 )
 
 const (
@@ -41,148 +39,157 @@ var DefaultConfigFilename = fmt.Sprintf("%s.%s",
 	DefaultConfigBasename,
 	DefaultConfigType)
 
-var ServeCmd = &cobra.Command{
-	Use:   "serve",
-	Short: "Eris-DB serve starts an eris-db node with client API enabled by default.",
-	Long: `Eris-DB serve starts an eris-db node with client API enabled by default.
+// build the serve subcommand
+func buildServeCommand(do *definitions.Do) *cobra.Command {
+	cmd := &cobra.Command{
+		Use:   "serve",
+		Short: "Eris-DB serve starts an eris-db node with client API enabled by default.",
+		Long: `Eris-DB serve starts an eris-db node with client API enabled by default.
 The Eris-DB node is modularly configured for the consensus engine and application
 manager.  The client API can be disabled.`,
-	Example: fmt.Sprintf(`$ eris-db serve -- will start the Eris-DB node based on the configuration file "%s" in the current working directory
+		Example: fmt.Sprintf(`$ eris-db serve -- will start the Eris-DB node based on the configuration file "%s" in the current working directory
 $ eris-db serve --work-dir <path-to-working-directory> -- will start the Eris-DB node based on the configuration file "%s" in the provided working directory
 $ eris-db serve --chain-id <CHAIN_ID> -- will overrule the configuration entry assert_chain_id`,
-		DefaultConfigFilename, DefaultConfigFilename),
-	PreRun: func(cmd *cobra.Command, args []string) {
-		// if WorkDir was not set by a flag or by $ERIS_DB_WORKDIR
-		// NOTE [ben]: we can consider an `Explicit` flag that eliminates
-		// the use of any assumptions while starting Eris-DB
-		if do.WorkDir == "" {
-			if currentDirectory, err := os.Getwd(); err != nil {
-				log.Fatalf("No directory provided and failed to get current working directory: %v", err)
+			DefaultConfigFilename, DefaultConfigFilename),
+		PreRun: func(cmd *cobra.Command, args []string) {
+			// if WorkDir was not set by a flag or by $ERIS_DB_WORKDIR
+			// NOTE [ben]: we can consider an `Explicit` flag that eliminates
+			// the use of any assumptions while starting Eris-DB
+			if do.WorkDir == "" {
+				if currentDirectory, err := os.Getwd(); err != nil {
+					panic(fmt.Sprintf("No directory provided and failed to get current "+
+						"working directory: %v", err))
+					os.Exit(1)
+				} else {
+					do.WorkDir = currentDirectory
+				}
+			}
+			if !util.IsDir(do.WorkDir) {
+				panic(fmt.Sprintf("Provided working directory %s is not a directory",
+					do.WorkDir))
 				os.Exit(1)
-			} else {
-				do.WorkDir = currentDirectory
 			}
-		}
-		if !util.IsDir(do.WorkDir) {
-			log.Fatalf("Provided working directory %s is not a directory", do.WorkDir)
-		}
-	},
-	Run: Serve,
-}
-
-// build the serve subcommand
-func buildServeCommand() {
-	addServeFlags()
+		},
+		Run: ServeRunner(do),
+	}
+	addServeFlags(do, cmd)
+	return cmd
 }
 
-func addServeFlags() {
-	ServeCmd.PersistentFlags().StringVarP(&do.ChainId, "chain-id", "c",
+func addServeFlags(do *definitions.Do, serveCmd *cobra.Command) {
+	serveCmd.PersistentFlags().StringVarP(&do.ChainId, "chain-id", "c",
 		defaultChainId(), "specify the chain id to use for assertion against the genesis file or the existing state. If omitted, and no id is set in $CHAIN_ID, then assert_chain_id is used from the configuration file.")
-	ServeCmd.PersistentFlags().StringVarP(&do.WorkDir, "work-dir", "w",
+	serveCmd.PersistentFlags().StringVarP(&do.WorkDir, "work-dir", "w",
 		defaultWorkDir(), "specify the working directory for the chain to run.  If omitted, and no path set in $ERIS_DB_WORKDIR, the current working directory is taken.")
-	ServeCmd.PersistentFlags().StringVarP(&do.DataDir, "data-dir", "",
+	serveCmd.PersistentFlags().StringVarP(&do.DataDir, "data-dir", "",
 		defaultDataDir(), "specify the data directory.  If omitted and not set in $ERIS_DB_DATADIR, <working_directory>/data is taken.")
-	ServeCmd.PersistentFlags().BoolVarP(&do.DisableRpc, "disable-rpc", "",
+	serveCmd.PersistentFlags().BoolVarP(&do.DisableRpc, "disable-rpc", "",
 		defaultDisableRpc(), "indicate for the RPC to be disabled. If omitted the RPC is enabled by default, unless (deprecated) $ERISDB_API is set to false.")
 }
 
 //------------------------------------------------------------------------------
 // functions
-
-// serve() prepares the environment and sets up the core for Eris_DB to run.
-// After the setup succeeds, serve() starts the core and halts for core to
-// terminate.
-func Serve(cmd *cobra.Command, args []string) {
-	// load configuration from a single location to avoid a wrong configuration
-	// file is loaded.
-	err := do.ReadConfig(do.WorkDir, DefaultConfigBasename, DefaultConfigType)
-	if err != nil {
-		log.WithFields(log.Fields{
-			"directory": do.WorkDir,
-			"file":      DefaultConfigFilename,
-		}).Fatalf("Fatal error reading configuration")
-		os.Exit(1)
-	}
-	// if do.ChainId is not yet set, load chain_id for assertion from configuration file
-	if do.ChainId == "" {
-		if do.ChainId = do.Config.GetString("chain.assert_chain_id"); do.ChainId == "" {
-			log.Fatalf("Failed to read non-empty string for ChainId from config.")
-			os.Exit(1)
-		}
-	}
+func NewCoreFromDo(do *definitions.Do) (*core.Core, error) {
 	// load the genesis file path
 	do.GenesisFile = path.Join(do.WorkDir,
 		do.Config.GetString("chain.genesis_file"))
+
 	if do.Config.GetString("chain.genesis_file") == "" {
-		log.Fatalf("Failed to read non-empty string for genesis file from config.")
-		os.Exit(1)
+		return nil, fmt.Errorf("The config value chain.genesis_file is empty, " +
+			"but should be set to the location of the genesis.json file.")
 	}
 	// Ensure data directory is set and accessible
 	if err := do.InitialiseDataDirectory(); err != nil {
-		log.Fatalf("Failed to initialise data directory (%s): %v", do.DataDir, err)
-		os.Exit(1)
+		return nil, fmt.Errorf("Failed to initialise data directory (%s): %v", do.DataDir, err)
 	}
-	log.WithFields(log.Fields{
-		"chainId":          do.ChainId,
-		"workingDirectory": do.WorkDir,
-		"dataDirectory":    do.DataDir,
-		"genesisFile":      do.GenesisFile,
-	}).Info("Eris-DB serve configuring")
 
-	consensusConfig, err := core.LoadConsensusModuleConfig(do)
+	loggerConfig, err := core.LoadLoggingConfigFromDo(do)
 	if err != nil {
-		log.Fatalf("Failed to load consensus module configuration: %s.", err)
-		os.Exit(1)
+		return nil, fmt.Errorf("Failed to load logging config: %s", err)
 	}
 
-	managerConfig, err := core.LoadApplicationManagerModuleConfig(do)
+	// Create a root logger to pass through to dependencies
+	logger := logging.WithScope(lifecycle.NewLoggerFromLoggingConfig(loggerConfig), "Serve")
+	// Capture all logging from tendermint/tendermint and tendermint/go-*
+	// dependencies
+	lifecycle.CaptureTendermintLog15Output(logger)
+	// And from stdlib go log
+	lifecycle.CaptureStdlibLogOutput(logger)
+
+	// if do.ChainId is not yet set, load chain_id for assertion from configuration file
+
+	if do.ChainId == "" {
+		if do.ChainId = do.Config.GetString("chain.assert_chain_id"); do.ChainId == "" {
+			return nil, fmt.Errorf("The config chain.assert_chain_id is empty, " +
+				"but should be set to the chain_id of the chain we are trying to run.")
+		}
+	}
+
+	logging.Msg(logger, "Loading configuration for serve command",
+		"chainId", do.ChainId,
+		"workingDirectory", do.WorkDir,
+		"dataDirectory", do.DataDir,
+		"genesisFile", do.GenesisFile)
+
+	consensusConfig, err := core.LoadConsensusModuleConfig(do)
 	if err != nil {
-		log.Fatalf("Failed to load application manager module configuration: %s.", err)
-		os.Exit(1)
+		return nil, fmt.Errorf("Failed to load consensus module configuration: %s.", err)
 	}
-	log.WithFields(log.Fields{
-		"consensusModule":    consensusConfig.Version,
-		"applicationManager": managerConfig.Version,
-	}).Debug("Modules configured")
 
-	newCore, err := core.NewCore(do.ChainId, consensusConfig, managerConfig)
+	managerConfig, err := core.LoadApplicationManagerModuleConfig(do)
 	if err != nil {
-		log.Fatalf("Failed to load core: %s", err)
+		return nil, fmt.Errorf("Failed to load application manager module configuration: %s.", err)
 	}
 
-	if !do.DisableRpc {
-		serverConfig, err := core.LoadServerConfig(do)
-		if err != nil {
-			log.Fatalf("Failed to load server configuration: %s.", err)
-			os.Exit(1)
-		}
+	logging.Msg(logger, "Modules configured",
+		"consensusModule", consensusConfig.Version,
+		"applicationManager", managerConfig.Version)
+
+	return core.NewCore(do.ChainId, consensusConfig, managerConfig, logger)
+}
 
-		serverProcess, err := newCore.NewGatewayV0(serverConfig)
+// ServeRunner() returns a command runner that prepares the environment and sets
+// up the core for Eris-DB to run. After the setup succeeds, it starts the core
+// and waits for the core to terminate.
+func ServeRunner(do *definitions.Do) func(*cobra.Command, []string) {
+	return func(cmd *cobra.Command, args []string) {
+		// load configuration from a single location to avoid a wrong configuration
+		// file is loaded.
+		err := do.ReadConfig(do.WorkDir, DefaultConfigBasename, DefaultConfigType)
 		if err != nil {
-			log.Fatalf("Failed to load servers: %s.", err)
-			os.Exit(1)
+			util.Fatalf("Fatal error reading configuration from %s/%s", do.WorkDir,
+				DefaultConfigFilename)
 		}
-		err = serverProcess.Start()
+
+		newCore, err := NewCoreFromDo(do)
+
 		if err != nil {
-			log.Fatalf("Failed to start servers: %s.", err)
-			os.Exit(1)
+			util.Fatalf("Failed to load core: %s", err)
 		}
-		_, err = newCore.NewGatewayTendermint(serverConfig)
-		if err != nil {
-			log.Fatalf("Failed to start Tendermint gateway")
+
+		if !do.DisableRpc {
+			serverConfig, err := core.LoadServerConfig(do)
+			if err != nil {
+				util.Fatalf("Failed to load server configuration: %s.", err)
+			}
+			serverProcess, err := newCore.NewGatewayV0(serverConfig)
+			if err != nil {
+				util.Fatalf("Failed to load servers: %s.", err)
+			}
+			err = serverProcess.Start()
+			if err != nil {
+				util.Fatalf("Failed to start servers: %s.", err)
+			}
+			_, err = newCore.NewGatewayTendermint(serverConfig)
+			if err != nil {
+				util.Fatalf("Failed to start Tendermint gateway")
+			}
+			<-serverProcess.StopEventChannel()
+		} else {
+			signals := make(chan os.Signal, 1)
+			signal.Notify(signals, syscall.SIGINT, syscall.SIGTERM)
+			fmt.Fprintf(os.Stderr, "Received %s signal. Marmots out.", <-signals)
 		}
-		<-serverProcess.StopEventChannel()
-	} else {
-		signals := make(chan os.Signal, 1)
-		done := make(chan bool, 1)
-		signal.Notify(signals, syscall.SIGINT, syscall.SIGTERM)
-		go func() {
-			signal := <-signals
-			// TODO: [ben] clean up core; in a manner consistent with enabled rpc
-			log.Fatalf("Received %s signal. Marmots out.", signal)
-			done <- true
-		}()
-		<-done
 	}
 }
 
diff --git a/common/math/integral/integral_math.go b/common/math/integral/integral_math.go
index 8cdc6ee18d3a4a1e8ed777527d9605d325a4a61c..863b92114352b6a12568f8dcc778708adbfd5283 100644
--- a/common/math/integral/integral_math.go
+++ b/common/math/integral/integral_math.go
@@ -1,3 +1,17 @@
+// 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 integral
 
 func MaxInt8(a, b int8) int8 {
diff --git a/common/random/random.go b/common/random/random.go
new file mode 100644
index 0000000000000000000000000000000000000000..e2a095e2a559980abf7ba3a5ea105c491baaeec8
--- /dev/null
+++ b/common/random/random.go
@@ -0,0 +1,154 @@
+// 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 random
+
+import (
+	crand "crypto/rand"
+	"math/rand"
+	"time"
+
+	"github.com/eris-ltd/eris-db/common/sanity"
+)
+
+const (
+	strChars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" // 62 characters
+)
+
+func init() {
+	b := cRandBytes(8)
+	var seed uint64
+	for i := 0; i < 8; i++ {
+		seed |= uint64(b[i])
+		seed <<= 8
+	}
+	rand.Seed(int64(seed))
+}
+
+// Constructs an alphanumeric string of given length.
+func RandStr(length int) string {
+	chars := []byte{}
+MAIN_LOOP:
+	for {
+		val := rand.Int63()
+		for i := 0; i < 10; i++ {
+			v := int(val & 0x3f) // rightmost 6 bits
+			if v >= 62 {         // only 62 characters in strChars
+				val >>= 6
+				continue
+			} else {
+				chars = append(chars, strChars[v])
+				if len(chars) == length {
+					break MAIN_LOOP
+				}
+				val >>= 6
+			}
+		}
+	}
+
+	return string(chars)
+}
+
+func RandUint16() uint16 {
+	return uint16(rand.Uint32() & (1<<16 - 1))
+}
+
+func RandUint32() uint32 {
+	return rand.Uint32()
+}
+
+func RandUint64() uint64 {
+	return uint64(rand.Uint32())<<32 + uint64(rand.Uint32())
+}
+
+func RandUint() uint {
+	return uint(rand.Int())
+}
+
+func RandInt16() int16 {
+	return int16(rand.Uint32() & (1<<16 - 1))
+}
+
+func RandInt32() int32 {
+	return int32(rand.Uint32())
+}
+
+func RandInt64() int64 {
+	return int64(rand.Uint32())<<32 + int64(rand.Uint32())
+}
+
+func RandInt() int {
+	return rand.Int()
+}
+
+// Distributed pseudo-exponentially to test for various cases
+func RandUint16Exp() uint16 {
+	bits := rand.Uint32() % 16
+	if bits == 0 {
+		return 0
+	}
+	n := uint16(1 << (bits - 1))
+	n += uint16(rand.Int31()) & ((1 << (bits - 1)) - 1)
+	return n
+}
+
+// Distributed pseudo-exponentially to test for various cases
+func RandUint32Exp() uint32 {
+	bits := rand.Uint32() % 32
+	if bits == 0 {
+		return 0
+	}
+	n := uint32(1 << (bits - 1))
+	n += uint32(rand.Int31()) & ((1 << (bits - 1)) - 1)
+	return n
+}
+
+// Distributed pseudo-exponentially to test for various cases
+func RandUint64Exp() uint64 {
+	bits := rand.Uint32() % 64
+	if bits == 0 {
+		return 0
+	}
+	n := uint64(1 << (bits - 1))
+	n += uint64(rand.Int63()) & ((1 << (bits - 1)) - 1)
+	return n
+}
+
+func RandFloat32() float32 {
+	return rand.Float32()
+}
+
+func RandTime() time.Time {
+	return time.Unix(int64(RandUint64Exp()), 0)
+}
+
+func RandBytes(n int) []byte {
+	bs := make([]byte, n)
+	for i := 0; i < n; i++ {
+		bs[i] = byte(rand.Intn(256))
+	}
+	return bs
+}
+
+// NOTE: This relies on the os's random number generator.
+// For real security, we should salt that with some seed.
+// See github.com/tendermint/go-crypto for a more secure reader.
+func cRandBytes(numBytes int) []byte {
+	b := make([]byte, numBytes)
+	_, err := crand.Read(b)
+	if err != nil {
+		sanity.PanicCrisis(err)
+	}
+	return b
+}
diff --git a/common/sanity/sanity.go b/common/sanity/sanity.go
new file mode 100644
index 0000000000000000000000000000000000000000..63fe7fd9e2f1a53ec7c379b7b199d082044f5b1b
--- /dev/null
+++ b/common/sanity/sanity.go
@@ -0,0 +1,48 @@
+// 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 sanity
+
+import (
+	"fmt"
+)
+
+//--------------------------------------------------------------------------------------------------
+// panic wrappers
+// NOTE: [ben] Fail fast and fail hard, these are wrappers that point to code that needs
+// to be addressed, but simplify finding them in the code;
+
+// A panic resulting from a sanity check means there is a programmer error
+// and some gaurantee is not satisfied.
+func PanicSanity(v interface{}) {
+	panic(fmt.Sprintf("Paniced on a Sanity Check: %v", v))
+}
+
+// A panic here means something has gone horribly wrong, in the form of data corruption or
+// failure of the operating system. In a correct/healthy system, these should never fire.
+// If they do, it's indicative of a much more serious problem.
+func PanicCrisis(v interface{}) {
+	panic(fmt.Sprintf("Paniced on a Crisis: %v", v))
+}
+
+// Indicates a failure of consensus. Someone was malicious or something has
+// gone horribly wrong. These should really boot us into an "emergency-recover" mode
+func PanicConsensus(v interface{}) {
+	panic(fmt.Sprintf("Paniced on a Consensus Failure: %v", v))
+}
+
+// For those times when we're not sure if we should panic
+func PanicQ(v interface{}) {
+	panic(fmt.Sprintf("Paniced questionably: %v", v))
+}
diff --git a/config/config.go b/config/config.go
new file mode 100644
index 0000000000000000000000000000000000000000..e49db3d10337f9e67149fc81de0b0ff0084bf6a6
--- /dev/null
+++ b/config/config.go
@@ -0,0 +1,185 @@
+// 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 config
+
+import (
+	"bytes"
+	"fmt"
+	"text/template"
+)
+
+type ConfigServiceGeneral struct {
+	ChainImageName      string
+	UseDataContainer    bool
+	ExportedPorts       string
+	ContainerEntrypoint string
+}
+
+// TODO: [ben] increase the configurability upon need
+type ConfigChainGeneral struct {
+	AssertChainId       string
+	ErisdbMajorVersion  uint8
+	ErisdbMinorVersion  uint8
+	GenesisRelativePath string
+}
+
+type ConfigChainModule struct {
+	Name               string
+	MajorVersion       uint8
+	MinorVersion       uint8
+	ModuleRelativeRoot string
+}
+
+type ConfigTendermint struct {
+	Moniker  string
+	Seeds    string
+	FastSync bool
+}
+
+var serviceGeneralTemplate *template.Template
+var chainGeneralTemplate *template.Template
+var chainConsensusTemplate *template.Template
+var chainApplicationManagerTemplate *template.Template
+var tendermintTemplate *template.Template
+
+func init() {
+	var err error
+	if serviceGeneralTemplate, err = template.New("serviceGeneral").Parse(sectionServiceGeneral); err != nil {
+		panic(err)
+	}
+	if chainGeneralTemplate, err = template.New("chainGeneral").Parse(sectionChainGeneral); err != nil {
+		panic(err)
+	}
+	if chainConsensusTemplate, err = template.New("chainConsensus").Parse(sectionChainConsensus); err != nil {
+		panic(err)
+	}
+	if chainApplicationManagerTemplate, err = template.New("chainApplicationManager").Parse(sectionChainApplicationManager); err != nil {
+		panic(err)
+	}
+	if tendermintTemplate, err = template.New("tendermint").Parse(sectionTendermint); err != nil {
+		panic(err)
+	}
+}
+
+// NOTE: [ben] for 0.12.0-rc3 we only have a single configuration path
+// with Tendermint in-process as the consensus engine and ErisMint
+// in-process as the application manager, so we hard-code the few
+// parameters that are already templated.
+// Let's learn to walk before we can run.
+func GetConfigurationFileBytes(chainId, moniker, seeds string, chainImageName string,
+	useDataContainer bool, exportedPortsString, containerEntrypoint string) ([]byte, error) {
+
+	erisdbService := &ConfigServiceGeneral{
+		ChainImageName:      chainImageName,
+		UseDataContainer:    useDataContainer,
+		ExportedPorts:       exportedPortsString,
+		ContainerEntrypoint: containerEntrypoint,
+	}
+	erisdbChain := &ConfigChainGeneral{
+		AssertChainId:       chainId,
+		ErisdbMajorVersion:  uint8(0),
+		ErisdbMinorVersion:  uint8(16),
+		GenesisRelativePath: "genesis.json",
+	}
+	chainConsensusModule := &ConfigChainModule{
+		Name:               "tendermint",
+		MajorVersion:       uint8(0),
+		MinorVersion:       uint8(8),
+		ModuleRelativeRoot: "tendermint",
+	}
+	chainApplicationManagerModule := &ConfigChainModule{
+		Name:               "erismint",
+		MajorVersion:       uint8(0),
+		MinorVersion:       uint8(16),
+		ModuleRelativeRoot: "erismint",
+	}
+	tendermintModule := &ConfigTendermint{
+		Moniker:  moniker,
+		Seeds:    seeds,
+		FastSync: false,
+	}
+
+	// NOTE: [ben] according to StackOverflow appending strings with copy is
+	// more efficient than bytes.WriteString, but for readability and because
+	// this is not performance critical code we opt for bytes, which is
+	// still more efficient than + concatentation operator.
+	var buffer bytes.Buffer
+
+	// write copyright header
+	buffer.WriteString(headerCopyright)
+
+	// write section [service]
+	if err := serviceGeneralTemplate.Execute(&buffer, erisdbService); err != nil {
+		return nil, fmt.Errorf("Failed to write template service general for %s: %s",
+			chainId, err)
+	}
+	// write section for service dependencies; this is currently a static section
+	// with a fixed dependency on eris-keys
+	buffer.WriteString(sectionServiceDependencies)
+
+	// write section [chain]
+	if err := chainGeneralTemplate.Execute(&buffer, erisdbChain); err != nil {
+		return nil, fmt.Errorf("Failed to write template chain general for %s: %s",
+			chainId, err)
+	}
+
+	// write separator chain consensus
+	buffer.WriteString(separatorChainConsensus)
+	// write section [chain.consensus]
+	if err := chainConsensusTemplate.Execute(&buffer, chainConsensusModule); err != nil {
+		return nil, fmt.Errorf("Failed to write template chain consensus for %s: %s",
+			chainId, err)
+	}
+
+	// write separator chain application manager
+	buffer.WriteString(separatorChainApplicationManager)
+	// write section [chain.consensus]
+	if err := chainApplicationManagerTemplate.Execute(&buffer,
+		chainApplicationManagerModule); err != nil {
+		return nil, fmt.Errorf("Failed to write template chain application manager for %s: %s",
+			chainId, err)
+	}
+
+	// write separator servers
+	buffer.WriteString(separatorServerConfiguration)
+	// TODO: [ben] upon necessity replace this with template too
+	// write static section servers
+	buffer.WriteString(sectionServers)
+
+	// write separator modules
+	buffer.WriteString(separatorModules)
+
+	// write section module Tendermint
+	if err := tendermintTemplate.Execute(&buffer, tendermintModule); err != nil {
+		return nil, fmt.Errorf("Failed to write template tendermint for %s, moniker %s: %s",
+			chainId, moniker, err)
+	}
+
+	// write static section erismint
+	buffer.WriteString(sectionErisMint)
+
+	return buffer.Bytes(), nil
+}
+
+func GetExampleConfigFileBytes() ([]byte, error) {
+	return GetConfigurationFileBytes(
+		"simplechain",
+		"delectable_marmot",
+		"192.168.168.255",
+		"db:latest",
+		true,
+		"46657",
+		"eris-db")
+}
diff --git a/config/config_test.go b/config/config_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..1f5a95c1963a726173813cb84a0f1f920b84accd
--- /dev/null
+++ b/config/config_test.go
@@ -0,0 +1,35 @@
+// 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 config
+
+import (
+	"bytes"
+	"testing"
+
+	"github.com/spf13/viper"
+	"github.com/stretchr/testify/assert"
+)
+
+// Since the logic for generating configuration files (in eris-cm) is split from
+// the logic for consuming them
+func TestGeneratedConfigIsUsable(t *testing.T) {
+	bs, err := GetExampleConfigFileBytes()
+	assert.NoError(t, err, "Should be able to create example config")
+	buf := bytes.NewBuffer(bs)
+	conf := viper.New()
+	viper.SetConfigType("toml")
+	err = conf.ReadConfig(buf)
+	assert.NoError(t, err, "Should be able to read example config into Viper")
+}
diff --git a/config/dump_config_test.go b/config/dump_config_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..5d238c9e84afd53ab19da4a70bcb88d3fe77d525
--- /dev/null
+++ b/config/dump_config_test.go
@@ -0,0 +1,34 @@
+// +build dumpconfig
+
+// Space above 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 config
+
+import (
+	"io/ioutil"
+	"testing"
+
+	"github.com/stretchr/testify/assert"
+)
+
+// This is a little convenience for getting a config file dump. Just run:
+// go test -tags dumpconfig ./config
+// This pseudo test won't run unless the dumpconfig tag is
+func TestDumpConfig(t *testing.T) {
+	bs, err := GetExampleConfigFileBytes()
+	assert.NoError(t, err, "Should be able to create example config")
+	ioutil.WriteFile("config_dump.toml", bs, 0644)
+}
diff --git a/config/module.go b/config/module.go
index 39c131d269ae7861b69fdc80b039065a6c909b7e..da0218c5ce47ea9b71f2b9d2b6a52883cb711a5d 100644
--- a/config/module.go
+++ b/config/module.go
@@ -1,21 +1,20 @@
-// Copyright 2015, 2016 Eris Industries (UK) Ltd.
-// This file is part of Eris-RT
+// 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.
 
-// Eris-RT is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-
-// Eris-RT is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License
-// along with Eris-RT.  If not, see <http://www.gnu.org/licenses/>.
+package config
 
 // config defines simple types in a separate package to avoid cyclical imports
-package config
 
 import (
 	viper "github.com/spf13/viper"
diff --git a/config/templates.go b/config/templates.go
new file mode 100644
index 0000000000000000000000000000000000000000..27372813daa38d25aac68b3b7619090eb155abeb
--- /dev/null
+++ b/config/templates.go
@@ -0,0 +1,298 @@
+// 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 config
+
+const headerCopyright = `# 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.
+
+# This is a TOML configuration for Eris-DB chains generated by Eris.
+
+`
+
+const sectionServiceGeneral = `[service]
+# NOTE: this section is read by Eris tooling, and ignored by eris-db.
+# Image specifies the image name eris-cli needs to pull 
+# for running the chain.
+image = "{{.ChainImageName}}"
+# Define whether eris-cli needs to attach the data container
+# for the chain.
+data_container = {{.UseDataContainer}}
+# Specify a list of ports that need to be exported on the container.
+ports = {{.ExportedPorts}}
+{{ if ne .ContainerEntrypoint "" }}# Entrypoint points to the default action to execute
+# in the chain container.
+entry_point = "{{.ContainerEntrypoint}}"{{ end }}
+
+`
+
+const sectionServiceDependencies = `[dependencies]
+# NOTE: this section is read by Eris tooling, and ignored by eris-db.
+# Eris-db expects these services to be available; eric-cli tooling will
+# automatically set these services up for you.
+# Services to boot with/required by the chain
+services = [ "keys" ]
+
+`
+
+const sectionChainGeneral = `[chain]
+
+# ChainId is a human-readable name to identify the chain.
+# This must correspond to the chain_id defined in the genesis file
+# and the assertion here provides a safe-guard on misconfiguring chains.
+assert_chain_id = "{{.AssertChainId}}"
+# semantic major and minor version
+major_version = {{.ErisdbMajorVersion}}
+minor_version = {{.ErisdbMinorVersion}}
+# genesis file, relative path is to eris-db working directory
+genesis_file = "{{.GenesisRelativePath}}"
+
+`
+
+const separatorChainConsensus = `
+################################################################################
+##
+##  consensus
+##
+################################################################################
+
+`
+
+const sectionChainConsensus = `  [chain.consensus]
+  # consensus defines the module to use for consensus and
+  # this will define the peer-to-peer consensus network;
+  # accepted values are ("noops", "abci",) "tendermint"
+  name = "{{.Name}}"
+  # version is the major and minor semantic version;
+  # the version will be asserted on
+  major_version = {{.MajorVersion}}
+  minor_version = {{.MinorVersion}}
+  # relative path to consensus' module root folder
+  relative_root = "{{.ModuleRelativeRoot}}"
+
+  `
+
+const separatorChainApplicationManager = `
+################################################################################
+##
+##  application manager
+##
+################################################################################
+
+`
+
+const sectionChainApplicationManager = `  [chain.manager]
+  # application manager name defines the module to use for handling
+  # the transactions.  Supported names are "erismint"
+  name = "{{.Name}}"
+  # version is the major and minor semantic version;
+  # the version will be asserted on
+  major_version = {{.MajorVersion}}
+  minor_version = {{.MinorVersion}}
+  # relative path to application manager root folder
+  relative_root = "{{.ModuleRelativeRoot}}"
+
+  `
+
+const separatorServerConfiguration = `
+################################################################################
+################################################################################
+##
+## Server configurations
+##
+################################################################################
+################################################################################
+
+`
+
+// TODO: [ben] map entries to structure defined in eris-db
+const sectionServers = `[servers]
+
+  [servers.bind]
+  address = ""
+  port = 1337
+
+  [servers.tls]
+  tls = false
+  cert_path = ""
+  key_path = ""
+
+  [servers.cors]
+  enable = false
+  allow_origins = []
+  allow_credentials = false
+  allow_methods = []
+  allow_headers = []
+  expose_headers = []
+  max_age = 0
+
+  [servers.http]
+  json_rpc_endpoint = "/rpc"
+
+  [servers.websocket]
+  endpoint = "/socketrpc"
+  max_sessions = 50
+  read_buffer_size = 4096
+  write_buffer_size = 4096
+
+	[servers.tendermint]
+	# Multiple listeners can be separated with a comma
+	rpc_local_address = "0.0.0.0:46657"
+	endpoint = "/websocket"
+
+  [servers.logging]
+  console_log_level = "info"
+  file_log_level = "warn"
+  log_file = ""
+
+  `
+
+const separatorModules = `
+################################################################################
+################################################################################
+##
+## Module configurations - dynamically loaded based on chain configuration
+##
+################################################################################
+################################################################################
+
+`
+
+// TODO: [ben] minimal fields have been made configurable; expand where needed
+const sectionTendermint = `
+################################################################################
+##
+## Tendermint
+## version 0.8
+##
+## in-process execution of Tendermint consensus engine
+##
+################################################################################
+
+[tendermint]
+# private validator file is used by tendermint to keep the status
+# of the private validator, but also (currently) holds the private key
+# for the private vaildator to sign with.  This private key needs to be moved
+# out and directly managed by eris-keys
+# This file needs to be in the root directory
+private_validator_file = "priv_validator.json"
+
+  # Tendermint requires additional configuration parameters.
+  # Eris-DB's tendermint consensus module will load [tendermint.configuration]
+  # as the configuration for Tendermint.
+  # Eris-DB will respect the configurations set in this file where applicable,
+  # but reserves the option to override or block conflicting settings.
+  [tendermint.configuration]
+  # moniker is the name of the node on the tendermint p2p network
+  moniker = "{{.Moniker}}"
+  # seeds lists the peers tendermint can connect to join the network
+  seeds = "{{.Seeds}}"
+  # fast_sync allows a tendermint node to catch up faster when joining
+  # the network.
+  # NOTE: Tendermint has reported potential issues with fast_sync enabled.
+  # The recommended setting is for keeping it disabled.
+  fast_sync = {{.FastSync}}
+  # database backend to use for Tendermint. Supported "leveldb" and "memdb".
+  db_backend = "leveldb"
+  # logging level. Supported "error" < "warn" < "notice" < "info" < "debug"
+  log_level = "info"
+  # node local address
+  node_laddr = "0.0.0.0:46656"
+  # rpc local address
+	# NOTE: value is ignored when run in-process as RPC is
+	# handled by [servers.tendermint]
+  rpc_laddr = "0.0.0.0:46657"
+  # proxy application address - used for abci connections,
+  # and this port should not be exposed for in-process Tendermint
+  proxy_app = "tcp://127.0.0.1:46658"
+
+  # Extended Tendermint configuration settings
+  # for reference to Tendermint see https://github.com/tendermint/tendermint/blob/master/config/tendermint/config.go
+
+  # genesis_file = "./data/tendermint/genesis.json"
+  # skip_upnp = false
+  # addrbook_file = "./data/tendermint/addrbook.json"
+  # priv_validator_file = "./data/tendermint/priv_validator.json"
+  # db_dir = "./data/tendermint/data"
+  # prof_laddr = ""
+  # revision_file = "./data/tendermint/revision"
+  # cswal = "./data/tendermint/data/cswal"
+  # cswal_light = false
+
+  # block_size = 10000
+  # disable_data_hash = false
+  # timeout_propose = 3000
+  # timeout_propose_delta = 500
+  # timeout_prevote = 1000
+  # timeout_prevote_delta = 500
+  # timeout_precommit = 1000
+  # timeout_precommit_delta = 500
+  # timeout_commit = 1000
+  # mempool_recheck = true
+  # mempool_recheck_empty = true
+  # mempool_broadcast = true
+
+		[tendermint.configuration.p2p]
+		# Switch config keys
+		dial_timeout_seconds = 3
+		handshake_timeout_seconds = 20
+		max_num_peers = 20
+		authenticated_encryption = true
+
+		# MConnection config keys
+		send_rate = 512000
+		recv_rate = 512000
+
+		# Fuzz params
+		fuzz_enable = false # use the fuzz wrapped conn
+		fuzz_active = false # toggle fuzzing
+		fuzz_mode = "drop"  # eg. drop, delay
+		fuzz_max_delay_milliseconds = 3000
+		fuzz_prob_drop_rw = 0.2
+		fuzz_prob_drop_conn = 0.00
+		fuzz_prob_sleep = 0.00
+
+`
+
+const sectionErisMint = `
+################################################################################
+##
+## Eris-Mint
+## version 0.16
+##
+## The original Ethereum virtual machine with IAVL merkle trees
+## and tendermint/go-wire encoding
+##
+################################################################################
+
+[erismint]
+# Database backend to use for ErisMint state database.
+# Supported "leveldb" and "memdb".
+db_backend = "leveldb"
+# tendermint host address needs to correspond to tendermints configuration
+# of the rpc local address
+tendermint_host = "0.0.0.0:46657"
+
+`
diff --git a/config/viper.go b/config/viper.go
new file mode 100644
index 0000000000000000000000000000000000000000..cefd2f2a8f5ec3b0abc89dd83f0dafa0f6b60951
--- /dev/null
+++ b/config/viper.go
@@ -0,0 +1,44 @@
+// 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 config
+
+import (
+	"fmt"
+
+	"github.com/spf13/viper"
+)
+
+// Safely get the subtree from a viper config, returning an error if it could not
+// be obtained for any reason.
+func ViperSubConfig(conf *viper.Viper, configSubtreePath string) (subConfig *viper.Viper, err error) {
+	// Viper internally panics if `moduleName` contains an unallowed
+	// character (eg, a dash).
+	defer func() {
+		if r := recover(); r != nil {
+			err = fmt.Errorf("Viper panicked trying to read config subtree: %s",
+				configSubtreePath)
+		}
+	}()
+	if !conf.IsSet(configSubtreePath) {
+		return nil, fmt.Errorf("Failed to read config subtree: %s",
+			configSubtreePath)
+	}
+	subConfig = conf.Sub(configSubtreePath)
+	if subConfig == nil {
+		return nil, fmt.Errorf("Failed to read config subtree: %s",
+			configSubtreePath)
+	}
+	return subConfig, err
+}
diff --git a/consensus/config.go b/consensus/config.go
index d676d8c214f8c794aaea43a845260f9407d2d311..05cc488f158d93dde57ec0ab46326d29b76b13a5 100644
--- a/consensus/config.go
+++ b/consensus/config.go
@@ -1,28 +1,22 @@
-// Copyright 2015, 2016 Eris Industries (UK) Ltd.
-// This file is part of Eris-RT
-
-// Eris-RT is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-
-// Eris-RT is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License
-// along with Eris-RT.  If not, see <http://www.gnu.org/licenses/>.
-
-// version provides the current Eris-DB version and a VersionIdentifier
-// for the modules to identify their version with.
+// 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 consensus
 
 import (
 	// noops      "github.com/eris-ltd/eris-db/consensus/noops"
 	tendermint "github.com/eris-ltd/eris-db/consensus/tendermint"
-	tmsp "github.com/eris-ltd/eris-db/consensus/tmsp"
 )
 
 //------------------------------------------------------------------------------
@@ -34,8 +28,6 @@ func AssertValidConsensusModule(name, minorVersionString string) bool {
 		// noops should not have any external interfaces that can change
 		// over iterations
 		return true
-	case "tmsp":
-		return minorVersionString == tmsp.GetTmspVersion().GetMinorVersionString()
 	case "tendermint":
 		return minorVersionString == tendermint.GetTendermintVersion().GetMinorVersionString()
 	case "bigchaindb":
diff --git a/consensus/consensus.go b/consensus/consensus.go
index f0795a5dde853f3ec6ee1aa046241aba5c25d250..77b7ffff3e0b6a9be768bca2f7de5450e7c6bc2b 100644
--- a/consensus/consensus.go
+++ b/consensus/consensus.go
@@ -1,18 +1,16 @@
-// Copyright 2015, 2016 Eris Industries (UK) Ltd.
-// This file is part of Eris-RT
-
-// Eris-RT is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-
-// Eris-RT is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License
-// along with Eris-RT.  If not, see <http://www.gnu.org/licenses/>.
+// 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 consensus
 
@@ -28,13 +26,13 @@ func LoadConsensusEngineInPipe(moduleConfig *config.ModuleConfig,
 	pipe definitions.Pipe) error {
 	switch moduleConfig.Name {
 	case "tendermint":
-		tendermint, err := tendermint.NewTendermint(moduleConfig,
-			pipe.GetApplication())
+		tmint, err := tendermint.NewTendermint(moduleConfig, pipe.GetApplication(),
+			pipe.Logger().With())
 		if err != nil {
 			return fmt.Errorf("Failed to load Tendermint node: %v", err)
 		}
 
-		err = pipe.SetConsensusEngine(tendermint)
+		err = pipe.SetConsensusEngine(tmint)
 		if err != nil {
 			return fmt.Errorf("Failed to load Tendermint in pipe as "+
 				"ConsensusEngine: %v", err)
@@ -42,7 +40,7 @@ func LoadConsensusEngineInPipe(moduleConfig *config.ModuleConfig,
 
 		// For Tendermint we have a coupled Blockchain and ConsensusEngine
 		// implementation, so load it at the same time as ConsensusEngine
-		err = pipe.SetBlockchain(tendermint)
+		err = pipe.SetBlockchain(tmint)
 		if err != nil {
 			return fmt.Errorf("Failed to load Tendermint in pipe as "+
 				"Blockchain: %v", err)
diff --git a/consensus/tendermint/config.go b/consensus/tendermint/config.go
index 1bbb74bd6aa35be73c28c7bb75adea040cfddfbb..b8c89d241d175d442b1550b09619b852a37f7b2c 100644
--- a/consensus/tendermint/config.go
+++ b/consensus/tendermint/config.go
@@ -1,21 +1,16 @@
-// Copyright 2015, 2016 Eris Industries (UK) Ltd.
-// This file is part of Eris-RT
-
-// Eris-RT is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-
-// Eris-RT is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License
-// along with Eris-RT.  If not, see <http://www.gnu.org/licenses/>.
-
-// version provides the current Eris-DB version and a VersionIdentifier
-// for the modules to identify their version with.
+// 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 tendermint
 
@@ -23,10 +18,10 @@ import (
 	"path"
 	"time"
 
-	viper "github.com/spf13/viper"
+	"github.com/spf13/viper"
 	tendermintConfig "github.com/tendermint/go-config"
 
-	config "github.com/eris-ltd/eris-db/config"
+	"github.com/eris-ltd/eris-db/config"
 )
 
 // NOTE [ben] Compiler check to ensure TendermintConfig successfully implements
@@ -56,6 +51,10 @@ func GetTendermintConfig(loadedConfig *viper.Viper) *TendermintConfig {
 //------------------------------------------------------------------------------
 // Tendermint defaults
 
+//
+// Contract
+//
+
 func (tmintConfig *TendermintConfig) AssertTendermintDefaults(chainId, workDir,
 	dataDir, rootDir string) {
 
@@ -69,6 +68,8 @@ func (tmintConfig *TendermintConfig) AssertTendermintDefaults(chainId, workDir,
 	tmintConfig.SetDefault("fast_sync", true)
 	tmintConfig.SetDefault("skip_upnp", false)
 	tmintConfig.SetDefault("addrbook_file", path.Join(rootDir, "addrbook.json"))
+	tmintConfig.SetDefault("addrbook_strict", true) // disable to allow connections locally
+	tmintConfig.SetDefault("pex_reactor", false)    // enable for peer exchange
 	tmintConfig.SetDefault("priv_validator_file", path.Join(rootDir, "priv_validator.json"))
 	tmintConfig.SetDefault("db_backend", "leveldb")
 	tmintConfig.SetDefault("db_dir", dataDir)
@@ -76,10 +77,12 @@ func (tmintConfig *TendermintConfig) AssertTendermintDefaults(chainId, workDir,
 	tmintConfig.SetDefault("rpc_laddr", "")
 	tmintConfig.SetDefault("prof_laddr", "")
 	tmintConfig.SetDefault("revision_file", path.Join(workDir, "revision"))
-	tmintConfig.SetDefault("cswal", path.Join(dataDir, "cswal"))
-	tmintConfig.SetDefault("cswal_light", false)
+	tmintConfig.SetDefault("cs_wal_dir", path.Join(dataDir, "cs.wal"))
+	tmintConfig.SetDefault("cs_wal_light", false)
+	tmintConfig.SetDefault("filter_peers", false)
 
-	tmintConfig.SetDefault("block_size", 10000)
+	tmintConfig.SetDefault("block_size", 10000)      // max number of txs
+	tmintConfig.SetDefault("block_part_size", 65536) // part size 64K
 	tmintConfig.SetDefault("disable_data_hash", false)
 	tmintConfig.SetDefault("timeout_propose", 3000)
 	tmintConfig.SetDefault("timeout_propose_delta", 500)
@@ -88,9 +91,12 @@ func (tmintConfig *TendermintConfig) AssertTendermintDefaults(chainId, workDir,
 	tmintConfig.SetDefault("timeout_precommit", 1000)
 	tmintConfig.SetDefault("timeout_precommit_delta", 500)
 	tmintConfig.SetDefault("timeout_commit", 1000)
+	// make progress asap (no `timeout_commit`) on full precommit votes
+	tmintConfig.SetDefault("skip_timeout_commit", false)
 	tmintConfig.SetDefault("mempool_recheck", true)
 	tmintConfig.SetDefault("mempool_recheck_empty", true)
 	tmintConfig.SetDefault("mempool_broadcast", true)
+	tmintConfig.SetDefault("mempool_wal_dir", path.Join(dataDir, "mempool.wal"))
 }
 
 //------------------------------------------------------------------------------
@@ -147,7 +153,8 @@ func (tmintConfig *TendermintConfig) GetMapString(key string) map[string]string
 func (tmintConfig *TendermintConfig) GetConfig(key string) tendermintConfig.Config {
 	// TODO: [ben] log out a warning as this indicates a potentially breaking code
 	// change from Tendermints side
-	if !tmintConfig.subTree.IsSet(key) {
+	subTree, _ := config.ViperSubConfig(tmintConfig.subTree, key)
+	if subTree == nil {
 		return &TendermintConfig{
 			subTree: viper.New(),
 		}
diff --git a/consensus/tendermint/local_client.go b/consensus/tendermint/local_client.go
deleted file mode 100644
index 97b732cac6ab66237ce6250478a6a886855a3b6f..0000000000000000000000000000000000000000
--- a/consensus/tendermint/local_client.go
+++ /dev/null
@@ -1,270 +0,0 @@
-// Copyright 2015, 2016 Eris Industries (UK) Ltd.
-// This file is part of Eris-RT
-
-// Eris-RT is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-
-// Eris-RT is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License
-// along with Eris-RT.  If not, see <http://www.gnu.org/licenses/>.
-
-// version provides the current Eris-DB version and a VersionIdentifier
-// for the modules to identify their version with.
-
-// This file is originally based on github.com/tendermint/tmsp/client/...
-// .../local_client.go
-
-package tendermint
-
-import (
-	"sync"
-
-	tmsp_client "github.com/tendermint/tmsp/client"
-	tmsp_types "github.com/tendermint/tmsp/types"
-
-	manager_types "github.com/eris-ltd/eris-db/manager/types"
-)
-
-// NOTE [ben] Compiler check to ensure localClient successfully implements
-// tendermint/tmsp/client
-var _ tmsp_client.Client = (*localClient)(nil)
-
-type localClient struct {
-	mtx         *sync.Mutex
-	Application manager_types.Application
-	Callback    tmsp_client.Callback
-}
-
-func NewLocalClient(mtx *sync.Mutex, app manager_types.Application) *localClient {
-	if mtx == nil {
-		mtx = new(sync.Mutex)
-	}
-	return &localClient{
-		mtx:         mtx,
-		Application: app,
-	}
-}
-
-func (app *localClient) SetResponseCallback(cb tmsp_client.Callback) {
-	app.mtx.Lock()
-	defer app.mtx.Unlock()
-	app.Callback = cb
-}
-
-// TODO: change manager_types.Application to include Error()?
-func (app *localClient) Error() error {
-	return nil
-}
-
-func (app *localClient) Stop() bool {
-	return true
-}
-
-func (app *localClient) FlushAsync() *tmsp_client.ReqRes {
-	// Do nothing
-	return newLocalReqRes(tmsp_types.ToRequestFlush(), nil)
-}
-
-func (app *localClient) EchoAsync(msg string) *tmsp_client.ReqRes {
-	return app.callback(
-		tmsp_types.ToRequestEcho(msg),
-		tmsp_types.ToResponseEcho(msg),
-	)
-}
-
-func (app *localClient) InfoAsync() *tmsp_client.ReqRes {
-	app.mtx.Lock()
-	info := app.Application.Info()
-	app.mtx.Unlock()
-	return app.callback(
-		tmsp_types.ToRequestInfo(),
-		tmsp_types.ToResponseInfo(info),
-	)
-}
-
-func (app *localClient) SetOptionAsync(key string, value string) *tmsp_client.ReqRes {
-	app.mtx.Lock()
-	log := app.Application.SetOption(key, value)
-	app.mtx.Unlock()
-	return app.callback(
-		tmsp_types.ToRequestSetOption(key, value),
-		tmsp_types.ToResponseSetOption(log),
-	)
-}
-
-func (app *localClient) AppendTxAsync(tx []byte) *tmsp_client.ReqRes {
-	app.mtx.Lock()
-	res := app.Application.AppendTx(tx)
-	app.mtx.Unlock()
-	return app.callback(
-		tmsp_types.ToRequestAppendTx(tx),
-		tmsp_types.ToResponseAppendTx(res.Code, res.Data, res.Log),
-	)
-}
-
-func (app *localClient) CheckTxAsync(tx []byte) *tmsp_client.ReqRes {
-	app.mtx.Lock()
-	res := app.Application.CheckTx(tx)
-	app.mtx.Unlock()
-	return app.callback(
-		tmsp_types.ToRequestCheckTx(tx),
-		tmsp_types.ToResponseCheckTx(res.Code, res.Data, res.Log),
-	)
-}
-
-func (app *localClient) QueryAsync(tx []byte) *tmsp_client.ReqRes {
-	app.mtx.Lock()
-	res := app.Application.Query(tx)
-	app.mtx.Unlock()
-	return app.callback(
-		tmsp_types.ToRequestQuery(tx),
-		tmsp_types.ToResponseQuery(res.Code, res.Data, res.Log),
-	)
-}
-
-func (app *localClient) CommitAsync() *tmsp_client.ReqRes {
-	app.mtx.Lock()
-	res := app.Application.Commit()
-	app.mtx.Unlock()
-	return app.callback(
-		tmsp_types.ToRequestCommit(),
-		tmsp_types.ToResponseCommit(res.Code, res.Data, res.Log),
-	)
-}
-
-func (app *localClient) InitChainAsync(validators []*tmsp_types.Validator) *tmsp_client.ReqRes {
-	app.mtx.Lock()
-	if bcApp, ok := app.Application.(tmsp_types.BlockchainAware); ok {
-		bcApp.InitChain(validators)
-	}
-	reqRes := app.callback(
-		tmsp_types.ToRequestInitChain(validators),
-		tmsp_types.ToResponseInitChain(),
-	)
-	app.mtx.Unlock()
-	return reqRes
-}
-
-func (app *localClient) BeginBlockAsync(height uint64) *tmsp_client.ReqRes {
-	app.mtx.Lock()
-	if bcApp, ok := app.Application.(tmsp_types.BlockchainAware); ok {
-		bcApp.BeginBlock(height)
-	}
-	app.mtx.Unlock()
-	return app.callback(
-		tmsp_types.ToRequestBeginBlock(height),
-		tmsp_types.ToResponseBeginBlock(),
-	)
-}
-
-func (app *localClient) EndBlockAsync(height uint64) *tmsp_client.ReqRes {
-	app.mtx.Lock()
-	var validators []*tmsp_types.Validator
-	if bcApp, ok := app.Application.(tmsp_types.BlockchainAware); ok {
-		validators = bcApp.EndBlock(height)
-	}
-	app.mtx.Unlock()
-	return app.callback(
-		tmsp_types.ToRequestEndBlock(height),
-		tmsp_types.ToResponseEndBlock(validators),
-	)
-}
-
-//-------------------------------------------------------
-
-func (app *localClient) FlushSync() error {
-	return nil
-}
-
-func (app *localClient) EchoSync(msg string) (res tmsp_types.Result) {
-	return tmsp_types.OK.SetData([]byte(msg))
-}
-
-func (app *localClient) InfoSync() (res tmsp_types.Result) {
-	app.mtx.Lock()
-	info := app.Application.Info()
-	app.mtx.Unlock()
-	return tmsp_types.OK.SetData([]byte(info))
-}
-
-func (app *localClient) SetOptionSync(key string, value string) (res tmsp_types.Result) {
-	app.mtx.Lock()
-	log := app.Application.SetOption(key, value)
-	app.mtx.Unlock()
-	return tmsp_types.OK.SetLog(log)
-}
-
-func (app *localClient) AppendTxSync(tx []byte) (res tmsp_types.Result) {
-	app.mtx.Lock()
-	res = app.Application.AppendTx(tx)
-	app.mtx.Unlock()
-	return res
-}
-
-func (app *localClient) CheckTxSync(tx []byte) (res tmsp_types.Result) {
-	app.mtx.Lock()
-	res = app.Application.CheckTx(tx)
-	app.mtx.Unlock()
-	return res
-}
-
-func (app *localClient) QuerySync(query []byte) (res tmsp_types.Result) {
-	app.mtx.Lock()
-	res = app.Application.Query(query)
-	app.mtx.Unlock()
-	return res
-}
-
-func (app *localClient) CommitSync() (res tmsp_types.Result) {
-	app.mtx.Lock()
-	res = app.Application.Commit()
-	app.mtx.Unlock()
-	return res
-}
-
-func (app *localClient) InitChainSync(validators []*tmsp_types.Validator) (err error) {
-	app.mtx.Lock()
-	if bcApp, ok := app.Application.(tmsp_types.BlockchainAware); ok {
-		bcApp.InitChain(validators)
-	}
-	app.mtx.Unlock()
-	return nil
-}
-
-func (app *localClient) BeginBlockSync(height uint64) (err error) {
-	app.mtx.Lock()
-	if bcApp, ok := app.Application.(tmsp_types.BlockchainAware); ok {
-		bcApp.BeginBlock(height)
-	}
-	app.mtx.Unlock()
-	return nil
-}
-
-func (app *localClient) EndBlockSync(height uint64) (changedValidators []*tmsp_types.Validator, err error) {
-	app.mtx.Lock()
-	if bcApp, ok := app.Application.(tmsp_types.BlockchainAware); ok {
-		changedValidators = bcApp.EndBlock(height)
-	}
-	app.mtx.Unlock()
-	return changedValidators, nil
-}
-
-//-------------------------------------------------------
-
-func (app *localClient) callback(req *tmsp_types.Request, res *tmsp_types.Response) *tmsp_client.ReqRes {
-	app.Callback(req, res)
-	return newLocalReqRes(req, res)
-}
-
-func newLocalReqRes(req *tmsp_types.Request, res *tmsp_types.Response) *tmsp_client.ReqRes {
-	reqRes := tmsp_client.NewReqRes(req)
-	reqRes.Response = res
-	reqRes.SetDone()
-	return reqRes
-}
diff --git a/consensus/tendermint/tendermint.go b/consensus/tendermint/tendermint.go
index 237fb4a0bd9b3da558fa73a7014b0f14546db661..2eda6171daa4742efe486bb1c958128299fb99e0 100644
--- a/consensus/tendermint/tendermint.go
+++ b/consensus/tendermint/tendermint.go
@@ -1,21 +1,16 @@
-// Copyright 2015, 2016 Eris Industries (UK) Ltd.
-// This file is part of Eris-RT
-
-// Eris-RT is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-
-// Eris-RT is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License
-// along with Eris-RT.  If not, see <http://www.gnu.org/licenses/>.
-
-// version provides the current Eris-DB version and a VersionIdentifier
-// for the modules to identify their version with.
+// 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 tendermint
 
@@ -23,24 +18,24 @@ import (
 	"fmt"
 	"path"
 	"strings"
-	"sync"
 
+	abci_types "github.com/tendermint/abci/types"
 	crypto "github.com/tendermint/go-crypto"
 	p2p "github.com/tendermint/go-p2p"
 	tendermint_consensus "github.com/tendermint/tendermint/consensus"
 	node "github.com/tendermint/tendermint/node"
 	proxy "github.com/tendermint/tendermint/proxy"
 	tendermint_types "github.com/tendermint/tendermint/types"
-	tmsp_types "github.com/tendermint/tmsp/types"
 
 	edb_event "github.com/eris-ltd/eris-db/event"
-	log "github.com/eris-ltd/eris-logger"
 
 	config "github.com/eris-ltd/eris-db/config"
 	manager_types "github.com/eris-ltd/eris-db/manager/types"
 	// files  "github.com/eris-ltd/eris-db/files"
 	blockchain_types "github.com/eris-ltd/eris-db/blockchain/types"
 	consensus_types "github.com/eris-ltd/eris-db/consensus/types"
+	"github.com/eris-ltd/eris-db/logging"
+	"github.com/eris-ltd/eris-db/logging/loggers"
 	"github.com/eris-ltd/eris-db/txs"
 	"github.com/tendermint/go-wire"
 )
@@ -49,6 +44,7 @@ type Tendermint struct {
 	tmintNode   *node.Node
 	tmintConfig *TendermintConfig
 	chainId     string
+	logger      loggers.InfoTraceLogger
 }
 
 // Compiler checks to ensure Tendermint successfully implements
@@ -57,7 +53,8 @@ var _ consensus_types.ConsensusEngine = (*Tendermint)(nil)
 var _ blockchain_types.Blockchain = (*Tendermint)(nil)
 
 func NewTendermint(moduleConfig *config.ModuleConfig,
-	application manager_types.Application) (*Tendermint, error) {
+	application manager_types.Application,
+	logger loggers.InfoTraceLogger) (*Tendermint, error) {
 	// re-assert proper configuration for module
 	if moduleConfig.Version != GetTendermintVersion().GetMinorVersionString() {
 		return nil, fmt.Errorf("Version string %s did not match %s",
@@ -71,10 +68,10 @@ func NewTendermint(moduleConfig *config.ModuleConfig,
 	if !moduleConfig.Config.IsSet("configuration") {
 		return nil, fmt.Errorf("Failed to extract Tendermint configuration subtree.")
 	}
-	tendermintConfigViper := moduleConfig.Config.Sub("configuration")
+	tendermintConfigViper, err := config.ViperSubConfig(moduleConfig.Config, "configuration")
 	if tendermintConfigViper == nil {
 		return nil,
-			fmt.Errorf("Failed to extract Tendermint configuration subtree.")
+			fmt.Errorf("Failed to extract Tendermint configuration subtree: %s", err)
 	}
 	// wrap a copy of the viper config in a tendermint/go-config interface
 	tmintConfig := GetTendermintConfig(tendermintConfigViper)
@@ -92,18 +89,19 @@ func NewTendermint(moduleConfig *config.ModuleConfig,
 	tmintConfig.AssertTendermintConsistency(moduleConfig,
 		privateValidatorFilePath)
 	chainId := tmintConfig.GetString("chain_id")
-	log.WithFields(log.Fields{
-		"chainId":              chainId,
-		"genesisFile":          tmintConfig.GetString("genesis_file"),
-		"nodeLocalAddress":     tmintConfig.GetString("node_laddr"),
-		"moniker":              tmintConfig.GetString("moniker"),
-		"seeds":                tmintConfig.GetString("seeds"),
-		"fastSync":             tmintConfig.GetBool("fast_sync"),
-		"rpcLocalAddress":      tmintConfig.GetString("rpc_laddr"),
-		"databaseDirectory":    tmintConfig.GetString("db_dir"),
-		"privateValidatorFile": tmintConfig.GetString("priv_validator_file"),
-		"privValFile":          moduleConfig.Config.GetString("private_validator_file"),
-	}).Debug("Loaded Tendermint sub-configuration")
+
+	logging.TraceMsg(logger, "Loaded Tendermint sub-configuration",
+		"chainId", chainId,
+		"genesisFile", tmintConfig.GetString("genesis_file"),
+		"nodeLocalAddress", tmintConfig.GetString("node_laddr"),
+		"moniker", tmintConfig.GetString("moniker"),
+		"seeds", tmintConfig.GetString("seeds"),
+		"fastSync", tmintConfig.GetBool("fast_sync"),
+		"rpcLocalAddress", tmintConfig.GetString("rpc_laddr"),
+		"databaseDirectory", tmintConfig.GetString("db_dir"),
+		"privateValidatorFile", tmintConfig.GetString("priv_validator_file"),
+		"privValFile", moduleConfig.Config.GetString("private_validator_file"))
+
 	// TODO: [ben] do not "or Generate Validator keys", rather fail directly
 	// TODO: [ben] implement the signer for Private validator over eris-keys
 	// TODO: [ben] copy from rootDir to tendermint workingDir;
@@ -116,15 +114,13 @@ func NewTendermint(moduleConfig *config.ModuleConfig,
 	// not running the tendermint RPC as it could lead to unexpected behaviour,
 	// not least if we accidentally try to run it on the same address as our own
 	if tmintConfig.GetString("rpc_laddr") != "" {
-		log.Warnf("Force disabling Tendermint's native RPC, which had been set to "+
-			"run on '%s' in the Tendermint config.", tmintConfig.GetString("rpc_laddr"))
+		logging.InfoMsg(logger, "Force disabling Tendermint's native RPC",
+			"provided_rpc_laddr", tmintConfig.GetString("rpc_laddr"))
 		tmintConfig.Set("rpc_laddr", "")
 	}
 
-	newNode := node.NewNode(tmintConfig, privateValidator, func(_, _ string,
-		hash []byte) proxy.AppConn {
-		return NewLocalClient(new(sync.Mutex), application)
-	})
+	newNode := node.NewNode(tmintConfig, privateValidator,
+		proxy.NewLocalClientCreator(application))
 
 	listener := p2p.NewDefaultListener("tcp", tmintConfig.GetString("node_laddr"),
 		tmintConfig.GetBool("skip_upnp"))
@@ -136,26 +132,25 @@ func NewTendermint(moduleConfig *config.ModuleConfig,
 		newNode.Stop()
 		return nil, fmt.Errorf("Failed to start Tendermint consensus node: %v", err)
 	}
-	log.WithFields(log.Fields{
-		"nodeAddress":       tmintConfig.GetString("node_laddr"),
-		"transportProtocol": "tcp",
-		"upnp":              !tmintConfig.GetBool("skip_upnp"),
-		"moniker":           tmintConfig.GetString("moniker"),
-	}).Info("Tendermint consensus node started")
+	logging.InfoMsg(logger, "Tendermint consensus node started",
+		"nodeAddress", tmintConfig.GetString("node_laddr"),
+		"transportProtocol", "tcp",
+		"upnp", !tmintConfig.GetBool("skip_upnp"),
+		"moniker", tmintConfig.GetString("moniker"))
 
 	// If seedNode is provided by config, dial out.
 	if tmintConfig.GetString("seeds") != "" {
 		seeds := strings.Split(tmintConfig.GetString("seeds"), ",")
 		newNode.DialSeeds(seeds)
-		log.WithFields(log.Fields{
-			"seeds": seeds,
-		}).Debug("Tendermint node called seeds")
+		logging.TraceMsg(logger, "Tendermint node called seeds",
+			"seeds", seeds)
 	}
 
 	return &Tendermint{
 		tmintNode:   newNode,
 		tmintConfig: tmintConfig,
 		chainId:     chainId,
+		logger:      logger,
 	}, nil
 }
 
@@ -228,11 +223,11 @@ func (tendermint *Tendermint) PublicValidatorKey() crypto.PubKey {
 }
 
 func (tendermint *Tendermint) Events() edb_event.EventEmitter {
-	return edb_event.NewEvents(tendermint.tmintNode.EventSwitch())
+	return edb_event.NewEvents(tendermint.tmintNode.EventSwitch(), tendermint.logger)
 }
 
 func (tendermint *Tendermint) BroadcastTransaction(transaction []byte,
-	callback func(*tmsp_types.Response)) error {
+	callback func(*abci_types.Response)) error {
 	return tendermint.tmintNode.MempoolReactor().BroadcastTx(transaction, callback)
 }
 
diff --git a/consensus/tendermint/version.go b/consensus/tendermint/version.go
index 870d1313bf43977a8976f0415d07f1aa5d1f2b2d..78ed5dea5ec3df5e07a19520959e371e8f2ece73 100644
--- a/consensus/tendermint/version.go
+++ b/consensus/tendermint/version.go
@@ -1,18 +1,16 @@
-// Copyright 2015, 2016 Eris Industries (UK) Ltd.
-// This file is part of Eris-RT
-
-// Eris-RT is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-
-// Eris-RT is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License
-// along with Eris-RT.  If not, see <http://www.gnu.org/licenses/>.
+// 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 tendermint
 
@@ -30,7 +28,7 @@ const (
 	// Major version component of the current release
 	tendermintVersionMajorConst uint8 = 0
 	// Minor version component of the current release
-	tendermintVersionMinorConst uint8 = 6
+	tendermintVersionMinorConst uint8 = 8
 	// Patch version component of the current release
 	tendermintVersionPatchConst uint8 = 0
 )
diff --git a/consensus/tendermint/version_test.go b/consensus/tendermint/version_test.go
index 25985ec115142e63d0956c8ea9bf311b8ce2e08c..bfbbe3e762bde36304cf59379b04c94d13cff4ae 100644
--- a/consensus/tendermint/version_test.go
+++ b/consensus/tendermint/version_test.go
@@ -1,18 +1,16 @@
-// Copyright 2015, 2016 Eris Industries (UK) Ltd.
-// This file is part of Eris-RT
-
-// Eris-RT is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-
-// Eris-RT is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License
-// along with Eris-RT.  If not, see <http://www.gnu.org/licenses/>.
+// 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 tendermint
 
diff --git a/consensus/tmsp/server.go b/consensus/tmsp/server.go
deleted file mode 100644
index 62abb9d641d747b748972e02e1b1d9b77ebacf47..0000000000000000000000000000000000000000
--- a/consensus/tmsp/server.go
+++ /dev/null
@@ -1,211 +0,0 @@
-// Copyright 2015, 2016 Eris Industries (UK) Ltd.
-// This file is part of Eris-RT
-
-// Eris-RT is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-
-// Eris-RT is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License
-// along with Eris-RT.  If not, see <http://www.gnu.org/licenses/>.
-
-// Taken originally from github.com/tendermint/tmsp/server.go
-
-package tmsp
-
-import (
-	"bufio"
-	"fmt"
-	"io"
-	"net"
-	"strings"
-	"sync"
-
-	. "github.com/tendermint/go-common"
-	tmsp_types "github.com/tendermint/tmsp/types"
-
-	manager_types "github.com/eris-ltd/eris-db/manager/types"
-)
-
-// var maxNumberConnections = 2
-
-type Server struct {
-	QuitService
-
-	proto    string
-	addr     string
-	listener net.Listener
-
-	appMtx sync.Mutex
-	app    manager_types.Application
-}
-
-func NewServer(protoAddr string, app manager_types.Application) (*Server, error) {
-	parts := strings.SplitN(protoAddr, "://", 2)
-	proto, addr := parts[0], parts[1]
-	s := &Server{
-		proto:    proto,
-		addr:     addr,
-		listener: nil,
-		app:      app,
-	}
-	s.QuitService = *NewQuitService(nil, "TMSPServer", s)
-	_, err := s.Start() // Just start it
-	return s, err
-}
-
-func (s *Server) OnStart() error {
-	s.QuitService.OnStart()
-	ln, err := net.Listen(s.proto, s.addr)
-	if err != nil {
-		return err
-	}
-	s.listener = ln
-	go s.acceptConnectionsRoutine()
-	return nil
-}
-
-func (s *Server) OnStop() {
-	s.QuitService.OnStop()
-	s.listener.Close()
-}
-
-func (s *Server) acceptConnectionsRoutine() {
-	// semaphore := make(chan struct{}, maxNumberConnections)
-
-	for {
-		// semaphore <- struct{}{}
-
-		// Accept a connection
-		fmt.Println("Waiting for new connection...")
-		conn, err := s.listener.Accept()
-		if err != nil {
-			if !s.IsRunning() {
-				return // Ignore error from listener closing.
-			}
-			Exit("Failed to accept connection: " + err.Error())
-		} else {
-			fmt.Println("Accepted a new connection")
-		}
-
-		closeConn := make(chan error, 2)                   // Push to signal connection closed
-		responses := make(chan *tmsp_types.Response, 1000) // A channel to buffer responses
-
-		// Read requests from conn and deal with them
-		go s.handleRequests(closeConn, conn, responses)
-		// Pull responses from 'responses' and write them to conn.
-		go s.handleResponses(closeConn, responses, conn)
-
-		go func() {
-			// Wait until signal to close connection
-			errClose := <-closeConn
-			if errClose != nil {
-				fmt.Printf("Connection error: %v\n", errClose)
-			} else {
-				fmt.Println("Connection was closed.")
-			}
-
-			// Close the connection
-			err := conn.Close()
-			if err != nil {
-				fmt.Printf("Error in closing connection: %v\n", err)
-			}
-
-			// <-semaphore
-		}()
-	}
-}
-
-// Read requests from conn and deal with them
-func (s *Server) handleRequests(closeConn chan error, conn net.Conn, responses chan<- *tmsp_types.Response) {
-	var count int
-	var bufReader = bufio.NewReader(conn)
-	for {
-
-		var req = &tmsp_types.Request{}
-		err := tmsp_types.ReadMessage(bufReader, req)
-		if err != nil {
-			if err == io.EOF {
-				closeConn <- fmt.Errorf("Connection closed by client")
-			} else {
-				closeConn <- fmt.Errorf("Error in handleRequests: %v", err.Error())
-			}
-			return
-		}
-		s.appMtx.Lock()
-		count++
-		s.handleRequest(req, responses)
-		s.appMtx.Unlock()
-	}
-}
-
-func (s *Server) handleRequest(req *tmsp_types.Request, responses chan<- *tmsp_types.Response) {
-	switch r := req.Value.(type) {
-	case *tmsp_types.Request_Echo:
-		responses <- tmsp_types.ToResponseEcho(r.Echo.Message)
-	case *tmsp_types.Request_Flush:
-		responses <- tmsp_types.ToResponseFlush()
-	case *tmsp_types.Request_Info:
-		data := s.app.Info()
-		responses <- tmsp_types.ToResponseInfo(data)
-	case *tmsp_types.Request_SetOption:
-		so := r.SetOption
-		logStr := s.app.SetOption(so.Key, so.Value)
-		responses <- tmsp_types.ToResponseSetOption(logStr)
-	case *tmsp_types.Request_AppendTx:
-		res := s.app.AppendTx(r.AppendTx.Tx)
-		responses <- tmsp_types.ToResponseAppendTx(res.Code, res.Data, res.Log)
-	case *tmsp_types.Request_CheckTx:
-		res := s.app.CheckTx(r.CheckTx.Tx)
-		responses <- tmsp_types.ToResponseCheckTx(res.Code, res.Data, res.Log)
-	case *tmsp_types.Request_Commit:
-		res := s.app.Commit()
-		responses <- tmsp_types.ToResponseCommit(res.Code, res.Data, res.Log)
-	case *tmsp_types.Request_Query:
-		res := s.app.Query(r.Query.Query)
-		responses <- tmsp_types.ToResponseQuery(res.Code, res.Data, res.Log)
-	case *tmsp_types.Request_InitChain:
-		if app, ok := s.app.(tmsp_types.BlockchainAware); ok {
-			app.InitChain(r.InitChain.Validators)
-			responses <- tmsp_types.ToResponseInitChain()
-		} else {
-			responses <- tmsp_types.ToResponseInitChain()
-		}
-	case *tmsp_types.Request_EndBlock:
-		if app, ok := s.app.(tmsp_types.BlockchainAware); ok {
-			validators := app.EndBlock(r.EndBlock.Height)
-			responses <- tmsp_types.ToResponseEndBlock(validators)
-		} else {
-			responses <- tmsp_types.ToResponseEndBlock(nil)
-		}
-	default:
-		responses <- tmsp_types.ToResponseException("Unknown request")
-	}
-}
-
-// Pull responses from 'responses' and write them to conn.
-func (s *Server) handleResponses(closeConn chan error, responses <-chan *tmsp_types.Response, conn net.Conn) {
-	var count int
-	var bufWriter = bufio.NewWriter(conn)
-	for {
-		var res = <-responses
-		err := tmsp_types.WriteMessage(res, bufWriter)
-		if err != nil {
-			closeConn <- fmt.Errorf("Error in handleResponses: %v", err.Error())
-			return
-		}
-		if _, ok := res.Value.(*tmsp_types.Response_Flush); ok {
-			err = bufWriter.Flush()
-			if err != nil {
-				closeConn <- fmt.Errorf("Error in handleValue: %v", err.Error())
-				return
-			}
-		}
-		count++
-	}
-}
diff --git a/consensus/tmsp/version.go b/consensus/tmsp/version.go
deleted file mode 100644
index 266b37d792c4b606cdd547469f05d050edcc0b3b..0000000000000000000000000000000000000000
--- a/consensus/tmsp/version.go
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright 2015, 2016 Eris Industries (UK) Ltd.
-// This file is part of Eris-RT
-
-// Eris-RT is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-
-// Eris-RT is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License
-// along with Eris-RT.  If not, see <http://www.gnu.org/licenses/>.
-
-package tmsp
-
-import (
-	version "github.com/eris-ltd/eris-db/version"
-)
-
-const (
-	// Client identifier to advertise over the network
-	tmspClientIdentifier = "tmsp"
-	// Major version component of the current release
-	tmspVersionMajor = 0
-	// Minor version component of the current release
-	tmspVersionMinor = 6
-	// Patch version component of the current release
-	tmspVersionPatch = 0
-)
-
-func GetTmspVersion() *version.VersionIdentifier {
-	return version.New(tmspClientIdentifier, tmspVersionMajor, tmspVersionMinor,
-		tmspVersionPatch)
-}
diff --git a/consensus/types/consensus_engine.go b/consensus/types/consensus_engine.go
index ea02d3b2ec36459765f755cfd2f11930a622b38c..191bc6e4cbd771803d56d889b8bcc22508ba6386 100644
--- a/consensus/types/consensus_engine.go
+++ b/consensus/types/consensus_engine.go
@@ -1,11 +1,25 @@
+// 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 types
 
 import (
 	"github.com/eris-ltd/eris-db/event"
 	"github.com/eris-ltd/eris-db/txs"
+	abci_types "github.com/tendermint/abci/types"
 	"github.com/tendermint/go-crypto"
 	"github.com/tendermint/go-p2p"
-	tmsp_types "github.com/tendermint/tmsp/types"
 )
 
 type ConsensusEngine interface {
@@ -20,7 +34,7 @@ type ConsensusEngine interface {
 
 	// Memory pool
 	BroadcastTransaction(transaction []byte,
-		callback func(*tmsp_types.Response)) error
+		callback func(*abci_types.Response)) error
 
 	// Events
 	// For consensus events like NewBlock
diff --git a/consensus/types/consensus_state.go b/consensus/types/consensus_state.go
index a22febd4fcd8ea4d37023b3a4ac00e84583ae7e5..74d8b4b4a2167d5061bc120ac930409ace542570 100644
--- a/consensus/types/consensus_state.go
+++ b/consensus/types/consensus_state.go
@@ -1,3 +1,17 @@
+// 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 types
 
 import (
diff --git a/consensus/types/peer.go b/consensus/types/peer.go
index 78ddc885c220dc02e859d177a5bd0bedd35440b2..c123cf5c022e43d7a0224c55c14623913a4f12c4 100644
--- a/consensus/types/peer.go
+++ b/consensus/types/peer.go
@@ -1,3 +1,17 @@
+// 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 types
 
 import "github.com/tendermint/go-p2p"
diff --git a/consensus/types/validator.go b/consensus/types/validator.go
index 8feefb1f3563c5f690f20448c1056dc1c249c0c1..86fcfac1a6d7badbd2792eb5cae07f7156b32038 100644
--- a/consensus/types/validator.go
+++ b/consensus/types/validator.go
@@ -1,3 +1,17 @@
+// 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 types
 
 import (
diff --git a/core/config.go b/core/config.go
index a2a82dbd1e07e649962f8ee37e2f61b48ceb25aa..9090c28ae91fa7fa79ffaaa997b71afec47672b3 100644
--- a/core/config.go
+++ b/core/config.go
@@ -1,22 +1,21 @@
-// Copyright 2015, 2016 Eris Industries (UK) Ltd.
-// This file is part of Eris-RT
+// Copyright 2017 Monax Industries Limited
 //
-// Eris-RT is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
+// 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
 //
-// Eris-RT is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
+//    http://www.apache.org/licenses/LICENSE-2.0
 //
-// You should have received a copy of the GNU General Public License
-// along with Eris-RT.  If not, see <http://www.gnu.org/licenses/>.
+// 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.
 
 // config.go keeps explicit structures on the runtime configuration of
 // Eris-DB and all modules.  It loads these from the Viper configuration
 // loaded in `definitions.Do`
+
 package core
 
 import (
@@ -24,13 +23,14 @@ import (
 	"os"
 	"path"
 
-	config "github.com/eris-ltd/eris-db/config"
-	consensus "github.com/eris-ltd/eris-db/consensus"
-	definitions "github.com/eris-ltd/eris-db/definitions"
-	manager "github.com/eris-ltd/eris-db/manager"
-	server "github.com/eris-ltd/eris-db/server"
-	util "github.com/eris-ltd/eris-db/util"
-	version "github.com/eris-ltd/eris-db/version"
+	"github.com/eris-ltd/eris-db/config"
+	"github.com/eris-ltd/eris-db/consensus"
+	"github.com/eris-ltd/eris-db/definitions"
+	"github.com/eris-ltd/eris-db/logging"
+	"github.com/eris-ltd/eris-db/manager"
+	"github.com/eris-ltd/eris-db/server"
+	"github.com/eris-ltd/eris-db/util"
+	"github.com/eris-ltd/eris-db/version"
 	"github.com/spf13/viper"
 )
 
@@ -75,17 +75,14 @@ func LoadModuleConfig(conf *viper.Viper, rootWorkDir, rootDataDir,
 			fmt.Errorf("Failed to create module data directory %s.", dataDir)
 	}
 	// load configuration subtree for module
-	// TODO: [ben] Viper internally panics if `moduleName` contains an unallowed
-	// character (eg, a dash).  Either this needs to be wrapped in a go-routine
-	// and recovered from or a PR to viper is needed to address this bug.
 	if !conf.IsSet(moduleName) {
 		return nil, fmt.Errorf("Failed to read configuration section for %s",
 			moduleName)
 	}
-	subConfig := conf.Sub(moduleName)
+	subConfig, err := config.ViperSubConfig(conf, moduleName)
 	if subConfig == nil {
-		return nil,
-			fmt.Errorf("Failed to read configuration section for %s.", moduleName)
+		return nil, fmt.Errorf("Failed to read configuration section for %s: %s",
+			moduleName, err)
 	}
 
 	return &config.ModuleConfig{
@@ -104,19 +101,29 @@ func LoadModuleConfig(conf *viper.Viper, rootWorkDir, rootDataDir,
 // LoadServerModuleConfig wraps specifically for the servers run by core
 func LoadServerConfig(do *definitions.Do) (*server.ServerConfig, error) {
 	// load configuration subtree for servers
-	if !do.Config.IsSet("servers") {
-		return nil, fmt.Errorf("Failed to read configuration section for servers")
-	}
-	subConfig := do.Config.Sub("servers")
-	if subConfig == nil {
-		return nil,
-			fmt.Errorf("Failed to read configuration section for servers")
+	subConfig, err := config.ViperSubConfig(do.Config, "servers")
+	if err != nil {
+		return nil, err
 	}
 	serverConfig, err := server.ReadServerConfig(subConfig)
+	if err != nil {
+		return nil, err
+	}
 	serverConfig.ChainId = do.ChainId
 	return serverConfig, err
 }
 
+func LoadLoggingConfigFromDo(do *definitions.Do) (*logging.LoggingConfig, error) {
+	//subConfig, err := SubConfig(conf, "logging")
+	loggingConfig := &logging.LoggingConfig{}
+	return loggingConfig, nil
+}
+
+func LoadLoggingConfigFromClientDo(do *definitions.ClientDo) (*logging.LoggingConfig, error) {
+	loggingConfig := &logging.LoggingConfig{}
+	return loggingConfig, nil
+}
+
 //------------------------------------------------------------------------------
 // Helper functions
 
diff --git a/core/core.go b/core/core.go
index 03f56b56a47927b09d8b2bdc9e5a2302da1fcd84..14725b6c2ac137df77f856577f25e897ddc432c2 100644
--- a/core/core.go
+++ b/core/core.go
@@ -1,18 +1,16 @@
-// Copyright 2015, 2016 Eris Industries (UK) Ltd.
-// This file is part of Eris-RT
-
-// Eris-RT is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-
-// Eris-RT is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License
-// along with Eris-RT.  If not, see <http://www.gnu.org/licenses/>.
+// 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 core
 
@@ -22,55 +20,53 @@ import (
 	// TODO: [ben] swap out go-events with eris-db/event (currently unused)
 	events "github.com/tendermint/go-events"
 
-	log "github.com/eris-ltd/eris-logger"
-
-	config "github.com/eris-ltd/eris-db/config"
-	consensus "github.com/eris-ltd/eris-db/consensus"
-	definitions "github.com/eris-ltd/eris-db/definitions"
-	event "github.com/eris-ltd/eris-db/event"
-	manager "github.com/eris-ltd/eris-db/manager"
+	"github.com/eris-ltd/eris-db/config"
+	"github.com/eris-ltd/eris-db/consensus"
+	"github.com/eris-ltd/eris-db/definitions"
+	"github.com/eris-ltd/eris-db/event"
+	"github.com/eris-ltd/eris-db/manager"
 	// rpc_v0 is carried over from Eris-DBv0.11 and before on port 1337
 	rpc_v0 "github.com/eris-ltd/eris-db/rpc/v0"
 	// rpc_tendermint is carried over from Eris-DBv0.11 and before on port 46657
+
+	"github.com/eris-ltd/eris-db/logging"
+	"github.com/eris-ltd/eris-db/logging/loggers"
 	rpc_tendermint "github.com/eris-ltd/eris-db/rpc/tendermint/core"
-	server "github.com/eris-ltd/eris-db/server"
+	"github.com/eris-ltd/eris-db/server"
 )
 
 // Core is the high-level structure
 type Core struct {
 	chainId        string
-	evsw           *events.EventSwitch
+	evsw           events.EventSwitch
 	pipe           definitions.Pipe
 	tendermintPipe definitions.TendermintPipe
 }
 
-func NewCore(chainId string, consensusConfig *config.ModuleConfig,
-	managerConfig *config.ModuleConfig) (*Core, error) {
+func NewCore(chainId string,
+	consensusConfig *config.ModuleConfig,
+	managerConfig *config.ModuleConfig,
+	logger loggers.InfoTraceLogger) (*Core, error) {
 	// start new event switch, TODO: [ben] replace with eris-db/event
 	evsw := events.NewEventSwitch()
 	evsw.Start()
+	logger = logging.WithScope(logger, "Core")
 
 	// start a new application pipe that will load an application manager
-	pipe, err := manager.NewApplicationPipe(managerConfig, evsw,
+	pipe, err := manager.NewApplicationPipe(managerConfig, evsw, logger,
 		consensusConfig.Version)
 	if err != nil {
 		return nil, fmt.Errorf("Failed to load application pipe: %v", err)
 	}
-	log.Debug("Loaded pipe with application manager")
+	logging.TraceMsg(logger, "Loaded pipe with application manager")
 	// pass the consensus engine into the pipe
 	if e := consensus.LoadConsensusEngineInPipe(consensusConfig, pipe); e != nil {
 		return nil, fmt.Errorf("Failed to load consensus engine in pipe: %v", e)
 	}
 	tendermintPipe, err := pipe.GetTendermintPipe()
 	if err != nil {
-		log.Warn(fmt.Sprintf("Tendermint gateway not supported by %s",
-			managerConfig.Version))
-		return &Core{
-			chainId:        chainId,
-			evsw:           evsw,
-			pipe:           pipe,
-			tendermintPipe: nil,
-		}, nil
+		logging.TraceMsg(logger, "Tendermint gateway not supported by manager",
+			"manager-version", managerConfig.Version)
 	}
 	return &Core{
 		chainId:        chainId,
diff --git a/core/types/types.go b/core/types/types.go
index ecb6fc95293cf98d6125ccf0f4450a33fdc0b0e3..abe9fd0c924b8ca2560da4a9365f8de0e5418002 100644
--- a/core/types/types.go
+++ b/core/types/types.go
@@ -1,23 +1,22 @@
-// Copyright 2015, 2016 Eris Industries (UK) Ltd.
-// This file is part of Eris-RT
+// 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.
 
-// Eris-RT is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-
-// Eris-RT is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License
-// along with Eris-RT.  If not, see <http://www.gnu.org/licenses/>.
+package types
 
 // TODO: [ben] this is poorly constructed but copied over
 // from eris-db/erisdb/pipe/types to make incremental changes and allow
 // for a discussion around the proper defintion of the needed types.
-package types
 
 import (
 	// NodeInfo (drop this!)
diff --git a/definitions/client_do.go b/definitions/client_do.go
index 849977fa3312c0dd6cc90b650592c2a9caa0b172..dc7c9c7e2f534a7eae150aac095bf40ba249012c 100644
--- a/definitions/client_do.go
+++ b/definitions/client_do.go
@@ -1,18 +1,16 @@
-// Copyright 2015, 2016 Eris Industries (UK) Ltd.
-// This file is part of Eris-RT
-
-// Eris-RT is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-
-// Eris-RT is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License
-// along with Eris-RT.  If not, see <http://www.gnu.org/licenses/>.
+// 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 definitions
 
diff --git a/definitions/do.go b/definitions/do.go
index f022aabbc2495d91933b0da38cbd39c4f0be4399..e89b69ffb375bd3a255dec6097c60a69591485f7 100644
--- a/definitions/do.go
+++ b/definitions/do.go
@@ -1,18 +1,16 @@
-// Copyright 2015, 2016 Eris Industries (UK) Ltd.
-// This file is part of Eris-RT
-
-// Eris-RT is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-
-// Eris-RT is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License
-// along with Eris-RT.  If not, see <http://www.gnu.org/licenses/>.
+// 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 definitions
 
diff --git a/definitions/pipe.go b/definitions/pipe.go
index f15c60df5cbe4aceda0a9421ed824c35bb0b3ea3..e00e46ed80fb10674222a55c29c92f276e814632 100644
--- a/definitions/pipe.go
+++ b/definitions/pipe.go
@@ -1,18 +1,16 @@
-// Copyright 2015, 2016 Eris Industries (UK) Ltd.
-// This file is part of Eris-RT
-
-// Eris-RT is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-
-// Eris-RT is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License
-// along with Eris-RT.  If not, see <http://www.gnu.org/licenses/>.
+// 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 definitions
 
@@ -31,6 +29,7 @@ import (
 	core_types "github.com/eris-ltd/eris-db/core/types"
 	types "github.com/eris-ltd/eris-db/core/types"
 	event "github.com/eris-ltd/eris-db/event"
+	"github.com/eris-ltd/eris-db/logging/loggers"
 	manager_types "github.com/eris-ltd/eris-db/manager/types"
 	"github.com/eris-ltd/eris-db/txs"
 )
@@ -43,6 +42,7 @@ type Pipe interface {
 	Transactor() Transactor
 	// Hash of Genesis state
 	GenesisHash() []byte
+	Logger() loggers.InfoTraceLogger
 	// NOTE: [ben] added to Pipe interface on 0.12 refactor
 	GetApplication() manager_types.Application
 	SetConsensusEngine(consensusEngine consensus_types.ConsensusEngine) error
diff --git a/definitions/tendermint_pipe.go b/definitions/tendermint_pipe.go
index e933194d7cb28c1f2bbb163f0ef9b0009d4509f6..8fd5a9bb5e3dd75f59336b63825788e10cbe07ba 100644
--- a/definitions/tendermint_pipe.go
+++ b/definitions/tendermint_pipe.go
@@ -1,18 +1,16 @@
-// Copyright 2015, 2016 Eris Industries (UK) Ltd.
-// This file is part of Eris-RT
-
-// Eris-RT is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-
-// Eris-RT is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License
-// along with Eris-RT.  If not, see <http://www.gnu.org/licenses/>.
+// 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 definitions
 
diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md
deleted file mode 100644
index 173af5fb540ce307cec1497c95be39cabe6b5b85..0000000000000000000000000000000000000000
--- a/docs/CHANGELOG.md
+++ /dev/null
@@ -1,38 +0,0 @@
-# Eris-DB changelog
-
-## 0.12.0-RC3
-This release marks the start of Eris-DB as the full permissioned blockchain node
- of the Eris platform with the Tendermint permissioned consensus engine.
- This involved significant refactoring of almost all parts of the code,
- but provides a solid foundation to build the next generation of advanced
- permissioned smart contract blockchains.
-
- Many changes are under the hood but here are the main externally
- visible changes:
-
-- Features and improvements
-  - Upgrade to Tendermint 0.6.0 in-process consensus
-  - Support DELEGATECALL opcode in Ethereum Virtual Machine (important for solidity library calls)
-  - ARM support
-  - Docker image size reduced
-  - Introduction of eris-client companion library for interacting with
-  eris:db
-  - Improved single configuration file for all components written by eris-cm
-  - Allow multiple event subscriptions from same host under rpc/tendermint
-
-
-- Tool changes  
-  - Use glide instead of godeps for dependencies
-
-
-- Testing
-  - integration tests over simulated RPC calls
-  - significantly improved unit tests
-  - the ethereum virtual machine and the consensus engine are now top-level
-  components and are exposed to continuous integration tests
-
-
-- Bugfixes (incomplete list)
-  - [EVM] Fix calculation of child CALL gaslimit (allowing solidity library calls to work properly)
-  - [RPC/v0] Fix blocking event subscription in transactAndHold (preventing return in Javascript libraries)
-  - [Blockchain] Fix getBlocks to respect block height cap
diff --git a/docs/PROPOSALS.md b/docs/PROPOSALS.md
new file mode 100644
index 0000000000000000000000000000000000000000..35cf450a7e304dd78522939496a6ff4bea93d504
--- /dev/null
+++ b/docs/PROPOSALS.md
@@ -0,0 +1,17 @@
+# Eris-db proposals for future work
+
+The following list is extra-ordinarily uncommitted to and deliberately incomplete, but we thought it may be worthwhile sharing with you for soliciting your input and collaboration going forward:
+
+#### Security, Identity and Privacy
+
+- **Advanced security framework:** Functionality preceding Monax’s Nightsky (see multi-chain universe continuation below) to enable global encryption of transactions, genesis files and account storage at rest.
+- **Identity Management and Whitelisting:** write protection is inherent to the permissioning scheme but read protection will be enabled by integrating certificates for restricting connectivity access to the peer-to-peer network for validators, verifiers or light clients.  This is in addition to normal VPN and firewall solutions and a precursor of Monax’s Nightsky, which restricts read-access through selective decryption.
+- **Multi-chain Universe (Step 2 of 3):** The second step towards enabling the multi-chain universe is well-underway with the Tendermint Cosmos proposal for interblockchain communication.  
+- **Multi-chain Universe (Step 3 of 3):** The third and final step is the Monax’s Nightsky proposal for inherent encryption of transactions and allowing only partial reconstruction of the smart contract application state for verifiers or light clients (for mobile or IoT devices). Together Cosmos and Nightsky allow smart contracts to orchestrate where information flows and who has the ability to decypher what part of the data.
+
+#### Scalability and Governance
+
+- **Read-cache Optimisation and Queryability:** subjectively pipe the application state and event logs to a data warehousing solution.  Building upon the read-cache the SQLsol prototype can be integrated as an SQL-opinionated transformation layer of smart contract events and  data into a relational database.
+- **Chain life-cycle management:** the tooling is the starting point for chain life-cycle management and will be extended with exporting snapshots of chain state.  These snapshots can be used to administratively start a new network with an updated version of eris-db software as cold upgrade.  In a second phase the Cosmos proposal is ideally suited to run a new version of the node software in parallel to existing chain and the validators of the network can atomically cast their vote of approval through the Cosmos hub to dynamically move the voting power over to the updated chain (hot upgrade) until a full vote of confidence is achieved.  It is important to note that chain life-cycle management is complementary to and will support smart contract life-cycle management, known to some as DOUG, our marmot mascot.
+- **Sharding and scalability framework:** interblockchain communication through the exchange of proofs leverages the peer-to-peer network - rather than oracles - to distribute the load across parallel chains and removes oracle-bridges as potential bottlenecks and security risks.
+- **Light-client and ABI integration:** a significant usability upgrade of smart contract chains will be achieved through the ability for the ABI definition of the deployed smart contracts to be verifiably linked to the smart contract accounts. The introduction of the EIP-141 will enable the injection of an ABI fingerprint into smart contract code such that a light client, eris-worker can dynamically expose the smart contract functionality through API calls. As an aside it is worth noting that the tendermint consensus protocol provides a distinctive advantage for light-clients as the last block signed by a majority of validators is unambiguously the current state;
diff --git a/docs/generator.go b/docs/generator.go
index fb430fc067be744340d07c486593563e994a75fd..404b1593fcec1b9bc8cd2c0ba6c679c60854bb71 100644
--- a/docs/generator.go
+++ b/docs/generator.go
@@ -1,3 +1,17 @@
+// 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 (
@@ -7,10 +21,11 @@ import (
 	"strings"
 	"text/template"
 
-	"github.com/eris-ltd/common/go/docs"
 	commands "github.com/eris-ltd/eris-db/cmd"
+	docs "github.com/eris-ltd/eris-db/docs/generator"
 
 	clientCommands "github.com/eris-ltd/eris-db/client/cmd"
+	"github.com/eris-ltd/eris-db/definitions"
 	"github.com/eris-ltd/eris-db/version"
 	"github.com/spf13/cobra"
 )
@@ -115,9 +130,9 @@ func AddClientToDB(dbCmd, clientCmd *cobra.Command) error {
 func main() {
 	// Repository maintainers should populate the top level command object.
 	erisDbCommand := commands.ErisDbCmd
-	commands.InitErisDbCli()
-	commands.AddCommands()
-	commands.AddGlobalFlags()
+	do := definitions.NewDo()
+	commands.AddGlobalFlags(do)
+	commands.AddCommands(do)
 
 	erisClientCommand := clientCommands.ErisClientCmd
 	clientCommands.InitErisClientInit()
diff --git a/docs/generator/generator.go b/docs/generator/generator.go
new file mode 100644
index 0000000000000000000000000000000000000000..296704a4841d3a652fc0eb2090088f2c15863a2b
--- /dev/null
+++ b/docs/generator/generator.go
@@ -0,0 +1,347 @@
+// 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 generator
+
+import (
+	"bufio"
+	"fmt"
+	"io"
+	"io/ioutil"
+	"os"
+	"path/filepath"
+	"regexp"
+	"strconv"
+	"strings"
+	"text/template"
+)
+
+const FrontMatter = `---
+
+layout: single
+type: docs
+title: "Documentation | {{ .Description }} | {{ $name }}"
+
+---`
+
+type Entry struct {
+	Title          string
+	Template       *template.Template
+	Specifications []*Entry
+	Examples       []*Entry
+	Description    string
+	FileName       string
+	CmdEntryPoint  string
+	URL            string
+	BaseURL        string
+}
+
+func GenerateFileName(dir, s string) string {
+	return (dir + strings.Replace(strings.ToLower(s), " ", "_", -1) + ".md")
+}
+
+func GenerateTitleFromFileName(file string) string {
+	file = strings.Replace(file, "_", " ", -1)
+	file = strings.Replace(file, "-", " ", -1)
+	return strings.Title(strings.Replace(file, ".md", "", 1))
+}
+
+func GenerateFileNameFromGlob(dir, s string) string {
+	return (dir + strings.Replace(filepath.Base(s), " ", "_", -1))
+}
+
+func GenerateURLFromFileName(s string) string {
+	s = strings.Replace(s, "./", "/", 1)
+	return strings.Replace(s, ".md", "/", -1)
+}
+
+func GenerateCommandsTemplate() (*template.Template, error) {
+	handle_link := func(s string) string {
+		return (strings.Replace(s, ".md", "/", -1))
+	}
+
+	handle_file := func(s1, s2 string) string {
+		return strings.Replace((s1 + " " + s2 + ".md"), " ", "_", -1)
+	}
+
+	funcMap := template.FuncMap{
+		"title":       strings.Title,
+		"replace":     strings.Replace,
+		"chomp":       strings.TrimSpace,
+		"handle_file": handle_file,
+		"handle_link": handle_link,
+	}
+
+	var templateText = `{{- $name := .Command.CommandPath -}}` + FrontMatter + `
+
+# {{ $name }}
+
+{{ title .Command.Short }}
+
+{{ if .Command.Runnable }}## Usage
+
+` + "```bash\n{{ .Command.UseLine }}\n```" + `{{ end }}
+
+{{ if ne .Command.Long  "" }}## Synopsis
+
+{{ .Command.Long }}
+{{ end }}
+{{ $flags := .Command.NonInheritedFlags }}
+{{ if $flags.HasFlags }}## Options
+
+` + "```bash\n  {{ $flags.FlagUsages | chomp }}\n```" + `{{ end }}
+{{ $global_flags := .Command.InheritedFlags }}
+{{ if $global_flags.HasFlags }}## Options inherited from parent commands
+
+` + "```bash\n  {{ $global_flags.FlagUsages | chomp }}\n```" + `{{ end }}
+
+{{ if .Command.HasSubCommands }}# Subcommands
+{{ range .Command.Commands }}
+{{ if ne .Deprecated "" }}
+* [{{ $name }} {{ .Name }}]({{ .BaseURL }}{{ handle_file $name .Name | handle_link }}) - {{ .Short }}
+{{ end }}
+{{ end }}
+{{ end }}
+
+{{ if .Command.HasParent }}{{ $parent := .Command.Parent }}## See Also
+* [{{ $parent.CommandPath }}]({{ .BaseURL }}{{ handle_file $parent.CommandPath "" | handle_link }}) - {{ $parent.Short }}
+{{ end }}
+
+{{ if ne .Command.Example "" }}# Quick Tips
+
+` + "```bash\n{{ .Command.Example }}\n```" + `{{ end }}
+
+{{ if ne (len .Entry.Examples) 0 }}# Examples
+{{ range .Entry.Examples }}
+* [{{ title .Title }}]({{ .URL }})
+{{- end }}
+{{ end }}
+
+{{ if ne (len .Entry.Specifications) 0 }}# Specifications
+{{ range .Entry.Specifications }}
+* [{{ title .Title }}]({{ .URL }})
+{{- end }}
+{{ end }}
+`
+
+	return template.New("docGenerator").Funcs(funcMap).Parse(templateText)
+}
+
+func GenerateEntries(dir, render_dir, description string) ([]*Entry, error) {
+	var entries []*Entry
+
+	if _, err := os.Stat(render_dir); os.IsNotExist(err) {
+		err = os.MkdirAll(render_dir, 0755)
+		if err != nil {
+			panic(err)
+		}
+	}
+
+	files := CollectEntries(dir)
+
+	for _, file := range files {
+		this_entry, err := GenerateEntry(file, dir, render_dir, description)
+		if err != nil {
+			return nil, err
+		} else {
+			entries = append(entries, this_entry)
+		}
+	}
+
+	return entries, nil
+}
+
+func CollectEntries(dir string) []string {
+	var newFiles []string
+
+	files, err := filepath.Glob(dir + "/*")
+	if err != nil {
+		panic(err)
+	}
+
+	for _, file := range files {
+		f_info, err := os.Stat(file)
+
+		if err != nil {
+			panic(err)
+		}
+
+		if f_info.IsDir() {
+			newFiles = append(newFiles, CollectEntries(file)...)
+		} else {
+			if filepath.Ext(file) == ".md" {
+				newFiles = append(newFiles, file)
+			}
+		}
+	}
+
+	return newFiles
+}
+
+func GenerateEntry(file, dir, render_dir, description string) (*Entry, error) {
+	var err error
+
+	this_entry := &Entry{
+		FileName:    GenerateFileNameFromGlob(render_dir, file),
+		Title:       GenerateTitleFromFileName(filepath.Base(file)),
+		Description: description,
+	}
+
+	this_entry.URL = GenerateURLFromFileName(this_entry.FileName)
+
+	txt, err := ioutil.ReadFile(file)
+	if err != nil {
+		return nil, err
+	}
+
+	// Get template from docs generator
+	this_entry.Template, err = GenerateEntriesTemplate(txt)
+	if err != nil {
+		return nil, err
+	}
+
+	return this_entry, nil
+}
+
+func GenerateEntriesTemplate(txt []byte) (*template.Template, error) {
+	handle_link := func(s string) string {
+		return (strings.Replace(s, ".md", "/", -1))
+	}
+
+	handle_file := func(s1 string) string {
+		return strings.Replace((s1 + ".md"), " ", "_", -1)
+	}
+
+	insert_definition := func(file string, struc string) string {
+		txt, err := ioutil.ReadFile(filepath.Join("definitions", file))
+		if err != nil {
+			panic(err)
+		}
+		finder := regexp.MustCompile(fmt.Sprintf(`(?ms:^type %s struct {.*?^})`, struc))
+		return ("```go\n" + string(finder.Find(txt)) + "\n```")
+	}
+
+	insert_bash_lines := func(file string, linesToRead string) string {
+		var lines []byte
+		var line []byte
+		var start int
+		var stop int
+
+		fileInfo, err := os.Open(filepath.Join("docs", "tests", file))
+		if err != nil {
+			panic(err)
+		}
+		defer fileInfo.Close()
+
+		start, err = strconv.Atoi(strings.Split(linesToRead, "-")[0])
+		if strings.Contains(linesToRead, "-") {
+			stop, err = strconv.Atoi(strings.Split(linesToRead, "-")[1])
+		} else {
+			stop = start
+		}
+		if err != nil {
+			panic(err)
+		}
+
+		r := bufio.NewReader(fileInfo)
+		for i := 1; ; i++ {
+			line, err = r.ReadBytes('\n')
+			if err != nil {
+				break
+			}
+			if i >= start && i <= stop {
+				lines = append(lines, line...)
+			}
+		}
+		if err != io.EOF {
+			panic(err)
+		}
+
+		return ("```bash\n" + string(lines) + "```")
+	}
+
+	insert_file := func(file string) string {
+		file = filepath.Join("docs", "tests", file)
+		ext := filepath.Ext(file)
+		switch ext {
+		case ".sol":
+			ext = ".javascript"
+		case ".yml":
+			ext = ".yaml"
+		}
+
+		ext = strings.Replace(ext, ".", "", 1)
+
+		txtB, err := ioutil.ReadFile(file)
+		if err != nil {
+			panic(err)
+		}
+
+		txt := string(txtB)
+		if !strings.HasSuffix(txt, "\n") {
+			txt = txt + "\n"
+		}
+
+		return ("```" + ext + "\n" + txt + "```") // TODO: add auto-curl text
+	}
+
+	funcMap := template.FuncMap{
+		"title":             strings.Title,
+		"replace":           strings.Replace,
+		"chomp":             strings.TrimSpace,
+		"handle_file":       handle_file,
+		"handle_link":       handle_link,
+		"insert_definition": insert_definition,
+		"insert_bash_lines": insert_bash_lines,
+		"insert_file":       insert_file,
+	}
+
+	var templateText = `{{- $name := .Title -}}` + FrontMatter + `
+
+` + string(txt) + `
+
+## Commands
+
+* [{{ .CmdEntryPoint }}]({{ .BaseURL }}{{ handle_file .CmdEntryPoint | handle_link }})
+
+{{ if ne (len .Examples) 0 }}# Examples
+{{ range .Examples }}
+* [{{ title .Title }}]({{ .URL }})
+{{- end }}
+{{ end }}
+
+{{ if ne (len .Specifications) 0 }}# Specifications
+{{ range .Specifications }}
+* [{{ title .Title }}]({{ .URL }})
+{{- end }}
+{{ end }}
+`
+
+	return template.New("entryGenerator").Funcs(funcMap).Parse(templateText)
+}
+
+func RenderEntry(this_entry *Entry) error {
+	out_file, err := os.Create(this_entry.FileName)
+	if err != nil {
+		return err
+	}
+	defer out_file.Close()
+
+	err = this_entry.Template.Execute(out_file, this_entry)
+	if err != nil {
+		return err
+	}
+
+	return nil
+}
diff --git a/event/event_cache.go b/event/event_cache.go
index 08db30116ea20225cb27875fb79fd103b0165070..474c892d08161476d5c177ec032226c2bc01ab31 100644
--- a/event/event_cache.go
+++ b/event/event_cache.go
@@ -1,10 +1,25 @@
+// 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 event
 
 import (
 	"fmt"
-	"github.com/eris-ltd/eris-db/txs"
 	"sync"
 	"time"
+
+	"github.com/eris-ltd/eris-db/txs"
 )
 
 var (
diff --git a/event/event_cache_test.go b/event/event_cache_test.go
index 35ce6d7ed0cbdc45c3b838d831b993fddfbbb42b..573eed113af6fb60306597530a647c437eaef102 100644
--- a/event/event_cache_test.go
+++ b/event/event_cache_test.go
@@ -1,3 +1,17 @@
+// 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 event
 
 import (
@@ -13,7 +27,7 @@ import (
 	"github.com/stretchr/testify/assert"
 )
 
-var mockInterval = 10 * time.Millisecond
+var mockInterval = 40 * time.Millisecond
 
 type mockSub struct {
 	subId    string
diff --git a/event/events.go b/event/events.go
index d5c37d8e724259036a661cc4758d9030c322aba1..5ada94a52e994f7497c111300c65205a86894d12 100644
--- a/event/events.go
+++ b/event/events.go
@@ -1,18 +1,16 @@
-// Copyright 2015, 2016 Eris Industries (UK) Ltd.
-// This file is part of Eris-RT
-
-// Eris-RT is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-
-// Eris-RT is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License
-// along with Eris-RT.  If not, see <http://www.gnu.org/licenses/>.
+// 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 event
 
@@ -23,8 +21,9 @@ import (
 
 	"fmt"
 
+	"github.com/eris-ltd/eris-db/logging"
+	"github.com/eris-ltd/eris-db/logging/loggers"
 	"github.com/eris-ltd/eris-db/txs"
-	log "github.com/eris-ltd/eris-logger"
 	go_events "github.com/tendermint/go-events"
 	tm_types "github.com/tendermint/tendermint/types"
 )
@@ -43,8 +42,8 @@ type EventEmitter interface {
 	Unsubscribe(subId string) error
 }
 
-func NewEvents(eventSwitch *go_events.EventSwitch) *events {
-	return &events{eventSwitch}
+func NewEvents(eventSwitch go_events.EventSwitch, logger loggers.InfoTraceLogger) *events {
+	return &events{eventSwitch: eventSwitch, logger: logging.WithScope(logger, "Events")}
 }
 
 // Provides an EventEmitter that wraps many underlying EventEmitters as a
@@ -56,28 +55,29 @@ func Multiplex(events ...EventEmitter) *multiplexedEvents {
 
 // The events struct has methods for working with events.
 type events struct {
-	eventSwitch *go_events.EventSwitch
+	eventSwitch go_events.EventSwitch
+	logger      loggers.InfoTraceLogger
 }
 
 // Subscribe to an event.
-func (this *events) Subscribe(subId, event string,
+func (evts *events) Subscribe(subId, event string,
 	callback func(txs.EventData)) error {
 	cb := func(evt go_events.EventData) {
 		eventData, err := mapToOurEventData(evt)
 		if err != nil {
-			log.WithError(err).
-				WithFields(log.Fields{"event": event}).
-				Error("Failed to map go-events EventData to our EventData")
+			logging.InfoMsg(evts.logger, "Failed to map go-events EventData to our EventData",
+				"error", err,
+				"event", event)
 		}
 		callback(eventData)
 	}
-	this.eventSwitch.AddListenerForEvent(subId, event, cb)
+	evts.eventSwitch.AddListenerForEvent(subId, event, cb)
 	return nil
 }
 
 // Un-subscribe from an event.
-func (this *events) Unsubscribe(subId string) error {
-	this.eventSwitch.RemoveListener(subId)
+func (evts *events) Unsubscribe(subId string) error {
+	evts.eventSwitch.RemoveListener(subId)
 	return nil
 }
 
diff --git a/event/events_test.go b/event/events_test.go
index 51d185ecb0ad5c012c528c2cf1eeb7e3165ab182..af6d9530377eceb4a184ded8e4b6b030458df35e 100644
--- a/event/events_test.go
+++ b/event/events_test.go
@@ -1,3 +1,17 @@
+// 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 event
 
 import (
diff --git a/event/filters.go b/event/filters.go
index 948a2f012af4275782adcd480248cc424b459ca6..ea04e989f45a8c61dd46370bebcaac02a86fc727 100644
--- a/event/filters.go
+++ b/event/filters.go
@@ -1,3 +1,17 @@
+// 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 event
 
 import (
diff --git a/event_new/event.go b/event_new/event.go
deleted file mode 100644
index 9553b3921991404a0298819c7b930e829fa67087..0000000000000000000000000000000000000000
--- a/event_new/event.go
+++ /dev/null
@@ -1,240 +0,0 @@
-// Copyright 2014 The go-ethereum Authors
-// This file is part of the go-ethereum library.
-//
-// The go-ethereum library is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// The go-ethereum library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
-
-// Copyright 2015, 2016 Eris Industries (UK) Ltd.
-// This file is part of Eris-RT
-
-// Eris-RT is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-
-// Eris-RT is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License
-// along with Eris-RT.  If not, see <http://www.gnu.org/licenses/>.
-
-// This code is ported over into Eris-RT from Go-Ethereum and further adapted,
-// with many thanks to the Ethereum foundation and the Go-Ethereum team.
-
-// Package event implements an event multiplexer.
-package event
-
-import (
-	"errors"
-	"fmt"
-	"reflect"
-	"sync"
-	"time"
-)
-
-// Event is a time-tagged notification pushed to subscribers.
-type Event struct {
-	Time time.Time
-	Data interface{}
-}
-
-// Subscription is implemented by event subscriptions.
-type Subscription interface {
-	// Chan returns a channel that carries events.
-	// Implementations should return the same channel
-	// for any subsequent calls to Chan.
-	Chan() <-chan *Event
-
-	// Unsubscribe stops delivery of events to a subscription.
-	// The event channel is closed.
-	// Unsubscribe can be called more than once.
-	Unsubscribe()
-}
-
-// A TypeMux dispatches events to registered receivers. Receivers can be
-// registered to handle events of certain type. Any operation
-// called after mux is stopped will return ErrMuxClosed.
-//
-// The zero value is ready to use.
-type TypeMux struct {
-	mutex   sync.RWMutex
-	subm    map[reflect.Type][]*muxsub
-	stopped bool
-}
-
-// ErrMuxClosed is returned when Posting on a closed TypeMux.
-var ErrMuxClosed = errors.New("event: mux closed")
-
-// Subscribe creates a subscription for events of the given types. The
-// subscription's channel is closed when it is unsubscribed
-// or the mux is closed.
-func (mux *TypeMux) Subscribe(types ...interface{}) Subscription {
-	sub := newsub(mux)
-	mux.mutex.Lock()
-	defer mux.mutex.Unlock()
-	if mux.stopped {
-		// set the status to closed so that calling Unsubscribe after this
-		// call will short curuit
-		sub.closed = true
-		close(sub.postC)
-	} else {
-		if mux.subm == nil {
-			mux.subm = make(map[reflect.Type][]*muxsub)
-		}
-		for _, t := range types {
-			rtyp := reflect.TypeOf(t)
-			oldsubs := mux.subm[rtyp]
-			if find(oldsubs, sub) != -1 {
-				panic(fmt.Sprintf("event: duplicate type %s in Subscribe", rtyp))
-			}
-			subs := make([]*muxsub, len(oldsubs)+1)
-			copy(subs, oldsubs)
-			subs[len(oldsubs)] = sub
-			mux.subm[rtyp] = subs
-		}
-	}
-	return sub
-}
-
-// Post sends an event to all receivers registered for the given type.
-// It returns ErrMuxClosed if the mux has been stopped.
-func (mux *TypeMux) Post(ev interface{}) error {
-	event := &Event{
-		Time: time.Now(),
-		Data: ev,
-	}
-	rtyp := reflect.TypeOf(ev)
-	mux.mutex.RLock()
-	if mux.stopped {
-		mux.mutex.RUnlock()
-		return ErrMuxClosed
-	}
-	subs := mux.subm[rtyp]
-	mux.mutex.RUnlock()
-	for _, sub := range subs {
-		sub.deliver(event)
-	}
-	return nil
-}
-
-// Stop closes a mux. The mux can no longer be used.
-// Future Post calls will fail with ErrMuxClosed.
-// Stop blocks until all current deliveries have finished.
-func (mux *TypeMux) Stop() {
-	mux.mutex.Lock()
-	for _, subs := range mux.subm {
-		for _, sub := range subs {
-			sub.closewait()
-		}
-	}
-	mux.subm = nil
-	mux.stopped = true
-	mux.mutex.Unlock()
-}
-
-func (mux *TypeMux) del(s *muxsub) {
-	mux.mutex.Lock()
-	for typ, subs := range mux.subm {
-		if pos := find(subs, s); pos >= 0 {
-			if len(subs) == 1 {
-				delete(mux.subm, typ)
-			} else {
-				mux.subm[typ] = posdelete(subs, pos)
-			}
-		}
-	}
-	s.mux.mutex.Unlock()
-}
-
-func find(slice []*muxsub, item *muxsub) int {
-	for i, v := range slice {
-		if v == item {
-			return i
-		}
-	}
-	return -1
-}
-
-func posdelete(slice []*muxsub, pos int) []*muxsub {
-	news := make([]*muxsub, len(slice)-1)
-	copy(news[:pos], slice[:pos])
-	copy(news[pos:], slice[pos+1:])
-	return news
-}
-
-type muxsub struct {
-	mux     *TypeMux
-	created time.Time
-	closeMu sync.Mutex
-	closing chan struct{}
-	closed  bool
-
-	// these two are the same channel. they are stored separately so
-	// postC can be set to nil without affecting the return value of
-	// Chan.
-	postMu sync.RWMutex
-	readC  <-chan *Event
-	postC  chan<- *Event
-}
-
-func newsub(mux *TypeMux) *muxsub {
-	c := make(chan *Event)
-	return &muxsub{
-		mux:     mux,
-		created: time.Now(),
-		readC:   c,
-		postC:   c,
-		closing: make(chan struct{}),
-	}
-}
-
-func (s *muxsub) Chan() <-chan *Event {
-	return s.readC
-}
-
-func (s *muxsub) Unsubscribe() {
-	s.mux.del(s)
-	s.closewait()
-}
-
-func (s *muxsub) closewait() {
-	s.closeMu.Lock()
-	defer s.closeMu.Unlock()
-	if s.closed {
-		return
-	}
-	close(s.closing)
-	s.closed = true
-
-	s.postMu.Lock()
-	close(s.postC)
-	s.postC = nil
-	s.postMu.Unlock()
-}
-
-func (s *muxsub) deliver(event *Event) {
-	// Short circuit delivery if stale event
-	if s.created.After(event.Time) {
-		return
-	}
-	// Otherwise deliver the event
-	s.postMu.RLock()
-	defer s.postMu.RUnlock()
-
-	select {
-	case s.postC <- event:
-	case <-s.closing:
-	}
-}
diff --git a/event_new/event_test.go b/event_new/event_test.go
deleted file mode 100644
index fcdb0b1cdda1ed5baf49c55280beed73c92b34f7..0000000000000000000000000000000000000000
--- a/event_new/event_test.go
+++ /dev/null
@@ -1,219 +0,0 @@
-// Copyright 2014 The go-ethereum Authors
-// This file is part of the go-ethereum library.
-//
-// The go-ethereum library is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// The go-ethereum library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
-
-// Copyright 2015, 2016 Eris Industries (UK) Ltd.
-// This file is part of Eris-RT
-
-// Eris-RT is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-
-// Eris-RT is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License
-// along with Eris-RT.  If not, see <http://www.gnu.org/licenses/>.
-
-// This code is ported over into Eris-RT from Go-Ethereum and further adapted,
-// with many thanks to the Ethereum foundation and the Go-Ethereum team.
-
-package event
-
-import (
-	"math/rand"
-	"sync"
-	"testing"
-	"time"
-)
-
-type testEvent int
-
-func TestSubCloseUnsub(t *testing.T) {
-	// the point of this test is **not** to panic
-	var mux TypeMux
-	mux.Stop()
-	sub := mux.Subscribe(int(0))
-	sub.Unsubscribe()
-}
-
-func TestSub(t *testing.T) {
-	mux := new(TypeMux)
-	defer mux.Stop()
-
-	sub := mux.Subscribe(testEvent(0))
-	go func() {
-		if err := mux.Post(testEvent(5)); err != nil {
-			t.Errorf("Post returned unexpected error: %v", err)
-		}
-	}()
-	ev := <-sub.Chan()
-
-	if ev.Data.(testEvent) != testEvent(5) {
-		t.Errorf("Got %v (%T), expected event %v (%T)",
-			ev, ev, testEvent(5), testEvent(5))
-	}
-}
-
-func TestMuxErrorAfterStop(t *testing.T) {
-	mux := new(TypeMux)
-	mux.Stop()
-
-	sub := mux.Subscribe(testEvent(0))
-	if _, isopen := <-sub.Chan(); isopen {
-		t.Errorf("subscription channel was not closed")
-	}
-	if err := mux.Post(testEvent(0)); err != ErrMuxClosed {
-		t.Errorf("Post error mismatch, got: %s, expected: %s", err, ErrMuxClosed)
-	}
-}
-
-func TestUnsubscribeUnblockPost(t *testing.T) {
-	mux := new(TypeMux)
-	defer mux.Stop()
-
-	sub := mux.Subscribe(testEvent(0))
-	unblocked := make(chan bool)
-	go func() {
-		mux.Post(testEvent(5))
-		unblocked <- true
-	}()
-
-	select {
-	case <-unblocked:
-		t.Errorf("Post returned before Unsubscribe")
-	default:
-		sub.Unsubscribe()
-		<-unblocked
-	}
-}
-
-func TestSubscribeDuplicateType(t *testing.T) {
-	mux := new(TypeMux)
-	expected := "event: duplicate type event.testEvent in Subscribe"
-
-	defer func() {
-		err := recover()
-		if err == nil {
-			t.Errorf("Subscribe didn't panic for duplicate type")
-		} else if err != expected {
-			t.Errorf("panic mismatch: got %#v, expected %#v", err, expected)
-		}
-	}()
-	mux.Subscribe(testEvent(1), testEvent(2))
-}
-
-func TestMuxConcurrent(t *testing.T) {
-	rand.Seed(time.Now().Unix())
-	mux := new(TypeMux)
-	defer mux.Stop()
-
-	recv := make(chan int)
-	poster := func() {
-		for {
-			err := mux.Post(testEvent(0))
-			if err != nil {
-				return
-			}
-		}
-	}
-	sub := func(i int) {
-		time.Sleep(time.Duration(rand.Intn(99)) * time.Millisecond)
-		sub := mux.Subscribe(testEvent(0))
-		<-sub.Chan()
-		sub.Unsubscribe()
-		recv <- i
-	}
-
-	go poster()
-	go poster()
-	go poster()
-	nsubs := 1000
-	for i := 0; i < nsubs; i++ {
-		go sub(i)
-	}
-
-	// wait until everyone has been served
-	counts := make(map[int]int, nsubs)
-	for i := 0; i < nsubs; i++ {
-		counts[<-recv]++
-	}
-	for i, count := range counts {
-		if count != 1 {
-			t.Errorf("receiver %d called %d times, expected only 1 call", i, count)
-		}
-	}
-}
-
-func emptySubscriber(mux *TypeMux, types ...interface{}) {
-	s := mux.Subscribe(testEvent(0))
-	go func() {
-		for _ = range s.Chan() {
-		}
-	}()
-}
-
-func BenchmarkPost3(b *testing.B) {
-	var mux = new(TypeMux)
-	defer mux.Stop()
-	emptySubscriber(mux, testEvent(0))
-	emptySubscriber(mux, testEvent(0))
-	emptySubscriber(mux, testEvent(0))
-
-	for i := 0; i < b.N; i++ {
-		mux.Post(testEvent(0))
-	}
-}
-
-func BenchmarkPostConcurrent(b *testing.B) {
-	var mux = new(TypeMux)
-	defer mux.Stop()
-	emptySubscriber(mux, testEvent(0))
-	emptySubscriber(mux, testEvent(0))
-	emptySubscriber(mux, testEvent(0))
-
-	var wg sync.WaitGroup
-	poster := func() {
-		for i := 0; i < b.N; i++ {
-			mux.Post(testEvent(0))
-		}
-		wg.Done()
-	}
-	wg.Add(5)
-	for i := 0; i < 5; i++ {
-		go poster()
-	}
-	wg.Wait()
-}
-
-// for comparison
-func BenchmarkChanSend(b *testing.B) {
-	c := make(chan interface{})
-	closed := make(chan struct{})
-	go func() {
-		for _ = range c {
-		}
-	}()
-
-	for i := 0; i < b.N; i++ {
-		select {
-		case c <- i:
-		case <-closed:
-		}
-	}
-}
diff --git a/event_new/example_test.go b/event_new/example_test.go
deleted file mode 100644
index 439589021747fcbd53b6fb2663b9b6d6547c2f65..0000000000000000000000000000000000000000
--- a/event_new/example_test.go
+++ /dev/null
@@ -1,77 +0,0 @@
-// Copyright 2014 The go-ethereum Authors
-// This file is part of the go-ethereum library.
-//
-// The go-ethereum library is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// The go-ethereum library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
-
-// Copyright 2015, 2016 Eris Industries (UK) Ltd.
-// This file is part of Eris-RT
-
-// Eris-RT is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-
-// Eris-RT is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License
-// along with Eris-RT.  If not, see <http://www.gnu.org/licenses/>.
-
-// This code is ported over into Eris-RT from Go-Ethereum and further adapted,
-// with many thanks to the Ethereum foundation and the Go-Ethereum team.
-
-package event
-
-import "fmt"
-
-func ExampleTypeMux() {
-	type someEvent struct{ I int }
-	type otherEvent struct{ S string }
-	type yetAnotherEvent struct{ X, Y int }
-
-	var mux TypeMux
-
-	// Start a subscriber.
-	done := make(chan struct{})
-	sub := mux.Subscribe(someEvent{}, otherEvent{})
-	go func() {
-		for event := range sub.Chan() {
-			fmt.Printf("Received: %#v\n", event.Data)
-		}
-		fmt.Println("done")
-		close(done)
-	}()
-
-	// Post some events.
-	mux.Post(someEvent{5})
-	mux.Post(yetAnotherEvent{X: 3, Y: 4})
-	mux.Post(someEvent{6})
-	mux.Post(otherEvent{"whoa"})
-
-	// Stop closes all subscription channels.
-	// The subscriber goroutine will print "done"
-	// and exit.
-	mux.Stop()
-
-	// Wait for subscriber to return.
-	<-done
-
-	// Output:
-	// Received: event.someEvent{I:5}
-	// Received: event.someEvent{I:6}
-	// Received: event.otherEvent{S:"whoa"}
-	// done
-}
diff --git a/event_new/filter/filter.go b/event_new/filter/filter.go
deleted file mode 100644
index 9742057dd9a16ee100c95bc86b16a715d654b219..0000000000000000000000000000000000000000
--- a/event_new/filter/filter.go
+++ /dev/null
@@ -1,114 +0,0 @@
-// Copyright 2014 The go-ethereum Authors
-// This file is part of the go-ethereum library.
-//
-// The go-ethereum library is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// The go-ethereum library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
-
-// Copyright 2015, 2016 Eris Industries (UK) Ltd.
-// This file is part of Eris-RT
-
-// Eris-RT is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-
-// Eris-RT is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License
-// along with Eris-RT.  If not, see <http://www.gnu.org/licenses/>.
-
-// This code is ported over into Eris-RT from Go-Ethereum and further adapted,
-// with many thanks to the Ethereum foundation and the Go-Ethereum team.
-
-// Package filter implements event filters.
-package filter
-
-import "reflect"
-
-type Filter interface {
-	Compare(Filter) bool
-	Trigger(data interface{})
-}
-
-type FilterEvent struct {
-	filter Filter
-	data   interface{}
-}
-
-type Filters struct {
-	id       int
-	watchers map[int]Filter
-	ch       chan FilterEvent
-
-	quit chan struct{}
-}
-
-func New() *Filters {
-	return &Filters{
-		ch:       make(chan FilterEvent),
-		watchers: make(map[int]Filter),
-		quit:     make(chan struct{}),
-	}
-}
-
-func (self *Filters) Start() {
-	go self.loop()
-}
-
-func (self *Filters) Stop() {
-	close(self.quit)
-}
-
-func (self *Filters) Notify(filter Filter, data interface{}) {
-	self.ch <- FilterEvent{filter, data}
-}
-
-func (self *Filters) Install(watcher Filter) int {
-	self.watchers[self.id] = watcher
-	self.id++
-
-	return self.id - 1
-}
-
-func (self *Filters) Uninstall(id int) {
-	delete(self.watchers, id)
-}
-
-func (self *Filters) loop() {
-out:
-	for {
-		select {
-		case <-self.quit:
-			break out
-		case event := <-self.ch:
-			for _, watcher := range self.watchers {
-				if reflect.TypeOf(watcher) == reflect.TypeOf(event.filter) {
-					if watcher.Compare(event.filter) {
-						watcher.Trigger(event.data)
-					}
-				}
-			}
-		}
-	}
-}
-
-func (self *Filters) Match(a, b Filter) bool {
-	return reflect.TypeOf(a) == reflect.TypeOf(b) && a.Compare(b)
-}
-
-func (self *Filters) Get(i int) Filter {
-	return self.watchers[i]
-}
diff --git a/event_new/filter/filter_test.go b/event_new/filter/filter_test.go
deleted file mode 100644
index c70d1ecce6e8b9c0fb120c8eb2d6f83d049cf48e..0000000000000000000000000000000000000000
--- a/event_new/filter/filter_test.go
+++ /dev/null
@@ -1,79 +0,0 @@
-// Copyright 2014 The go-ethereum Authors
-// This file is part of the go-ethereum library.
-//
-// The go-ethereum library is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// The go-ethereum library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
-
-// Copyright 2015, 2016 Eris Industries (UK) Ltd.
-// This file is part of Eris-RT
-
-// Eris-RT is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-
-// Eris-RT is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License
-// along with Eris-RT.  If not, see <http://www.gnu.org/licenses/>.
-
-// This code is ported over into Eris-RT from Go-Ethereum and further adapted,
-// with many thanks to the Ethereum foundation and the Go-Ethereum team.
-
-package filter
-
-import (
-	"testing"
-	"time"
-)
-
-// Simple test to check if baseline matching/mismatching filtering works.
-func TestFilters(t *testing.T) {
-	fm := New()
-	fm.Start()
-
-	// Register two filters to catch posted data
-	first := make(chan struct{})
-	fm.Install(Generic{
-		Str1: "hello",
-		Fn: func(data interface{}) {
-			first <- struct{}{}
-		},
-	})
-	second := make(chan struct{})
-	fm.Install(Generic{
-		Str1: "hello1",
-		Str2: "hello",
-		Fn: func(data interface{}) {
-			second <- struct{}{}
-		},
-	})
-	// Post an event that should only match the first filter
-	fm.Notify(Generic{Str1: "hello"}, true)
-	fm.Stop()
-
-	// Ensure only the mathcing filters fire
-	select {
-	case <-first:
-	case <-time.After(100 * time.Millisecond):
-		t.Error("matching filter timed out")
-	}
-	select {
-	case <-second:
-		t.Error("mismatching filter fired")
-	case <-time.After(100 * time.Millisecond):
-	}
-}
diff --git a/event_new/filter/generic_filter.go b/event_new/filter/generic_filter.go
deleted file mode 100644
index 6b475b97214502d5646c2ab7ccb586f33b3b8484..0000000000000000000000000000000000000000
--- a/event_new/filter/generic_filter.go
+++ /dev/null
@@ -1,67 +0,0 @@
-// Copyright 2014 The go-ethereum Authors
-// This file is part of the go-ethereum library.
-//
-// The go-ethereum library is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// The go-ethereum library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
-
-// Copyright 2015, 2016 Eris Industries (UK) Ltd.
-// This file is part of Eris-RT
-
-// Eris-RT is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-
-// Eris-RT is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License
-// along with Eris-RT.  If not, see <http://www.gnu.org/licenses/>.
-
-// This code is ported over into Eris-RT from Go-Ethereum and further adapted,
-// with many thanks to the Ethereum foundation and the Go-Ethereum team.
-
-package filter
-
-type Generic struct {
-	Str1, Str2, Str3 string
-	Data             map[string]struct{}
-
-	Fn func(data interface{})
-}
-
-// self = registered, f = incoming
-func (self Generic) Compare(f Filter) bool {
-	var strMatch, dataMatch = true, true
-
-	filter := f.(Generic)
-	if (len(self.Str1) > 0 && filter.Str1 != self.Str1) ||
-		(len(self.Str2) > 0 && filter.Str2 != self.Str2) ||
-		(len(self.Str3) > 0 && filter.Str3 != self.Str3) {
-		strMatch = false
-	}
-
-	for k, _ := range self.Data {
-		if _, ok := filter.Data[k]; !ok {
-			return false
-		}
-	}
-
-	return strMatch && dataMatch
-}
-
-func (self Generic) Trigger(data interface{}) {
-	self.Fn(data)
-}
diff --git a/files/files.go b/files/files.go
index aa9e59c83a11c980383e50198125fde577dd59cf..a11c8a62f145ba42813c5086713b9241f9212e21 100644
--- a/files/files.go
+++ b/files/files.go
@@ -1,4 +1,18 @@
 // Cross-platform file utils.
+// 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 files
 
 import (
diff --git a/files/files_test.go b/files/files_test.go
index 16943df7f53d6f5e899e89b26c224d68aa71705c..1cf51762f6c7c8b3ae3d3977026318c73341b8f7 100644
--- a/files/files_test.go
+++ b/files/files_test.go
@@ -1,3 +1,17 @@
+// 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 files
 
 import (
diff --git a/files/log.go b/files/log.go
index a18f6b6a6ec7420d469269b33832a2e5cc277a43..3914c6c7b80df67fb9ad47a2f9e3714a81a4d19a 100644
--- a/files/log.go
+++ b/files/log.go
@@ -1,3 +1,17 @@
+// 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 files
 
 import (
diff --git a/files/posix.go b/files/posix.go
index e3dcb079ddcb0fc2d7a86b428317da62d7a5cac8..037f40dd7cd12c5c679e89be35661b2029e7e5d2 100644
--- a/files/posix.go
+++ b/files/posix.go
@@ -1,5 +1,19 @@
 // +build !windows
 
+// 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 files
 
 import "os"
diff --git a/files/windows.go b/files/windows.go
index 495dd30386412cfde0ffe73d8d4c22ed3558a3a6..27a7fd84a447a8843730ac517bc9605832cb39d0 100644
--- a/files/windows.go
+++ b/files/windows.go
@@ -1,5 +1,19 @@
 // +build windows
 
+// 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 files
 
 import (
diff --git a/genesis/gen_test.go b/genesis/gen_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..3a55eea7df1cbbba038cfb07be248dc383f5c889
--- /dev/null
+++ b/genesis/gen_test.go
@@ -0,0 +1,178 @@
+// 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 genesis
+
+import (
+	"bytes"
+	"io/ioutil"
+	"os"
+	"path/filepath"
+	"testing"
+	"time"
+)
+
+// set the chain ID
+var chainID string = "genesis-file-maker-test"
+
+var genesisFileExpected string = `{
+	"genesis_time": "0001-01-01T00:00:00.000Z",
+	"chain_id": "genesis-file-maker-test",
+	"params": null,
+	"accounts": [
+		{
+			"address": "74417C1BEFB3938B71B22B202050A4C6591FFCF6",
+			"amount": 9999999999,
+			"name": "genesis-file-maker-test_developer_000",
+			"permissions": {
+				"base": {
+					"perms": 14430,
+					"set": 16383
+				},
+				"roles": []
+			}
+		},
+		{
+			"address": "0C9DAEA4046491A661FCE0B41B0CAA2AD3415268",
+			"amount": 99999999999999,
+			"name": "genesis-file-maker-test_full_000",
+			"permissions": {
+				"base": {
+					"perms": 16383,
+					"set": 16383
+				},
+				"roles": []
+			}
+		},
+		{
+			"address": "E1BD50A1B90A15861F5CF0F182D291F556B21A86",
+			"amount": 9999999999,
+			"name": "genesis-file-maker-test_participant_000",
+			"permissions": {
+				"base": {
+					"perms": 2118,
+					"set": 16383
+				},
+				"roles": []
+			}
+		},
+		{
+			"address": "A6C8E2DE652DB8ADB4036293DC21F8FE389D77C2",
+			"amount": 9999999999,
+			"name": "genesis-file-maker-test_root_000",
+			"permissions": {
+				"base": {
+					"perms": 16383,
+					"set": 16383
+				},
+				"roles": []
+			}
+		},
+		{
+			"address": "E96CB7910001320B6F1E2266A8431D5E98FF0183",
+			"amount": 9999999999,
+			"name": "genesis-file-maker-test_validator_000",
+			"permissions": {
+				"base": {
+					"perms": 32,
+					"set": 16383
+				},
+				"roles": []
+			}
+		}
+	],
+	"validators": [
+		{
+			"pub_key": [
+				1,
+				"238E1A77CC7CDCD13F4D77841F1FE4A46A77DB691EC89718CD0D4CB3409F61D2"
+			],
+			"amount": 9999999999,
+			"name": "genesis-file-maker-test_full_000",
+			"unbond_to": [
+				{
+					"address": "0C9DAEA4046491A661FCE0B41B0CAA2AD3415268",
+					"amount": 9999999999
+				}
+			]
+		},
+		{
+			"pub_key": [
+				1,
+				"7F53D78C526F96C87ACBD0D2B9DB2E9FC176981623D26B1DB1CF59748EE9F4CF"
+			],
+			"amount": 9999999998,
+			"name": "genesis-file-maker-test_validator_000",
+			"unbond_to": [
+				{
+					"address": "E96CB7910001320B6F1E2266A8431D5E98FF0183",
+					"amount": 9999999998
+				}
+			]
+		}
+	]
+}`
+
+var accountsCSV string = `F0BD5CE45D306D61C9AB73CE5268C2B59D52CAF7127EF0E3B65523302254350A,9999999999,genesis-file-maker-test_developer_000,14430,16383
+238E1A77CC7CDCD13F4D77841F1FE4A46A77DB691EC89718CD0D4CB3409F61D2,99999999999999,genesis-file-maker-test_full_000,16383,16383
+E37A655E560D53721C9BB06BA742398323504DFE2EB2C67E71F8D16E71E0471B,9999999999,genesis-file-maker-test_participant_000,2118,16383
+EC0E38CC8308EC9E720EE839242A7BC5C781D1F852E962FAC5A8E0599CE5B224,9999999999,genesis-file-maker-test_root_000,16383,16383
+7F53D78C526F96C87ACBD0D2B9DB2E9FC176981623D26B1DB1CF59748EE9F4CF,9999999999,genesis-file-maker-test_validator_000,32,16383`
+
+var validatorsCSV string = `238E1A77CC7CDCD13F4D77841F1FE4A46A77DB691EC89718CD0D4CB3409F61D2,9999999999,genesis-file-maker-test_full_000,16383,16383
+7F53D78C526F96C87ACBD0D2B9DB2E9FC176981623D26B1DB1CF59748EE9F4CF,9999999998,genesis-file-maker-test_validator_000,32,16383`
+
+func TestKnownCSV(t *testing.T) {
+	// make temp dir
+	dir, err := ioutil.TempDir(os.TempDir(), "genesis-file-maker-test")
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	defer func() {
+		//cleanup
+		os.RemoveAll(dir)
+		if err != nil {
+			t.Fatal(err)
+		}
+
+	}()
+
+	// set the filepaths to be written to
+	accountsCSVpath := filepath.Join(dir, "accounts.csv")
+	validatorsCSVpath := filepath.Join(dir, "validators.csv")
+
+	// write the accounts.csv
+	if err := ioutil.WriteFile(accountsCSVpath, []byte(accountsCSV), 0600); err != nil {
+		t.Fatal(err)
+	}
+
+	// write the validators.csv
+	if err := ioutil.WriteFile(validatorsCSVpath, []byte(validatorsCSV), 0600); err != nil {
+		t.Fatal(err)
+	}
+
+	// create the genesis file
+	// NOTE: [ben] set time to zero time, "genesis_time": "0001-01-01T00:00:00.000Z"
+	genesisFileWritten, err := generateKnownWithTime(chainID, accountsCSVpath, validatorsCSVpath, time.Time{})
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	// compare
+	if !bytes.Equal([]byte(genesisFileExpected), []byte(genesisFileWritten)) {
+		t.Fatalf("Bad genesis file: got (%s), expected (%s)", genesisFileWritten, genesisFileExpected)
+	}
+
+}
diff --git a/genesis/genesis.go b/genesis/genesis.go
new file mode 100644
index 0000000000000000000000000000000000000000..3ca287e55bc6c214a7032413e665fb85103a1d79
--- /dev/null
+++ b/genesis/genesis.go
@@ -0,0 +1,84 @@
+// 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 genesis
+
+import (
+	"bytes"
+	"encoding/json"
+	"time"
+
+	ptypes "github.com/eris-ltd/eris-db/permission/types"
+	wire "github.com/tendermint/go-wire"
+)
+
+// MakeGenesisDocFromAccounts takes a chainName and a slice of pointers to GenesisAccount,
+// and a slice of pointers to GenesisValidator to construct a GenesisDoc, or returns an error on
+// failure.  In particular MakeGenesisDocFromAccount uses the local time as a
+// timestamp for the GenesisDoc.
+func MakeGenesisDocFromAccounts(chainName string, accounts []*GenesisAccount,
+	validators []*GenesisValidator) (GenesisDoc, error) {
+
+	// TODO: assert valid accounts and validators
+	// TODO: [ben] expose setting global permissions
+	globalPermissions := ptypes.DefaultAccountPermissions.Clone()
+	genesisParameters := &GenesisParams{
+		GlobalPermissions: &globalPermissions,
+	}
+	// copy slice of pointers to accounts into slice of accounts
+	accountsCopy := make([]GenesisAccount, len(accounts))
+	for i, genesisAccount := range accounts {
+		accountsCopy[i] = genesisAccount.Clone()
+	}
+	// copy slice of pointers to validators into slice of validators
+	validatorsCopy := make([]GenesisValidator, len(validators))
+	for i, genesisValidator := range validators {
+		genesisValidatorCopy, err := genesisValidator.Clone()
+		if err != nil {
+			return GenesisDoc{}, err
+		}
+		validatorsCopy[i] = genesisValidatorCopy
+	}
+	genesisDoc := GenesisDoc{
+		GenesisTime: time.Now(),
+		// TODO: this needs to be corrected for ChainName, and ChainId
+		// is the derived hash from the GenesisDoc serialised bytes
+		ChainID:    chainName,
+		Params:     genesisParameters,
+		Accounts:   accountsCopy,
+		Validators: validatorsCopy,
+	}
+	return genesisDoc, nil
+}
+
+// GetGenesisFileBytes returns the JSON (not-yet) canonical bytes for a given
+// GenesisDoc or an error.  In a first rewrite, rely on go-wire
+// for the JSON serialisation with type-bytes.
+func GetGenesisFileBytes(genesisDoc *GenesisDoc) ([]byte, error) {
+
+	// TODO: write JSON in canonical order
+	var err error
+	buffer, n := new(bytes.Buffer), new(int)
+	// write JSON with go-wire type-bytes (for public keys)
+	wire.WriteJSON(genesisDoc, buffer, n, &err)
+	if err != nil {
+		return nil, err
+	}
+	// rewrite buffer with indentation
+	indentedBuffer := new(bytes.Buffer)
+	if err := json.Indent(indentedBuffer, buffer.Bytes(), "", "\t"); err != nil {
+		return nil, err
+	}
+	return indentedBuffer.Bytes(), nil
+}
diff --git a/genesis/make_genesis_file.go b/genesis/make_genesis_file.go
new file mode 100644
index 0000000000000000000000000000000000000000..a4dce67bf1f200c23da9055ee6ff1cc028aecc12
--- /dev/null
+++ b/genesis/make_genesis_file.go
@@ -0,0 +1,249 @@
+// 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 genesis
+
+import (
+	"bytes"
+	"encoding/csv"
+	"encoding/hex"
+	"encoding/json"
+	"fmt"
+	"os"
+	"strconv"
+	"time"
+
+	ptypes "github.com/eris-ltd/eris-db/permission/types"
+	"github.com/eris-ltd/eris-db/util"
+
+	"github.com/tendermint/go-crypto"
+	wire "github.com/tendermint/go-wire"
+)
+
+//------------------------------------------------------------------------------------
+// interface functions that are consumed by monax tooling
+// TODO: [ben] these interfaces will be deprecated from v0.17
+
+func GenerateKnown(chainID, accountsPathCSV, validatorsPathCSV string) (string, error) {
+	return generateKnownWithTime(chainID, accountsPathCSV, validatorsPathCSV,
+		// set the timestamp for the genesis
+		time.Now())
+}
+
+//------------------------------------------------------------------------------------
+// interface functions that are consumed by monax tooling
+
+func GenerateGenesisFileBytes(chainName string, genesisAccounts []*GenesisAccount,
+	genesisValidators []*GenesisValidator) ([]byte, error) {
+	genesisDoc, err := MakeGenesisDocFromAccounts(chainName, genesisAccounts, genesisValidators)
+
+	buf, buf2, n := new(bytes.Buffer), new(bytes.Buffer), new(int)
+	wire.WriteJSON(genesisDoc, buf, n, &err)
+	if err != nil {
+		return nil, err
+	}
+	if err := json.Indent(buf2, buf.Bytes(), "", "\t"); err != nil {
+		return nil, err
+	}
+
+	return buf2.Bytes(), nil
+}
+
+//------------------------------------------------------------------------------------
+// core functions that provide functionality for monax tooling in v0.16
+
+// GenerateKnownWithTime takes chainId, an accounts and validators CSV filepath
+// and a timestamp to generate the string of `genesis.json`
+// NOTE: [ben] is introduced as technical debt to preserve the signature
+// of GenerateKnown but in order to introduce the timestamp gradually
+// This will be deprecated in v0.17
+func generateKnownWithTime(chainID, accountsPathCSV, validatorsPathCSV string,
+	genesisTime time.Time) (string, error) {
+	var genDoc *GenesisDoc
+
+	// TODO [eb] eliminate reading priv_val ... [zr] where?
+	if accountsPathCSV == "" || validatorsPathCSV == "" {
+		return "", fmt.Errorf("both accounts.csv and validators.csv is required")
+	}
+
+	pubkeys, amts, names, perms, setbits, err := parseCsv(validatorsPathCSV)
+	if err != nil {
+		return "", err
+	}
+
+	pubkeysA, amtsA, namesA, permsA, setbitsA, err := parseCsv(accountsPathCSV)
+	if err != nil {
+		return "", err
+	}
+
+	genDoc = newGenDoc(chainID, genesisTime, len(pubkeys), len(pubkeysA))
+	for i, pk := range pubkeys {
+		genDocAddValidator(genDoc, pk, amts[i], names[i], perms[i], setbits[i], i)
+	}
+	for i, pk := range pubkeysA {
+		genDocAddAccount(genDoc, pk, amtsA[i], namesA[i], permsA[i], setbitsA[i], i)
+	}
+
+	buf, buf2, n := new(bytes.Buffer), new(bytes.Buffer), new(int)
+	wire.WriteJSON(genDoc, buf, n, &err)
+	if err != nil {
+		return "", err
+	}
+	if err := json.Indent(buf2, buf.Bytes(), "", "\t"); err != nil {
+		return "", err
+	}
+
+	return buf2.String(), nil
+}
+
+//-----------------------------------------------------------------------------
+// gendoc convenience functions
+
+func newGenDoc(chainID string, genesisTime time.Time, nVal, nAcc int) *GenesisDoc {
+	genDoc := GenesisDoc{
+		ChainID:     chainID,
+		GenesisTime: genesisTime,
+	}
+	genDoc.Accounts = make([]GenesisAccount, nAcc)
+	genDoc.Validators = make([]GenesisValidator, nVal)
+	return &genDoc
+}
+
+func genDocAddAccount(genDoc *GenesisDoc, pubKey crypto.PubKeyEd25519, amt int64, name string, perm, setbit ptypes.PermFlag, index int) {
+	addr := pubKey.Address()
+	acc := GenesisAccount{
+		Address: addr,
+		Amount:  amt,
+		Name:    name,
+		Permissions: &ptypes.AccountPermissions{
+			Base: ptypes.BasePermissions{
+				Perms:  perm,
+				SetBit: setbit,
+			},
+		},
+	}
+	if index < 0 {
+		genDoc.Accounts = append(genDoc.Accounts, acc)
+	} else {
+		genDoc.Accounts[index] = acc
+	}
+}
+
+func genDocAddValidator(genDoc *GenesisDoc, pubKey crypto.PubKeyEd25519, amt int64, name string, perm, setbit ptypes.PermFlag, index int) {
+	addr := pubKey.Address()
+	genDoc.Validators[index] = GenesisValidator{
+		PubKey: pubKey,
+		Amount: amt,
+		Name:   name,
+		UnbondTo: []BasicAccount{
+			{
+				Address: addr,
+				Amount:  amt,
+			},
+		},
+	}
+	// [zr] why no index < 0 like in genDocAddAccount?
+}
+
+//-----------------------------------------------------------------------------
+// util functions
+
+// convert hex strings to ed25519 pubkeys
+func pubKeyStringsToPubKeys(pubkeys []string) ([]crypto.PubKeyEd25519, error) {
+	pubKeys := make([]crypto.PubKeyEd25519, len(pubkeys))
+	for i, k := range pubkeys {
+		pubBytes, err := hex.DecodeString(k)
+		if err != nil {
+			return pubKeys, err
+		}
+		copy(pubKeys[i][:], pubBytes)
+	}
+	return pubKeys, nil
+}
+
+// empty is over written
+func ifExistsElse(list []string, index int, defaultValue string) string {
+	if len(list) > index {
+		if list[index] != "" {
+			return list[index]
+		}
+	}
+	return defaultValue
+}
+
+// takes a csv in the following format: pubkey, starting balance, name, permissions, setbit
+func parseCsv(filePath string) (pubKeys []crypto.PubKeyEd25519, amts []int64, names []string, perms, setbits []ptypes.PermFlag, err error) {
+
+	csvFile, err := os.Open(filePath)
+	if err != nil {
+		util.Fatalf("Couldn't open file: %s: %v", filePath, err)
+	}
+	defer csvFile.Close()
+
+	r := csv.NewReader(csvFile)
+	//r.FieldsPerRecord = # of records expected
+	params, err := r.ReadAll()
+	if err != nil {
+		util.Fatalf("Couldn't read file: %v", err)
+
+	}
+
+	pubkeys := make([]string, len(params))
+	amtS := make([]string, len(params))
+	names = make([]string, len(params))
+	permsS := make([]string, len(params))
+	setbitS := make([]string, len(params))
+	for i, each := range params {
+		pubkeys[i] = each[0]
+		amtS[i] = ifExistsElse(each, 1, "1000")
+		names[i] = ifExistsElse(each, 2, "")
+		permsS[i] = ifExistsElse(each, 3, fmt.Sprintf("%d", ptypes.DefaultPermFlags))
+		setbitS[i] = ifExistsElse(each, 4, permsS[i])
+	}
+
+	//TODO convert int to uint64, see issue #25
+	perms = make([]ptypes.PermFlag, len(permsS))
+	for i, perm := range permsS {
+		pflag, err := strconv.Atoi(perm)
+		if err != nil {
+			util.Fatalf("Permissions (%v) must be an integer", perm)
+		}
+		perms[i] = ptypes.PermFlag(pflag)
+	}
+	setbits = make([]ptypes.PermFlag, len(setbitS))
+	for i, setbit := range setbitS {
+		setbitsFlag, err := strconv.Atoi(setbit)
+		if err != nil {
+			util.Fatalf("SetBits (%v) must be an integer", setbit)
+		}
+		setbits[i] = ptypes.PermFlag(setbitsFlag)
+	}
+
+	// convert amts to ints
+	amts = make([]int64, len(amtS))
+	for i, a := range amtS {
+		if amts[i], err = strconv.ParseInt(a, 10, 64); err != nil {
+			err = fmt.Errorf("Invalid amount: %v", err)
+			return
+		}
+	}
+
+	// convert pubkey hex strings to struct
+	pubKeys, err = pubKeyStringsToPubKeys(pubkeys)
+	if err != nil {
+		return
+	}
+
+	return pubKeys, amts, names, perms, setbits, nil
+}
diff --git a/genesis/maker.go b/genesis/maker.go
new file mode 100644
index 0000000000000000000000000000000000000000..707d8150ee17bbe5c4f8191ba3e2d8018de7ddcd
--- /dev/null
+++ b/genesis/maker.go
@@ -0,0 +1,84 @@
+// 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 genesis
+
+import (
+	"fmt"
+
+	ptypes "github.com/eris-ltd/eris-db/permission/types"
+
+	"github.com/tendermint/go-crypto"
+)
+
+const (
+	PublicKeyEd25519ByteLength   int = 32
+	PublicKeySecp256k1ByteLength int = 64
+)
+
+// NewGenesisAccount returns a new GenesisAccount
+func NewGenesisAccount(address []byte, amount int64, name string,
+	permissions *ptypes.AccountPermissions) *GenesisAccount {
+	return &GenesisAccount{
+		Address:     address,
+		Amount:      amount,
+		Name:        name,
+		Permissions: permissions,
+	}
+}
+
+func NewGenesisValidator(amount int64, name string, unbondToAddress []byte,
+	unbondAmount int64, keyType string, publicKeyBytes []byte) (*GenesisValidator, error) {
+	// convert the key bytes into a typed fixed size byte array
+	var typedPublicKeyBytes []byte
+	switch keyType {
+	case "ed25519":
+		// TODO: [ben] functionality and checks need to be inherit in the type
+		if len(publicKeyBytes) != PublicKeyEd25519ByteLength {
+			return nil, fmt.Errorf("Invalid length provided for ed25519 public key (len %v)",
+				len(publicKeyBytes))
+		}
+		// ed25519 has type byte 0x01
+		typedPublicKeyBytes = make([]byte, PublicKeyEd25519ByteLength+1)
+		// prepend type byte to public key
+		typedPublicKeyBytes = append([]byte{crypto.PubKeyTypeEd25519}, publicKeyBytes...)
+	case "secp256k1":
+		if len(publicKeyBytes) != PublicKeySecp256k1ByteLength {
+			return nil, fmt.Errorf("Invalid length provided for secp256k1 public key (len %v)",
+				len(publicKeyBytes))
+		}
+		// secp256k1 has type byte 0x02
+		typedPublicKeyBytes = make([]byte, PublicKeySecp256k1ByteLength+1)
+		// prepend type byte to public key
+		typedPublicKeyBytes = append([]byte{crypto.PubKeyTypeSecp256k1}, publicKeyBytes...)
+	default:
+		return nil, fmt.Errorf("Unsupported key type (%s)", keyType)
+	}
+	newPublicKey, err := crypto.PubKeyFromBytes(typedPublicKeyBytes)
+	if err != nil {
+		return nil, err
+	}
+	// ability to unbond to multiple accounts currently unused
+	var unbondTo []BasicAccount
+
+	return &GenesisValidator{
+		PubKey: newPublicKey,
+		Amount: unbondAmount,
+		Name:   name,
+		UnbondTo: append(unbondTo, BasicAccount{
+			Address: unbondToAddress,
+			Amount:  unbondAmount,
+		}),
+	}, nil
+}
diff --git a/genesis/types.go b/genesis/types.go
new file mode 100644
index 0000000000000000000000000000000000000000..c962a3c316d406f4e1b2cac7fde1bab14c37b2ea
--- /dev/null
+++ b/genesis/types.go
@@ -0,0 +1,157 @@
+// 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 genesis
+
+import (
+	"fmt"
+	"os"
+	"time"
+
+	ptypes "github.com/eris-ltd/eris-db/permission/types"
+
+	"github.com/tendermint/go-crypto"
+	"github.com/tendermint/go-wire"
+)
+
+//------------------------------------------------------------
+// we store the GenesisDoc in the db under this key
+
+var GenDocKey = []byte("GenDocKey")
+
+//------------------------------------------------------------
+// core types for a genesis definition
+
+type BasicAccount struct {
+	Address []byte `json:"address"`
+	Amount  int64  `json:"amount"`
+}
+
+type GenesisAccount struct {
+	Address     []byte                     `json:"address"`
+	Amount      int64                      `json:"amount"`
+	Name        string                     `json:"name"`
+	Permissions *ptypes.AccountPermissions `json:"permissions"`
+}
+
+type GenesisValidator struct {
+	PubKey   crypto.PubKey  `json:"pub_key"`
+	Amount   int64          `json:"amount"`
+	Name     string         `json:"name"`
+	UnbondTo []BasicAccount `json:"unbond_to"`
+}
+
+// GenesisPrivateValidator marshals the state of the private
+// validator for the purpose of Genesis creation; and hence
+// is defined in genesis and not under consensus, where
+// PrivateValidator (currently inherited from Tendermint) is.
+type GenesisPrivateValidator struct {
+	Address    string        `json:"address"`
+	PubKey     []interface{} `json:"pub_key"`
+	PrivKey    []interface{} `json:"priv_key"`
+	LastHeight int64         `json:"last_height"`
+	LastRound  int64         `json:"last_round"`
+	LastStep   int64         `json:"last_step"`
+}
+
+type GenesisParams struct {
+	GlobalPermissions *ptypes.AccountPermissions `json:"global_permissions"`
+}
+
+//------------------------------------------------------------
+// GenesisDoc is stored in the state database
+
+type GenesisDoc struct {
+	GenesisTime time.Time          `json:"genesis_time"`
+	ChainID     string             `json:"chain_id"`
+	Params      *GenesisParams     `json:"params"`
+	Accounts    []GenesisAccount   `json:"accounts"`
+	Validators  []GenesisValidator `json:"validators"`
+}
+
+//------------------------------------------------------------
+// Make genesis state from file
+
+func GenesisDocFromJSON(jsonBlob []byte) (genState *GenesisDoc) {
+	var err error
+	wire.ReadJSONPtr(&genState, jsonBlob, &err)
+	if err != nil {
+		fmt.Printf("Couldn't read GenesisDoc: %v", err)
+		// TODO: on error return error, not exit
+		os.Exit(1)
+	}
+	return
+}
+
+//------------------------------------------------------------
+// Methods for genesis types
+// NOTE: breaks formatting convention
+// TODO: split each genesis type in its own file definition
+
+//------------------------------------------------------------
+// GenesisAccount methods
+
+// Clone clones the genesis account
+func (genesisAccount *GenesisAccount) Clone() GenesisAccount {
+	// clone the address
+	addressClone := make([]byte, len(genesisAccount.Address))
+	copy(addressClone, genesisAccount.Address)
+	// clone the account permissions
+	accountPermissionsClone := genesisAccount.Permissions.Clone()
+	return GenesisAccount{
+		Address:     addressClone,
+		Amount:      genesisAccount.Amount,
+		Name:        genesisAccount.Name,
+		Permissions: &accountPermissionsClone,
+	}
+}
+
+//------------------------------------------------------------
+// GenesisValidator methods
+
+// Clone clones the genesis validator
+func (genesisValidator *GenesisValidator) Clone() (GenesisValidator, error) {
+	if genesisValidator == nil {
+		return GenesisValidator{}, fmt.Errorf("Cannot clone nil GenesisValidator.")
+	}
+	if genesisValidator.PubKey == nil {
+		return GenesisValidator{}, fmt.Errorf("Invalid GenesisValidator %s with nil public key.",
+			genesisValidator.Name)
+	}
+	// clone the addresses to unbond to
+	unbondToClone := make([]BasicAccount, len(genesisValidator.UnbondTo))
+	for i, basicAccount := range genesisValidator.UnbondTo {
+		unbondToClone[i] = basicAccount.Clone()
+	}
+	return GenesisValidator{
+		PubKey:   genesisValidator.PubKey,
+		Amount:   genesisValidator.Amount,
+		Name:     genesisValidator.Name,
+		UnbondTo: unbondToClone,
+	}, nil
+}
+
+//------------------------------------------------------------
+// BasicAccount methods
+
+// Clone clones the basic account
+func (basicAccount *BasicAccount) Clone() BasicAccount {
+	// clone the address
+	addressClone := make([]byte, len(basicAccount.Address))
+	copy(addressClone, basicAccount.Address)
+	return BasicAccount{
+		Address: addressClone,
+		Amount:  basicAccount.Amount,
+	}
+}
diff --git a/glide.lock b/glide.lock
index 76c7e0b2c0dc6b668890e5388cc0820b9d4b430c..6887d752d90fc9ab64b4b6d7181b92262ed992d3 100644
--- a/glide.lock
+++ b/glide.lock
@@ -1,12 +1,12 @@
-hash: f1f85c5d4b9520217cc6fa9fd7b7e97790e737def9bc08ab45d53d5db729c779
-updated: 2016-09-14T20:54:48.289839938+02:00
+hash: 310aa7c7435ad7dd1c3eb6772a42065b5f506e38e195107bdbfb1584833add9a
+updated: 2017-02-21T01:43:41.814044634Z
 imports:
 - name: github.com/Azure/go-ansiterm
   version: 388960b655244e76e24c75f48631564eaefade62
   subpackages:
   - winterm
 - name: github.com/btcsuite/btcd
-  version: 7de7bddba9d9a8b0b7490931e346e8f10d0bdb7f
+  version: 153dca5c1e4b5d1ea1523592495e5bedfa503391
   subpackages:
   - btcec
 - name: github.com/btcsuite/fastsha256
@@ -20,18 +20,17 @@ imports:
 - name: github.com/bugsnag/panicwrap
   version: d6191e27ad06236eaad65d79e49a08b03b9f8029
 - name: github.com/BurntSushi/toml
-  version: f0aeabca5a127c4078abb8c8d64298b147264b55
+  version: 99064174e013895bbd9b025c31100bd1d9b590ca
 - name: github.com/davecgh/go-spew
   version: 5215b55f46b2b919f50a1df0eaa5886afe4e3b3d
-- name: github.com/eris-ltd/common
-  version: 8ca15f5455104403db4202c995e2f6e161654c02
-  subpackages:
-  - go/docs
-  - go/common
+- name: github.com/eapache/channels
+  version: 47238d5aae8c0fefd518ef2bee46290909cf8263
+- name: github.com/eapache/queue
+  version: 44cc805cf13205b55f69e14bcb69867d1ae92f98
+- name: github.com/ebuchman/fail-test
+  version: c1eddaa09da2b4017351245b0d43234955276798
 - name: github.com/eris-ltd/eris-keys
   version: 114ebc77443db9a153692233294e48bc7e184215
-- name: github.com/eris-ltd/eris-logger
-  version: ea48a395d6ecc0eccc67a26da9fc7a6106fabb84
 - name: github.com/fsnotify/fsnotify
   version: 30411dbcefb7a1da7e84f75530ad3abe4011b4f8
 - name: github.com/gin-gonic/gin
@@ -39,37 +38,53 @@ imports:
   subpackages:
   - binding
   - render
+- name: github.com/go-kit/kit
+  version: f66b0e13579bfc5a48b9e2a94b1209c107ea1f41
+  subpackages:
+  - log
+- name: github.com/go-logfmt/logfmt
+  version: 390ab7935ee28ec6b286364bba9b4dd6410cb3d5
 - name: github.com/go-stack/stack
   version: 100eb0c0a9c5b306ca2fb4f165df21d80ada4b82
+- name: github.com/gogo/protobuf
+  version: f9114dace7bd920b32f943b3c73fafbcbab2bf31
 - name: github.com/golang/protobuf
-  version: 0c1f6d65b5a189c2250d10e71a5506f06f9fa0a0
+  version: 8ee79997227bf9b34611aee7946ae64735e6fd93
   subpackages:
   - proto
 - name: github.com/golang/snappy
   version: d9eb7a3d35ec988b8585d4a0068e462c27d28380
 - name: github.com/gorilla/websocket
-  version: a68708917c6a4f06314ab4e52493cc61359c9d42
+  version: 17634340a83afe0cab595e40fbc63f6ffa1d8915
 - name: github.com/hashicorp/hcl
   version: da486364306ed66c218be9b7953e19173447c18b
   subpackages:
   - hcl/ast
   - hcl/parser
-  - hcl/token
-  - json/parser
   - hcl/scanner
   - hcl/strconv
+  - hcl/token
+  - json/parser
   - json/scanner
   - json/token
+- name: github.com/inconshreveable/log15
+  version: 46a701a619de90c65a78c04d1a58bf02585e9701
+  subpackages:
+  - term
 - name: github.com/inconshreveable/mousetrap
   version: 76626ae9c91c4f2a10f34cad8ce83ea42c93bb75
+- name: github.com/jmhodges/levigo
+  version: c42d9e0ca023e2198120196f842701bb4c55d7b9
 - name: github.com/magiconair/properties
   version: c265cfa48dda6474e208715ca93e987829f572f8
 - name: github.com/manucorporat/sse
   version: ee05b128a739a0fb76c7ebd3ae4810c1de808d6d
+- name: github.com/Masterminds/glide
+  version: 84607742b10f492430762d038e954236bbaf23f7
 - name: github.com/mattn/go-colorable
-  version: 9056b7a9f2d1f2d96498d6d146acd1f9d5ed3d59
+  version: d228849504861217f796da67fae4f6e347643f15
 - name: github.com/mattn/go-isatty
-  version: 56b76bdf51f7708750eac80fa38b952bb9f32639
+  version: 30a891c33c7cde7b02a981314b4228ec99380cca
 - name: github.com/mitchellh/mapstructure
   version: d2dd0262208475919e1a362f675cfc0e7c10e905
 - name: github.com/naoina/toml
@@ -79,7 +94,7 @@ imports:
   subpackages:
   - difflib
 - name: github.com/Sirupsen/logrus
-  version: f3cfb454f4c209e6668c95216c4744b8fddb2356
+  version: d26492970760ca5d33129d2d799e34be5c4782eb
 - name: github.com/spf13/cast
   version: 27b586b42e29bec072fe7379259cc719e1289da6
 - name: github.com/spf13/cobra
@@ -87,117 +102,133 @@ imports:
 - name: github.com/spf13/jwalterweatherman
   version: 33c24e77fb80341fe7130ee7c594256ff08ccc46
 - name: github.com/spf13/pflag
-  version: 367864438f1b1a3c7db4da06a2f55b144e6784e0
+  version: 25f8b5b07aece3207895bf19f7ab517eb3b22a40
 - name: github.com/spf13/viper
   version: c1ccc378a054ea8d4e38d8c67f6938d4760b53dd
+- name: github.com/streadway/simpleuuid
+  version: 6617b501e485b77e61b98cd533aefff9e258b5a7
 - name: github.com/stretchr/testify
   version: d77da356e56a7428ad25149ca77381849a6a5232
   subpackages:
   - assert
 - name: github.com/syndtr/goleveldb
-  version: fa5b5c78794bc5c18f330361059f871ae8c2b9d6
+  version: 23851d93a2292dcc56e71a18ec9e0624d84a0f65
   subpackages:
   - leveldb
-  - leveldb/errors
-  - leveldb/opt
   - leveldb/cache
   - leveldb/comparer
+  - leveldb/errors
   - leveldb/filter
   - leveldb/iterator
   - leveldb/journal
   - leveldb/memdb
+  - leveldb/opt
   - leveldb/storage
   - leveldb/table
   - leveldb/util
+- name: github.com/tendermint/abci
+  version: 699d45bc678865b004b90213bf88a950f420973b
+  subpackages:
+  - client
+  - example/counter
+  - example/dummy
+  - example/nil
+  - server
+  - types
 - name: github.com/tendermint/ed25519
-  version: fdac6641497281ed1cc368687ec6377e96e02b24
+  version: 1f52c6f8b8a5c7908aff4497c186af344b428925
   subpackages:
   - edwards25519
   - extra25519
 - name: github.com/tendermint/flowcontrol
   version: 84d9671090430e8ec80e35b339907e0579b999eb
+- name: github.com/tendermint/go-autofile
+  version: 0416e0aa9c68205aa44844096f9f151ada9d0405
 - name: github.com/tendermint/go-clist
-  version: 634527f5b60fd7c71ca811262493df2ad65ee0ca
+  version: 3baa390bbaf7634251c42ad69a8682e7e3990552
 - name: github.com/tendermint/go-common
-  version: dcfa46af1341d03b80d32e4901019d1668b978b9
+  version: e289af53b6bf6af28da129d9ef64389a4cf7987f
+  subpackages:
+  - test
 - name: github.com/tendermint/go-config
-  version: cfcef384d64b94e50909596e39b32ffb3cc20573
+  version: e64b424499acd0eb9856b88e10c0dff41628c0d6
 - name: github.com/tendermint/go-crypto
-  version: 41cfb7b677f4e16cdfd22b6ce0946c89919fbc7b
+  version: 4b11d62bdb324027ea01554e5767b71174680ba0
 - name: github.com/tendermint/go-db
-  version: 31fdd21c7eaeed53e0ea7ca597fb1e960e2988a5
+  version: 72f6dacd22a686cdf7fcd60286503e3aceda77ba
 - name: github.com/tendermint/go-events
-  version: 7b75ca7bb55aa25e9ef765eb8c0b69486b227357
+  version: fddee66d90305fccb6f6d84d16c34fa65ea5b7f6
+- name: github.com/tendermint/go-flowrate
+  version: a20c98e61957faa93b4014fbd902f20ab9317a6a
+  subpackages:
+  - flowrate
 - name: github.com/tendermint/go-logger
-  version: 529efe50eab1a8a9c111d55f4de4ecd95f482761
+  version: cefb3a45c0bf3c493a04e9bcd9b1540528be59f2
 - name: github.com/tendermint/go-merkle
-  version: 05042c6ab9cad51d12e4cecf717ae68e3b1409a8
+  version: 7a86b4486f2cd84ac885c5bbc609fdee2905f5d1
 - name: github.com/tendermint/go-p2p
-  version: 5bd7692323ec60d6461678f09b5024a952164151
+  version: 3d98f675f30dc4796546b8b890f895926152fa8d
   subpackages:
   - upnp
 - name: github.com/tendermint/go-rpc
-  version: 479510be0e80dd9e5d6b1f941adad168df0af85f
+  version: fcea0cda21f64889be00a0f4b6d13266b1a76ee7
   subpackages:
   - client
   - server
   - types
 - name: github.com/tendermint/go-wire
-  version: 3b0adbc86ed8425eaed98516165b6788d9f4de7a
+  version: 2f3b7aafe21c80b19b6ee3210ecb3e3d07c7a471
 - name: github.com/tendermint/log15
-  version: 9545b249b3aacafa97f79e0838b02b274adc6f5f
+  version: ae0f3d6450da9eac7074b439c8e1c3cabf0d5ce6
   subpackages:
   - term
 - name: github.com/tendermint/tendermint
-  version: aaea0c5d2e3ecfbf29f2608f9d43649ec7f07f50
+  version: 764091dfbb035f1b28da4b067526e04c6a849966
   subpackages:
-  - node
-  - proxy
-  - types
-  - version
-  - consensus
-  - rpc/core/types
   - blockchain
+  - consensus
   - mempool
+  - node
+  - proxy
   - rpc/core
+  - rpc/core/types
   - state
-- name: github.com/tendermint/tmsp
-  version: 73e5c3cb7bbee2f9c49792e5a0fcbcab442bf7dc
-  subpackages:
-  - client
   - types
-  - example/dummy
-  - example/nil
+  - version
 - name: github.com/tommy351/gin-cors
   version: dc91dec6313ae4db53481bf3b29cf6b94bf80357
 - name: golang.org/x/crypto
-  version: f3241ce8505855877cc8a9717bd61a0f7c4ea83c
+  version: 7c6cc321c680f03b9ef0764448e780704f486b51
   subpackages:
-  - ripemd160
+  - curve25519
+  - nacl/box
   - nacl/secretbox
   - openpgp/armor
-  - nacl/box
+  - openpgp/errors
   - poly1305
+  - ripemd160
   - salsa20/salsa
-  - openpgp/errors
-  - curve25519
 - name: golang.org/x/net
-  version: de35ec43e7a9aabd6a9c54d2898220ea7e44de7d
+  version: 60c41d1de8da134c05b7b40154a9a82bf5b7edb9
   subpackages:
-  - http2
   - context
-  - netutil
-  - trace
+  - http2
   - http2/hpack
   - idna
-  - lex/httplex
   - internal/timeseries
 - name: golang.org/x/sys
-  version: 62bee037599929a6e9146f29d10dd5208c43507d
+  version: d75a52659825e75fff6158388dddc6a5b04f9ba5
   subpackages:
   - unix
+- name: golang.org/x/text
+  version: 44f4f658a783b0cee41fe0a23b8fc91d9c120558
+  subpackages:
+  - secure/bidirule
+  - transform
+  - unicode/bidi
+  - unicode/norm
 - name: google.golang.org/grpc
-  version: e78224b060cf3215247b7be455f80ea22e469b66
+  version: 50955793b0183f9de69bd78e2ec251cf20aab121
   subpackages:
   - codes
   - credentials
@@ -205,8 +236,10 @@ imports:
   - internal
   - metadata
   - naming
-  - transport
   - peer
+  - stats
+  - tap
+  - transport
 - name: gopkg.in/fatih/set.v0
   version: 27c40922c40b43fe04554d8223a402af3ea333f3
 - name: gopkg.in/go-playground/validator.v8
@@ -215,4 +248,4 @@ imports:
   version: ecde8c8f16df93a994dda8936c8f60f0c26c28ab
 - name: gopkg.in/yaml.v2
   version: a83829b6f1293c91addabc89d0571c246397bbf4
-devImports: []
+testImports: []
diff --git a/glide.yaml b/glide.yaml
index ca8e52b5c438cf55e2cb5a85ca74617f8d53c485..ed8e097c2828278365c0e7d158acd11a5a9fb6f5 100644
--- a/glide.yaml
+++ b/glide.yaml
@@ -1,19 +1,34 @@
 package: github.com/eris-ltd/eris-db
 import:
-- package: github.com/eris-ltd/eris-logger
 - package: github.com/eris-ltd/eris-keys
 - package: github.com/spf13/cobra
 - package: github.com/spf13/viper
-- package: github.com/tendermint/tendermint
 - package: github.com/gin-gonic/gin
 - package: github.com/gorilla/websocket
 - package: github.com/naoina/toml
 - package: github.com/stretchr/testify
+- package: github.com/tendermint/tendermint
+  version: ~0.8.0
 - package: github.com/tommy351/gin-cors
 - package: golang.org/x/crypto
   subpackages:
   - ripemd160
 - package: gopkg.in/fatih/set.v0
 - package: gopkg.in/tylerb/graceful.v1
-- package: golang.org/x/net/http2
-- package: github.com/eris-ltd/common
+- package: golang.org/x/net
+  subpackages:
+  - http2
+- package: github.com/go-kit/kit
+  version: ^0.3.0
+- package: github.com/eapache/channels
+  version: ~1.1.0
+- package: github.com/go-logfmt/logfmt
+  version: ^0.3.0
+- package: github.com/go-stack/stack
+  version: ^1.5.2
+- package: github.com/inconshreveable/log15
+- package: github.com/Sirupsen/logrus
+  version: ^0.11.0
+- package: github.com/streadway/simpleuuid
+- package: github.com/Masterminds/glide
+  version: ~0.12.3
diff --git a/keys/key_client.go b/keys/key_client.go
index e841f50abd71f68ce4bdd9fc838acf764e5f3b1f..edbc451123db1c069033cbce1cad4a1d0b2135b1 100644
--- a/keys/key_client.go
+++ b/keys/key_client.go
@@ -1,24 +1,25 @@
-// Copyright 2015, 2016 Eris Industries (UK) Ltd.
-// This file is part of Eris-RT
-
-// Eris-RT is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-
-// Eris-RT is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License
-// along with Eris-RT.  If not, see <http://www.gnu.org/licenses/>.
+// 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 keys
 
 import (
 	"encoding/hex"
 	"fmt"
+
+	"github.com/eris-ltd/eris-db/logging"
+	"github.com/eris-ltd/eris-db/logging/loggers"
 )
 
 type KeyClient interface {
@@ -29,31 +30,33 @@ type KeyClient interface {
 	PublicKey(address []byte) (publicKey []byte, err error)
 }
 
-// NOTE [ben] Compiler check to ensure ErisKeyClient successfully implements
+// NOTE [ben] Compiler check to ensure erisKeyClient successfully implements
 // eris-db/keys.KeyClient
-var _ KeyClient = (*ErisKeyClient)(nil)
+var _ KeyClient = (*erisKeyClient)(nil)
 
-type ErisKeyClient struct {
+type erisKeyClient struct {
 	rpcString string
+	logger    loggers.InfoTraceLogger
 }
 
-// ErisKeyClient.New returns a new eris-keys client for provided rpc location
+// erisKeyClient.New returns a new eris-keys client for provided rpc location
 // Eris-keys connects over http request-responses
-func NewErisKeyClient(rpcString string) *ErisKeyClient {
-	return &ErisKeyClient{
+func NewErisKeyClient(rpcString string, logger loggers.InfoTraceLogger) *erisKeyClient {
+	return &erisKeyClient{
 		rpcString: rpcString,
+		logger:    logging.WithScope(logger, "ErisKeysClient"),
 	}
 }
 
 // Eris-keys client Sign requests the signature from ErisKeysClient over rpc for the given
 // bytes to be signed and the address to sign them with.
-func (erisKeys *ErisKeyClient) Sign(signBytesString string, signAddress []byte) (signature []byte, err error) {
+func (erisKeys *erisKeyClient) Sign(signBytesString string, signAddress []byte) (signature []byte, err error) {
 	args := map[string]string{
 		"msg":  signBytesString,
 		"hash": signBytesString, // TODO:[ben] backwards compatibility
 		"addr": fmt.Sprintf("%X", signAddress),
 	}
-	sigS, err := RequestResponse(erisKeys.rpcString, "sign", args)
+	sigS, err := RequestResponse(erisKeys.rpcString, "sign", args, erisKeys.logger)
 	if err != nil {
 		return
 	}
@@ -66,11 +69,11 @@ func (erisKeys *ErisKeyClient) Sign(signBytesString string, signAddress []byte)
 
 // Eris-keys client PublicKey requests the public key associated with an address from
 // the eris-keys server.
-func (erisKeys *ErisKeyClient) PublicKey(address []byte) (publicKey []byte, err error) {
+func (erisKeys *erisKeyClient) PublicKey(address []byte) (publicKey []byte, err error) {
 	args := map[string]string{
 		"addr": fmt.Sprintf("%X", address),
 	}
-	pubS, err := RequestResponse(erisKeys.rpcString, "pub", args)
+	pubS, err := RequestResponse(erisKeys.rpcString, "pub", args, erisKeys.logger)
 	if err != nil {
 		return
 	}
diff --git a/keys/key_client_util.go b/keys/key_client_util.go
index e9e5f4783d51ce2df4e590cea008535ed5f1a4d7..b59c61f6b37a9a1ffa2b21f6b7982eecd7f3fb12 100644
--- a/keys/key_client_util.go
+++ b/keys/key_client_util.go
@@ -1,21 +1,16 @@
-// Copyright 2015, 2016 Eris Industries (UK) Ltd.
-// This file is part of Eris-RT
-
-// Eris-RT is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-
-// Eris-RT is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License
-// along with Eris-RT.  If not, see <http://www.gnu.org/licenses/>.
-
-// version provides the current Eris-DB version and a VersionIdentifier
-// for the modules to identify their version with.
+// 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 keys
 
@@ -26,7 +21,8 @@ import (
 	"io/ioutil"
 	"net/http"
 
-	log "github.com/eris-ltd/eris-logger"
+	"github.com/eris-ltd/eris-db/logging"
+	"github.com/eris-ltd/eris-db/logging/loggers"
 )
 
 // Eris-Keys server connects over http request-response structures
@@ -36,17 +32,17 @@ type HTTPResponse struct {
 	Error    string
 }
 
-func RequestResponse(addr, method string, args map[string]string) (string, error) {
-	b, err := json.Marshal(args)
+func RequestResponse(addr, method string, args map[string]string, logger loggers.InfoTraceLogger) (string, error) {
+	body, err := json.Marshal(args)
 	if err != nil {
 		return "", err
 	}
 	endpoint := fmt.Sprintf("%s/%s", addr, method)
-	log.WithFields(log.Fields{
-		"key server endpoint": endpoint,
-		"request body":        string(b),
-	}).Debugf("Eris-client: Sending request body to key server")
-	req, err := http.NewRequest("POST", endpoint, bytes.NewBuffer(b))
+	logging.TraceMsg(logger, "Sending request to key server",
+		"key_server_endpoint", endpoint,
+		"request_body", string(body),
+	)
+	req, err := http.NewRequest("POST", endpoint, bytes.NewBuffer(body))
 	if err != nil {
 		return "", err
 	}
@@ -58,11 +54,11 @@ func RequestResponse(addr, method string, args map[string]string) (string, error
 	if errS != "" {
 		return "", fmt.Errorf("Error (string) calling eris-keys at %s: %s", endpoint, errS)
 	}
-	log.WithFields(log.Fields{
-		"endpoint":     endpoint,
-		"request body": string(b),
-		"response":     res,
-	}).Debugf("Received response from key server")
+	logging.TraceMsg(logger, "Received response from key server",
+		"endpoint", endpoint,
+		"request body", string(body),
+		"response", res,
+	)
 	return res, nil
 }
 
diff --git a/keys/mock/key_client_mock.go b/keys/mock/key_client_mock.go
index ef9cca8612a535011da62185af3e0a72fa8a5170..d1ae1bd0917124025d79d6f1c5f7b0d109d9d669 100644
--- a/keys/mock/key_client_mock.go
+++ b/keys/mock/key_client_mock.go
@@ -1,18 +1,16 @@
-// Copyright 2015, 2016 Eris Industries (UK) Ltd.
-// This file is part of Eris-RT
-
-// Eris-RT is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-
-// Eris-RT is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License
-// along with Eris-RT.  If not, see <http://www.gnu.org/licenses/>.
+// 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
 
diff --git a/license.md b/license.md
index 9cecc1d4669ee8af2ca727a5d8cde10cd8b2d7cc..d9a10c0d8e868ebf8da0b3dc95bb0be634c34bfe 100644
--- a/license.md
+++ b/license.md
@@ -1,674 +1,176 @@
-                    GNU GENERAL PUBLIC LICENSE
-                       Version 3, 29 June 2007
-
- Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
-                            Preamble
-
-  The GNU General Public License is a free, copyleft license for
-software and other kinds of works.
-
-  The licenses for most software and other practical works are designed
-to take away your freedom to share and change the works.  By contrast,
-the GNU General Public License is intended to guarantee your freedom to
-share and change all versions of a program--to make sure it remains free
-software for all its users.  We, the Free Software Foundation, use the
-GNU General Public License for most of our software; it applies also to
-any other work released this way by its authors.  You can apply it to
-your programs, too.
-
-  When we speak of free software, we are referring to freedom, not
-price.  Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-them if you wish), that you receive source code or can get it if you
-want it, that you can change the software or use pieces of it in new
-free programs, and that you know you can do these things.
-
-  To protect your rights, we need to prevent others from denying you
-these rights or asking you to surrender the rights.  Therefore, you have
-certain responsibilities if you distribute copies of the software, or if
-you modify it: responsibilities to respect the freedom of others.
-
-  For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must pass on to the recipients the same
-freedoms that you received.  You must make sure that they, too, receive
-or can get the source code.  And you must show them these terms so they
-know their rights.
-
-  Developers that use the GNU GPL protect your rights with two steps:
-(1) assert copyright on the software, and (2) offer you this License
-giving you legal permission to copy, distribute and/or modify it.
-
-  For the developers' and authors' protection, the GPL clearly explains
-that there is no warranty for this free software.  For both users' and
-authors' sake, the GPL requires that modified versions be marked as
-changed, so that their problems will not be attributed erroneously to
-authors of previous versions.
-
-  Some devices are designed to deny users access to install or run
-modified versions of the software inside them, although the manufacturer
-can do so.  This is fundamentally incompatible with the aim of
-protecting users' freedom to change the software.  The systematic
-pattern of such abuse occurs in the area of products for individuals to
-use, which is precisely where it is most unacceptable.  Therefore, we
-have designed this version of the GPL to prohibit the practice for those
-products.  If such problems arise substantially in other domains, we
-stand ready to extend this provision to those domains in future versions
-of the GPL, as needed to protect the freedom of users.
-
-  Finally, every program is threatened constantly by software patents.
-States should not allow patents to restrict development and use of
-software on general-purpose computers, but in those that do, we wish to
-avoid the special danger that patents applied to a free program could
-make it effectively proprietary.  To prevent this, the GPL assures that
-patents cannot be used to render the program non-free.
-
-  The precise terms and conditions for copying, distribution and
-modification follow.
-
-                       TERMS AND CONDITIONS
-
-  0. Definitions.
-
-  "This License" refers to version 3 of the GNU General Public License.
-
-  "Copyright" also means copyright-like laws that apply to other kinds of
-works, such as semiconductor masks.
-
-  "The Program" refers to any copyrightable work licensed under this
-License.  Each licensee is addressed as "you".  "Licensees" and
-"recipients" may be individuals or organizations.
-
-  To "modify" a work means to copy from or adapt all or part of the work
-in a fashion requiring copyright permission, other than the making of an
-exact copy.  The resulting work is called a "modified version" of the
-earlier work or a work "based on" the earlier work.
-
-  A "covered work" means either the unmodified Program or a work based
-on the Program.
-
-  To "propagate" a work means to do anything with it that, without
-permission, would make you directly or secondarily liable for
-infringement under applicable copyright law, except executing it on a
-computer or modifying a private copy.  Propagation includes copying,
-distribution (with or without modification), making available to the
-public, and in some countries other activities as well.
-
-  To "convey" a work means any kind of propagation that enables other
-parties to make or receive copies.  Mere interaction with a user through
-a computer network, with no transfer of a copy, is not conveying.
-
-  An interactive user interface displays "Appropriate Legal Notices"
-to the extent that it includes a convenient and prominently visible
-feature that (1) displays an appropriate copyright notice, and (2)
-tells the user that there is no warranty for the work (except to the
-extent that warranties are provided), that licensees may convey the
-work under this License, and how to view a copy of this License.  If
-the interface presents a list of user commands or options, such as a
-menu, a prominent item in the list meets this criterion.
-
-  1. Source Code.
-
-  The "source code" for a work means the preferred form of the work
-for making modifications to it.  "Object code" means any non-source
-form of a work.
-
-  A "Standard Interface" means an interface that either is an official
-standard defined by a recognized standards body, or, in the case of
-interfaces specified for a particular programming language, one that
-is widely used among developers working in that language.
-
-  The "System Libraries" of an executable work include anything, other
-than the work as a whole, that (a) is included in the normal form of
-packaging a Major Component, but which is not part of that Major
-Component, and (b) serves only to enable use of the work with that
-Major Component, or to implement a Standard Interface for which an
-implementation is available to the public in source code form.  A
-"Major Component", in this context, means a major essential component
-(kernel, window system, and so on) of the specific operating system
-(if any) on which the executable work runs, or a compiler used to
-produce the work, or an object code interpreter used to run it.
-
-  The "Corresponding Source" for a work in object code form means all
-the source code needed to generate, install, and (for an executable
-work) run the object code and to modify the work, including scripts to
-control those activities.  However, it does not include the work's
-System Libraries, or general-purpose tools or generally available free
-programs which are used unmodified in performing those activities but
-which are not part of the work.  For example, Corresponding Source
-includes interface definition files associated with source files for
-the work, and the source code for shared libraries and dynamically
-linked subprograms that the work is specifically designed to require,
-such as by intimate data communication or control flow between those
-subprograms and other parts of the work.
-
-  The Corresponding Source need not include anything that users
-can regenerate automatically from other parts of the Corresponding
-Source.
-
-  The Corresponding Source for a work in source code form is that
-same work.
-
-  2. Basic Permissions.
-
-  All rights granted under this License are granted for the term of
-copyright on the Program, and are irrevocable provided the stated
-conditions are met.  This License explicitly affirms your unlimited
-permission to run the unmodified Program.  The output from running a
-covered work is covered by this License only if the output, given its
-content, constitutes a covered work.  This License acknowledges your
-rights of fair use or other equivalent, as provided by copyright law.
-
-  You may make, run and propagate covered works that you do not
-convey, without conditions so long as your license otherwise remains
-in force.  You may convey covered works to others for the sole purpose
-of having them make modifications exclusively for you, or provide you
-with facilities for running those works, provided that you comply with
-the terms of this License in conveying all material for which you do
-not control copyright.  Those thus making or running the covered works
-for you must do so exclusively on your behalf, under your direction
-and control, on terms that prohibit them from making any copies of
-your copyrighted material outside their relationship with you.
-
-  Conveying under any other circumstances is permitted solely under
-the conditions stated below.  Sublicensing is not allowed; section 10
-makes it unnecessary.
-
-  3. Protecting Users' Legal Rights From Anti-Circumvention Law.
-
-  No covered work shall be deemed part of an effective technological
-measure under any applicable law fulfilling obligations under article
-11 of the WIPO copyright treaty adopted on 20 December 1996, or
-similar laws prohibiting or restricting circumvention of such
-measures.
-
-  When you convey a covered work, you waive any legal power to forbid
-circumvention of technological measures to the extent such circumvention
-is effected by exercising rights under this License with respect to
-the covered work, and you disclaim any intention to limit operation or
-modification of the work as a means of enforcing, against the work's
-users, your or third parties' legal rights to forbid circumvention of
-technological measures.
-
-  4. Conveying Verbatim Copies.
-
-  You may convey verbatim copies of the Program's source code as you
-receive it, in any medium, provided that you conspicuously and
-appropriately publish on each copy an appropriate copyright notice;
-keep intact all notices stating that this License and any
-non-permissive terms added in accord with section 7 apply to the code;
-keep intact all notices of the absence of any warranty; and give all
-recipients a copy of this License along with the Program.
-
-  You may charge any price or no price for each copy that you convey,
-and you may offer support or warranty protection for a fee.
-
-  5. Conveying Modified Source Versions.
-
-  You may convey a work based on the Program, or the modifications to
-produce it from the Program, in the form of source code under the
-terms of section 4, provided that you also meet all of these conditions:
-
-    a) The work must carry prominent notices stating that you modified
-    it, and giving a relevant date.
-
-    b) The work must carry prominent notices stating that it is
-    released under this License and any conditions added under section
-    7.  This requirement modifies the requirement in section 4 to
-    "keep intact all notices".
-
-    c) You must license the entire work, as a whole, under this
-    License to anyone who comes into possession of a copy.  This
-    License will therefore apply, along with any applicable section 7
-    additional terms, to the whole of the work, and all its parts,
-    regardless of how they are packaged.  This License gives no
-    permission to license the work in any other way, but it does not
-    invalidate such permission if you have separately received it.
-
-    d) If the work has interactive user interfaces, each must display
-    Appropriate Legal Notices; however, if the Program has interactive
-    interfaces that do not display Appropriate Legal Notices, your
-    work need not make them do so.
-
-  A compilation of a covered work with other separate and independent
-works, which are not by their nature extensions of the covered work,
-and which are not combined with it such as to form a larger program,
-in or on a volume of a storage or distribution medium, is called an
-"aggregate" if the compilation and its resulting copyright are not
-used to limit the access or legal rights of the compilation's users
-beyond what the individual works permit.  Inclusion of a covered work
-in an aggregate does not cause this License to apply to the other
-parts of the aggregate.
-
-  6. Conveying Non-Source Forms.
-
-  You may convey a covered work in object code form under the terms
-of sections 4 and 5, provided that you also convey the
-machine-readable Corresponding Source under the terms of this License,
-in one of these ways:
-
-    a) Convey the object code in, or embodied in, a physical product
-    (including a physical distribution medium), accompanied by the
-    Corresponding Source fixed on a durable physical medium
-    customarily used for software interchange.
-
-    b) Convey the object code in, or embodied in, a physical product
-    (including a physical distribution medium), accompanied by a
-    written offer, valid for at least three years and valid for as
-    long as you offer spare parts or customer support for that product
-    model, to give anyone who possesses the object code either (1) a
-    copy of the Corresponding Source for all the software in the
-    product that is covered by this License, on a durable physical
-    medium customarily used for software interchange, for a price no
-    more than your reasonable cost of physically performing this
-    conveying of source, or (2) access to copy the
-    Corresponding Source from a network server at no charge.
-
-    c) Convey individual copies of the object code with a copy of the
-    written offer to provide the Corresponding Source.  This
-    alternative is allowed only occasionally and noncommercially, and
-    only if you received the object code with such an offer, in accord
-    with subsection 6b.
-
-    d) Convey the object code by offering access from a designated
-    place (gratis or for a charge), and offer equivalent access to the
-    Corresponding Source in the same way through the same place at no
-    further charge.  You need not require recipients to copy the
-    Corresponding Source along with the object code.  If the place to
-    copy the object code is a network server, the Corresponding Source
-    may be on a different server (operated by you or a third party)
-    that supports equivalent copying facilities, provided you maintain
-    clear directions next to the object code saying where to find the
-    Corresponding Source.  Regardless of what server hosts the
-    Corresponding Source, you remain obligated to ensure that it is
-    available for as long as needed to satisfy these requirements.
-
-    e) Convey the object code using peer-to-peer transmission, provided
-    you inform other peers where the object code and Corresponding
-    Source of the work are being offered to the general public at no
-    charge under subsection 6d.
-
-  A separable portion of the object code, whose source code is excluded
-from the Corresponding Source as a System Library, need not be
-included in conveying the object code work.
-
-  A "User Product" is either (1) a "consumer product", which means any
-tangible personal property which is normally used for personal, family,
-or household purposes, or (2) anything designed or sold for incorporation
-into a dwelling.  In determining whether a product is a consumer product,
-doubtful cases shall be resolved in favor of coverage.  For a particular
-product received by a particular user, "normally used" refers to a
-typical or common use of that class of product, regardless of the status
-of the particular user or of the way in which the particular user
-actually uses, or expects or is expected to use, the product.  A product
-is a consumer product regardless of whether the product has substantial
-commercial, industrial or non-consumer uses, unless such uses represent
-the only significant mode of use of the product.
-
-  "Installation Information" for a User Product means any methods,
-procedures, authorization keys, or other information required to install
-and execute modified versions of a covered work in that User Product from
-a modified version of its Corresponding Source.  The information must
-suffice to ensure that the continued functioning of the modified object
-code is in no case prevented or interfered with solely because
-modification has been made.
-
-  If you convey an object code work under this section in, or with, or
-specifically for use in, a User Product, and the conveying occurs as
-part of a transaction in which the right of possession and use of the
-User Product is transferred to the recipient in perpetuity or for a
-fixed term (regardless of how the transaction is characterized), the
-Corresponding Source conveyed under this section must be accompanied
-by the Installation Information.  But this requirement does not apply
-if neither you nor any third party retains the ability to install
-modified object code on the User Product (for example, the work has
-been installed in ROM).
-
-  The requirement to provide Installation Information does not include a
-requirement to continue to provide support service, warranty, or updates
-for a work that has been modified or installed by the recipient, or for
-the User Product in which it has been modified or installed.  Access to a
-network may be denied when the modification itself materially and
-adversely affects the operation of the network or violates the rules and
-protocols for communication across the network.
-
-  Corresponding Source conveyed, and Installation Information provided,
-in accord with this section must be in a format that is publicly
-documented (and with an implementation available to the public in
-source code form), and must require no special password or key for
-unpacking, reading or copying.
-
-  7. Additional Terms.
-
-  "Additional permissions" are terms that supplement the terms of this
-License by making exceptions from one or more of its conditions.
-Additional permissions that are applicable to the entire Program shall
-be treated as though they were included in this License, to the extent
-that they are valid under applicable law.  If additional permissions
-apply only to part of the Program, that part may be used separately
-under those permissions, but the entire Program remains governed by
-this License without regard to the additional permissions.
-
-  When you convey a copy of a covered work, you may at your option
-remove any additional permissions from that copy, or from any part of
-it.  (Additional permissions may be written to require their own
-removal in certain cases when you modify the work.)  You may place
-additional permissions on material, added by you to a covered work,
-for which you have or can give appropriate copyright permission.
-
-  Notwithstanding any other provision of this License, for material you
-add to a covered work, you may (if authorized by the copyright holders of
-that material) supplement the terms of this License with terms:
-
-    a) Disclaiming warranty or limiting liability differently from the
-    terms of sections 15 and 16 of this License; or
-
-    b) Requiring preservation of specified reasonable legal notices or
-    author attributions in that material or in the Appropriate Legal
-    Notices displayed by works containing it; or
-
-    c) Prohibiting misrepresentation of the origin of that material, or
-    requiring that modified versions of such material be marked in
-    reasonable ways as different from the original version; or
-
-    d) Limiting the use for publicity purposes of names of licensors or
-    authors of the material; or
-
-    e) Declining to grant rights under trademark law for use of some
-    trade names, trademarks, or service marks; or
-
-    f) Requiring indemnification of licensors and authors of that
-    material by anyone who conveys the material (or modified versions of
-    it) with contractual assumptions of liability to the recipient, for
-    any liability that these contractual assumptions directly impose on
-    those licensors and authors.
-
-  All other non-permissive additional terms are considered "further
-restrictions" within the meaning of section 10.  If the Program as you
-received it, or any part of it, contains a notice stating that it is
-governed by this License along with a term that is a further
-restriction, you may remove that term.  If a license document contains
-a further restriction but permits relicensing or conveying under this
-License, you may add to a covered work material governed by the terms
-of that license document, provided that the further restriction does
-not survive such relicensing or conveying.
-
-  If you add terms to a covered work in accord with this section, you
-must place, in the relevant source files, a statement of the
-additional terms that apply to those files, or a notice indicating
-where to find the applicable terms.
-
-  Additional terms, permissive or non-permissive, may be stated in the
-form of a separately written license, or stated as exceptions;
-the above requirements apply either way.
-
-  8. Termination.
-
-  You may not propagate or modify a covered work except as expressly
-provided under this License.  Any attempt otherwise to propagate or
-modify it is void, and will automatically terminate your rights under
-this License (including any patent licenses granted under the third
-paragraph of section 11).
-
-  However, if you cease all violation of this License, then your
-license from a particular copyright holder is reinstated (a)
-provisionally, unless and until the copyright holder explicitly and
-finally terminates your license, and (b) permanently, if the copyright
-holder fails to notify you of the violation by some reasonable means
-prior to 60 days after the cessation.
-
-  Moreover, your license from a particular copyright holder is
-reinstated permanently if the copyright holder notifies you of the
-violation by some reasonable means, this is the first time you have
-received notice of violation of this License (for any work) from that
-copyright holder, and you cure the violation prior to 30 days after
-your receipt of the notice.
-
-  Termination of your rights under this section does not terminate the
-licenses of parties who have received copies or rights from you under
-this License.  If your rights have been terminated and not permanently
-reinstated, you do not qualify to receive new licenses for the same
-material under section 10.
-
-  9. Acceptance Not Required for Having Copies.
-
-  You are not required to accept this License in order to receive or
-run a copy of the Program.  Ancillary propagation of a covered work
-occurring solely as a consequence of using peer-to-peer transmission
-to receive a copy likewise does not require acceptance.  However,
-nothing other than this License grants you permission to propagate or
-modify any covered work.  These actions infringe copyright if you do
-not accept this License.  Therefore, by modifying or propagating a
-covered work, you indicate your acceptance of this License to do so.
-
-  10. Automatic Licensing of Downstream Recipients.
-
-  Each time you convey a covered work, the recipient automatically
-receives a license from the original licensors, to run, modify and
-propagate that work, subject to this License.  You are not responsible
-for enforcing compliance by third parties with this License.
-
-  An "entity transaction" is a transaction transferring control of an
-organization, or substantially all assets of one, or subdividing an
-organization, or merging organizations.  If propagation of a covered
-work results from an entity transaction, each party to that
-transaction who receives a copy of the work also receives whatever
-licenses to the work the party's predecessor in interest had or could
-give under the previous paragraph, plus a right to possession of the
-Corresponding Source of the work from the predecessor in interest, if
-the predecessor has it or can get it with reasonable efforts.
-
-  You may not impose any further restrictions on the exercise of the
-rights granted or affirmed under this License.  For example, you may
-not impose a license fee, royalty, or other charge for exercise of
-rights granted under this License, and you may not initiate litigation
-(including a cross-claim or counterclaim in a lawsuit) alleging that
-any patent claim is infringed by making, using, selling, offering for
-sale, or importing the Program or any portion of it.
-
-  11. Patents.
-
-  A "contributor" is a copyright holder who authorizes use under this
-License of the Program or a work on which the Program is based.  The
-work thus licensed is called the contributor's "contributor version".
-
-  A contributor's "essential patent claims" are all patent claims
-owned or controlled by the contributor, whether already acquired or
-hereafter acquired, that would be infringed by some manner, permitted
-by this License, of making, using, or selling its contributor version,
-but do not include claims that would be infringed only as a
-consequence of further modification of the contributor version.  For
-purposes of this definition, "control" includes the right to grant
-patent sublicenses in a manner consistent with the requirements of
-this License.
-
-  Each contributor grants you a non-exclusive, worldwide, royalty-free
-patent license under the contributor's essential patent claims, to
-make, use, sell, offer for sale, import and otherwise run, modify and
-propagate the contents of its contributor version.
-
-  In the following three paragraphs, a "patent license" is any express
-agreement or commitment, however denominated, not to enforce a patent
-(such as an express permission to practice a patent or covenant not to
-sue for patent infringement).  To "grant" such a patent license to a
-party means to make such an agreement or commitment not to enforce a
-patent against the party.
-
-  If you convey a covered work, knowingly relying on a patent license,
-and the Corresponding Source of the work is not available for anyone
-to copy, free of charge and under the terms of this License, through a
-publicly available network server or other readily accessible means,
-then you must either (1) cause the Corresponding Source to be so
-available, or (2) arrange to deprive yourself of the benefit of the
-patent license for this particular work, or (3) arrange, in a manner
-consistent with the requirements of this License, to extend the patent
-license to downstream recipients.  "Knowingly relying" means you have
-actual knowledge that, but for the patent license, your conveying the
-covered work in a country, or your recipient's use of the covered work
-in a country, would infringe one or more identifiable patents in that
-country that you have reason to believe are valid.
-
-  If, pursuant to or in connection with a single transaction or
-arrangement, you convey, or propagate by procuring conveyance of, a
-covered work, and grant a patent license to some of the parties
-receiving the covered work authorizing them to use, propagate, modify
-or convey a specific copy of the covered work, then the patent license
-you grant is automatically extended to all recipients of the covered
-work and works based on it.
-
-  A patent license is "discriminatory" if it does not include within
-the scope of its coverage, prohibits the exercise of, or is
-conditioned on the non-exercise of one or more of the rights that are
-specifically granted under this License.  You may not convey a covered
-work if you are a party to an arrangement with a third party that is
-in the business of distributing software, under which you make payment
-to the third party based on the extent of your activity of conveying
-the work, and under which the third party grants, to any of the
-parties who would receive the covered work from you, a discriminatory
-patent license (a) in connection with copies of the covered work
-conveyed by you (or copies made from those copies), or (b) primarily
-for and in connection with specific products or compilations that
-contain the covered work, unless you entered into that arrangement,
-or that patent license was granted, prior to 28 March 2007.
-
-  Nothing in this License shall be construed as excluding or limiting
-any implied license or other defenses to infringement that may
-otherwise be available to you under applicable patent law.
-
-  12. No Surrender of Others' Freedom.
-
-  If conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License.  If you cannot convey a
-covered work so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you may
-not convey it at all.  For example, if you agree to terms that obligate you
-to collect a royalty for further conveying from those to whom you convey
-the Program, the only way you could satisfy both those terms and this
-License would be to refrain entirely from conveying the Program.
-
-  13. Use with the GNU Affero General Public License.
-
-  Notwithstanding any other provision of this License, you have
-permission to link or combine any covered work with a work licensed
-under version 3 of the GNU Affero General Public License into a single
-combined work, and to convey the resulting work.  The terms of this
-License will continue to apply to the part which is the covered work,
-but the special requirements of the GNU Affero General Public License,
-section 13, concerning interaction through a network will apply to the
-combination as such.
-
-  14. Revised Versions of this License.
-
-  The Free Software Foundation may publish revised and/or new versions of
-the GNU General Public License from time to time.  Such new versions will
-be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
-  Each version is given a distinguishing version number.  If the
-Program specifies that a certain numbered version of the GNU General
-Public License "or any later version" applies to it, you have the
-option of following the terms and conditions either of that numbered
-version or of any later version published by the Free Software
-Foundation.  If the Program does not specify a version number of the
-GNU General Public License, you may choose any version ever published
-by the Free Software Foundation.
-
-  If the Program specifies that a proxy can decide which future
-versions of the GNU General Public License can be used, that proxy's
-public statement of acceptance of a version permanently authorizes you
-to choose that version for the Program.
-
-  Later license versions may give you additional or different
-permissions.  However, no additional obligations are imposed on any
-author or copyright holder as a result of your choosing to follow a
-later version.
-
-  15. Disclaimer of Warranty.
-
-  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
-APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
-HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
-OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
-THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
-IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
-ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
-
-  16. Limitation of Liability.
-
-  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
-THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
-GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
-USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
-DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
-PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
-EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGES.
-
-  17. Interpretation of Sections 15 and 16.
-
-  If the disclaimer of warranty and limitation of liability provided
-above cannot be given local legal effect according to their terms,
-reviewing courts shall apply local law that most closely approximates
-an absolute waiver of all civil liability in connection with the
-Program, unless a warranty or assumption of liability accompanies a
-copy of the Program in return for a fee.
-
-                     END OF TERMS AND CONDITIONS
-
-            How to Apply These Terms to Your New Programs
-
-  If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
-  To do so, attach the following notices to the program.  It is safest
-to attach them to the start of each source file to most effectively
-state the exclusion of warranty; and each file should have at least
-the "copyright" line and a pointer to where the full notice is found.
-
-    {one line to give the program's name and a brief idea of what it does.}
-    Copyright (C) {year}  {name of author}
-
-    This program is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-Also add information on how to contact you by electronic and paper mail.
-
-  If the program does terminal interaction, make it output a short
-notice like this when it starts in an interactive mode:
-
-    {project}  Copyright (C) {year}  {fullname}
-    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
-    This is free software, and you are welcome to redistribute it
-    under certain conditions; type `show c' for details.
-
-The hypothetical commands `show w' and `show c' should show the appropriate
-parts of the General Public License.  Of course, your program's commands
-might be different; for a GUI interface, you would use an "about box".
-
-  You should also get your employer (if you work as a programmer) or school,
-if any, to sign a "copyright disclaimer" for the program, if necessary.
-For more information on this, and how to apply and follow the GNU GPL, see
-<http://www.gnu.org/licenses/>.
-
-  The GNU General Public License does not permit incorporating your program
-into proprietary programs.  If your program is a subroutine library, you
-may consider it more useful to permit linking proprietary applications with
-the library.  If this is what you want to do, use the GNU Lesser General
-Public License instead of this License.  But first, please read
-<http://www.gnu.org/philosophy/why-not-lgpl.html>.
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
diff --git a/logging/adapters/logrus/logrus.go b/logging/adapters/logrus/logrus.go
new file mode 100644
index 0000000000000000000000000000000000000000..84b6837188e6c6712ef05461227b658372ccd0bb
--- /dev/null
+++ b/logging/adapters/logrus/logrus.go
@@ -0,0 +1,36 @@
+// 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 adapters
+
+import (
+	"github.com/Sirupsen/logrus"
+	kitlog "github.com/go-kit/kit/log"
+)
+
+type logrusLogger struct {
+	logger logrus.Logger
+}
+
+var _ kitlog.Logger = (*logrusLogger)(nil)
+
+func NewLogrusLogger(logger logrus.Logger) *logrusLogger {
+	return &logrusLogger{
+		logger: logger,
+	}
+}
+
+func (ll *logrusLogger) Log(keyvals ...interface{}) error {
+	return nil
+}
diff --git a/logging/adapters/stdlib/capture.go b/logging/adapters/stdlib/capture.go
new file mode 100644
index 0000000000000000000000000000000000000000..3c8a2a88e14b4199b548c6cea441c67d3d1a90e5
--- /dev/null
+++ b/logging/adapters/stdlib/capture.go
@@ -0,0 +1,40 @@
+// 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 stdlib
+
+import (
+	"io"
+	"log"
+
+	"github.com/eris-ltd/eris-db/logging/loggers"
+	kitlog "github.com/go-kit/kit/log"
+)
+
+func Capture(stdLibLogger log.Logger,
+	logger loggers.InfoTraceLogger) io.Writer {
+	adapter := newAdapter(logger)
+	stdLibLogger.SetOutput(adapter)
+	return adapter
+}
+
+func CaptureRootLogger(logger loggers.InfoTraceLogger) io.Writer {
+	adapter := newAdapter(logger)
+	log.SetOutput(adapter)
+	return adapter
+}
+
+func newAdapter(logger loggers.InfoTraceLogger) io.Writer {
+	return kitlog.NewStdlibAdapter(logger)
+}
diff --git a/logging/adapters/tendermint_log15/capture.go b/logging/adapters/tendermint_log15/capture.go
new file mode 100644
index 0000000000000000000000000000000000000000..64f5a139da1860ffc929c7e49c617be51099649b
--- /dev/null
+++ b/logging/adapters/tendermint_log15/capture.go
@@ -0,0 +1,61 @@
+// 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 adapters
+
+import (
+	"github.com/eris-ltd/eris-db/logging/loggers"
+	kitlog "github.com/go-kit/kit/log"
+	"github.com/tendermint/log15"
+)
+
+type infoTraceLoggerAsLog15Handler struct {
+	logger loggers.InfoTraceLogger
+}
+
+var _ log15.Handler = (*infoTraceLoggerAsLog15Handler)(nil)
+
+type log15HandlerAsKitLogger struct {
+	handler log15.Handler
+}
+
+var _ kitlog.Logger = (*log15HandlerAsKitLogger)(nil)
+
+func (l *log15HandlerAsKitLogger) Log(keyvals ...interface{}) error {
+	record := LogLineToRecord(keyvals...)
+	return l.handler.Log(record)
+}
+
+func (h *infoTraceLoggerAsLog15Handler) Log(record *log15.Record) error {
+	if record.Lvl < log15.LvlDebug {
+		// Send to Critical, Warning, Error, and Info to the Info channel
+		h.logger.Info(RecordToLogLine(record)...)
+	} else {
+		// Send to Debug to the Trace channel
+		h.logger.Trace(RecordToLogLine(record)...)
+	}
+	return nil
+}
+
+func Log15HandlerAsKitLogger(handler log15.Handler) kitlog.Logger {
+	return &log15HandlerAsKitLogger{
+		handler: handler,
+	}
+}
+
+func InfoTraceLoggerAsLog15Handler(logger loggers.InfoTraceLogger) log15.Handler {
+	return &infoTraceLoggerAsLog15Handler{
+		logger: logger,
+	}
+}
diff --git a/logging/adapters/tendermint_log15/convert.go b/logging/adapters/tendermint_log15/convert.go
new file mode 100644
index 0000000000000000000000000000000000000000..f1668b262ab0dac75948274da43c97c52d12b0e3
--- /dev/null
+++ b/logging/adapters/tendermint_log15/convert.go
@@ -0,0 +1,84 @@
+// 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 adapters
+
+import (
+	"time"
+
+	"github.com/eris-ltd/eris-db/logging/loggers"
+	"github.com/eris-ltd/eris-db/logging/structure"
+	. "github.com/eris-ltd/eris-db/util/slice"
+	"github.com/go-stack/stack"
+	"github.com/tendermint/log15"
+)
+
+// Convert a go-kit log line (i.e. keyvals... interface{}) into a log15 record
+// This allows us to use log15 output handlers
+func LogLineToRecord(keyvals ...interface{}) *log15.Record {
+	vals, ctx := structure.ValuesAndContext(keyvals, structure.TimeKey,
+		structure.MessageKey, structure.CallerKey, structure.LevelKey)
+
+	// Mapping of log line to Record is on a best effort basis
+	theTime, _ := vals[structure.TimeKey].(time.Time)
+	call, _ := vals[structure.CallerKey].(stack.Call)
+	level, _ := vals[structure.LevelKey].(string)
+	message, _ := vals[structure.MessageKey].(string)
+
+	return &log15.Record{
+		Time: theTime,
+		Lvl:  Log15LvlFromString(level),
+		Msg:  message,
+		Call: call,
+		Ctx:  ctx,
+		KeyNames: log15.RecordKeyNames{
+			Time: structure.TimeKey,
+			Msg:  structure.MessageKey,
+			Lvl:  structure.LevelKey,
+		}}
+}
+
+// Convert a log15 record to a go-kit log line (i.e. keyvals... interface{})
+// This allows us to capture output from dependencies using log15
+func RecordToLogLine(record *log15.Record) []interface{} {
+	return Concat(
+		Slice(
+			structure.TimeKey, record.Time,
+			structure.CallerKey, record.Call,
+			structure.LevelKey, record.Lvl.String(),
+		),
+		record.Ctx,
+		Slice(
+			structure.MessageKey, record.Msg,
+		))
+}
+
+// Collapse our weak notion of leveling and log15's into a log15.Lvl
+func Log15LvlFromString(level string) log15.Lvl {
+	if level == "" {
+		return log15.LvlDebug
+	}
+	switch level {
+	case loggers.InfoLevelName:
+		return log15.LvlInfo
+	case loggers.TraceLevelName:
+		return log15.LvlDebug
+	default:
+		lvl, err := log15.LvlFromString(level)
+		if err == nil {
+			return lvl
+		}
+		return log15.LvlDebug
+	}
+}
diff --git a/logging/config.go b/logging/config.go
new file mode 100644
index 0000000000000000000000000000000000000000..5123b93695f9ee60ecb38e50ef58ad040fd6780c
--- /dev/null
+++ b/logging/config.go
@@ -0,0 +1,25 @@
+// 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 logging
+
+type (
+	SinkConfig struct {
+		Channels []string
+	}
+
+	LoggingConfig struct {
+		Sinks []SinkConfig
+	}
+)
diff --git a/logging/convention.go b/logging/convention.go
new file mode 100644
index 0000000000000000000000000000000000000000..8dc5b05da97bc2b9bf267ed55e281a47989f32f6
--- /dev/null
+++ b/logging/convention.go
@@ -0,0 +1,72 @@
+// 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 logging
+
+import (
+	"github.com/eris-ltd/eris-db/logging/loggers"
+	"github.com/eris-ltd/eris-db/logging/structure"
+	"github.com/eris-ltd/eris-db/util/slice"
+	kitlog "github.com/go-kit/kit/log"
+)
+
+// Helper functions for InfoTraceLoggers, sort of extension methods to loggers
+// to centralise and establish logging conventions on top of in with the base
+// logging interface
+
+// Record structured Info log line with a message and conventional keys
+func InfoMsgVals(logger loggers.InfoTraceLogger, message string, vals ...interface{}) {
+	MsgVals(kitlog.LoggerFunc(logger.Info), message, vals...)
+}
+
+// Record structured Trace log line with a message and conventional keys
+func TraceMsgVals(logger loggers.InfoTraceLogger, message string, vals ...interface{}) {
+	MsgVals(kitlog.LoggerFunc(logger.Trace), message, vals...)
+}
+
+// Record structured Info log line with a message
+func InfoMsg(logger loggers.InfoTraceLogger, message string, keyvals ...interface{}) {
+	Msg(kitlog.LoggerFunc(logger.Info), message, keyvals...)
+}
+
+// Record structured Trace log line with a message
+func TraceMsg(logger loggers.InfoTraceLogger, message string, keyvals ...interface{}) {
+	Msg(kitlog.LoggerFunc(logger.Trace), message, keyvals...)
+}
+
+// Establish or extend the scope of this logger by appending scopeName to the Scope vector.
+// Like With the logging scope is append only but can be used to provide parenthetical scopes by hanging on to the
+// parent scope and using once the scope has been exited. The scope mechanism does is agnostic to the type of scope
+// so can be used to identify certain segments of the call stack, a lexical scope, or any other nested scope.
+func WithScope(logger loggers.InfoTraceLogger, scopeName string) loggers.InfoTraceLogger {
+	// InfoTraceLogger will collapse successive (ScopeKey, scopeName) pairs into a vector in the order which they appear
+	return logger.With(structure.ScopeKey, scopeName)
+}
+
+// Record a structured log line with a message
+func Msg(logger kitlog.Logger, message string, keyvals ...interface{}) error {
+	prepended := slice.CopyPrepend(keyvals, structure.MessageKey, message)
+	return logger.Log(prepended...)
+}
+
+// Record a structured log line with a message and conventional keys
+func MsgVals(logger kitlog.Logger, message string, vals ...interface{}) error {
+	keyvals := make([]interface{}, len(vals)*2)
+	for i := 0; i < len(vals); i++ {
+		kv := i * 2
+		keyvals[kv] = structure.KeyFromValue(vals[i])
+		keyvals[kv+1] = vals[i]
+	}
+	return Msg(logger, message, keyvals)
+}
diff --git a/logging/lifecycle/lifecycle.go b/logging/lifecycle/lifecycle.go
new file mode 100644
index 0000000000000000000000000000000000000000..81f6a20df8e14b0265ba7017b7115a413cd54863
--- /dev/null
+++ b/logging/lifecycle/lifecycle.go
@@ -0,0 +1,72 @@
+// 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 lifecycle
+
+// No package in ./logging/... should depend on lifecycle
+import (
+	"os"
+
+	"time"
+
+	"github.com/eris-ltd/eris-db/logging"
+	"github.com/eris-ltd/eris-db/logging/adapters/stdlib"
+	tmLog15adapter "github.com/eris-ltd/eris-db/logging/adapters/tendermint_log15"
+	"github.com/eris-ltd/eris-db/logging/loggers"
+	"github.com/eris-ltd/eris-db/logging/structure"
+
+	kitlog "github.com/go-kit/kit/log"
+	"github.com/streadway/simpleuuid"
+	tmLog15 "github.com/tendermint/log15"
+)
+
+// Lifecycle provides a canonical source for eris loggers. Components should use the functions here
+// to set up their root logger and capture any other logging output.
+
+// Obtain a logger from a LoggingConfig
+func NewLoggerFromLoggingConfig(LoggingConfig *logging.LoggingConfig) loggers.InfoTraceLogger {
+	return NewStdErrLogger()
+}
+
+func NewStdErrLogger() loggers.InfoTraceLogger {
+	logger := tmLog15adapter.Log15HandlerAsKitLogger(
+		tmLog15.StreamHandler(os.Stderr, tmLog15.TerminalFormat()))
+	return NewLogger(logger, logger)
+}
+
+// Provided a standard eris logger that outputs to the supplied underlying info and trace
+// loggers
+func NewLogger(infoLogger, traceLogger kitlog.Logger) loggers.InfoTraceLogger {
+	infoTraceLogger := loggers.NewInfoTraceLogger(
+		loggers.ErisFormatLogger(infoLogger),
+		loggers.ErisFormatLogger(traceLogger))
+	// Create a random ID based on start time
+	uuid, _ := simpleuuid.NewTime(time.Now())
+	var runId string
+	if uuid != nil {
+		runId = uuid.String()
+	}
+	return logging.WithMetadata(infoTraceLogger.With(structure.RunId, runId))
+}
+
+func CaptureTendermintLog15Output(infoTraceLogger loggers.InfoTraceLogger) {
+	tmLog15.Root().SetHandler(
+		tmLog15adapter.InfoTraceLoggerAsLog15Handler(infoTraceLogger.
+			With(structure.CapturedLoggingSourceKey, "tendermint_log15")))
+}
+
+func CaptureStdlibLogOutput(infoTraceLogger loggers.InfoTraceLogger) {
+	stdlib.CaptureRootLogger(infoTraceLogger.
+		With(structure.CapturedLoggingSourceKey, "stdlib_log"))
+}
diff --git a/logging/loggers/channel_logger.go b/logging/loggers/channel_logger.go
new file mode 100644
index 0000000000000000000000000000000000000000..1bacfa44697847389ab8b689f0a672cb3a3fa53b
--- /dev/null
+++ b/logging/loggers/channel_logger.go
@@ -0,0 +1,87 @@
+// 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 loggers
+
+import (
+	"github.com/eapache/channels"
+	kitlog "github.com/go-kit/kit/log"
+)
+
+const (
+	LoggingRingBufferCap channels.BufferCap = 100
+)
+
+type ChannelLogger struct {
+	ch channels.Channel
+}
+
+var _ kitlog.Logger = (*ChannelLogger)(nil)
+
+// Creates a Logger that uses a uses a non-blocking channel.
+//
+// We would like calls to Log to never block so we use a channel implementation
+// that is non-blocking on writes and is able to be so by using a finite ring
+// buffer.
+func newChannelLogger() *ChannelLogger {
+	return &ChannelLogger{
+		ch: channels.NewRingChannel(LoggingRingBufferCap),
+	}
+}
+
+func (cl *ChannelLogger) Log(keyvals ...interface{}) error {
+	cl.ch.In() <- keyvals
+	// We don't have a way to pass on any logging errors, but that's okay: Log is
+	// a maximal interface and the error return type is only there for special
+	// cases.
+	return nil
+}
+
+// Read a log line by waiting until one is available and returning it
+func (cl *ChannelLogger) WaitReadLogLine() []interface{} {
+	log := <-cl.ch.Out()
+	// We are passing slices of interfaces down this channel (go-kit log's Log
+	// interface type), a panic is the right thing to do if this type assertion
+	// fails.
+	return log.([]interface{})
+}
+
+// Tries to read a log line from the channel buffer or returns nil if none is
+// immediately available
+func (cl *ChannelLogger) ReadLogLine() []interface{} {
+	select {
+	case log := <-cl.ch.Out():
+		// See WaitReadLogLine
+		return log.([]interface{})
+	default:
+		return nil
+	}
+}
+
+// Enters an infinite loop that will drain any log lines from the passed logger.
+//
+// Exits if the channel is closed.
+func (cl *ChannelLogger) DrainChannelToLogger(logger kitlog.Logger) {
+	for cl.ch.Out() != nil {
+		logger.Log(cl.WaitReadLogLine()...)
+	}
+}
+
+// Wraps an underlying Logger baseLogger to provide a Logger that is
+// is non-blocking on calls to Log.
+func NonBlockingLogger(logger kitlog.Logger) *ChannelLogger {
+	cl := newChannelLogger()
+	go cl.DrainChannelToLogger(logger)
+	return cl
+}
diff --git a/logging/loggers/channel_logger_test.go b/logging/loggers/channel_logger_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..0573556e15f70b11ec1163e36ab5435106e612ab
--- /dev/null
+++ b/logging/loggers/channel_logger_test.go
@@ -0,0 +1,47 @@
+// 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 loggers
+
+import (
+	"testing"
+
+	"fmt"
+
+	"github.com/stretchr/testify/assert"
+)
+
+func TestChannelLogger(t *testing.T) {
+	cl := newChannelLogger()
+
+	// Push a larger number of log messages than will fit into ring buffer
+	for i := 0; i < int(LoggingRingBufferCap)+10; i++ {
+		cl.Log("log line", i)
+	}
+
+	// Observe that oldest 10 messages are overwritten (so first message is 10)
+	for i := 0; i < int(LoggingRingBufferCap); i++ {
+		ll := cl.WaitReadLogLine()
+		assert.Equal(t, 10+i, ll[1])
+	}
+
+	assert.Nil(t, cl.ReadLogLine(), "Since we have drained the buffer there "+
+		"should be no more log lines.")
+}
+
+func TestBlether(t *testing.T) {
+	var bs []byte
+	ext := append(bs)
+	fmt.Println(ext)
+}
diff --git a/logging/loggers/eris_format_logger.go b/logging/loggers/eris_format_logger.go
new file mode 100644
index 0000000000000000000000000000000000000000..aea07254d4d0356620a40919f8caad7165bb3e43
--- /dev/null
+++ b/logging/loggers/eris_format_logger.go
@@ -0,0 +1,53 @@
+// 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 loggers
+
+import (
+	"fmt"
+
+	"github.com/eris-ltd/eris-db/logging/structure"
+
+	kitlog "github.com/go-kit/kit/log"
+)
+
+// Logger that implements some formatting conventions for eris-db and eris-client
+// This is intended for applying consistent value formatting before the final 'output' logger;
+// we should avoid prematurely formatting values here if it is useful to let the output logger
+// decide how it wants to display values. Ideal candidates for 'early' formatting here are types that
+// we control and generic output loggers are unlikely to know about.
+type erisFormatLogger struct {
+	logger kitlog.Logger
+}
+
+var _ kitlog.Logger = &erisFormatLogger{}
+
+func (efl *erisFormatLogger) Log(keyvals ...interface{}) error {
+	return efl.logger.Log(structure.MapKeyValues(keyvals, erisFormatKeyValueMapper)...)
+}
+
+func erisFormatKeyValueMapper(key, value interface{}) (interface{}, interface{}) {
+	switch key {
+	default:
+		switch v := value.(type) {
+		case []byte:
+			return key, fmt.Sprintf("%X", v)
+		}
+	}
+	return key, value
+}
+
+func ErisFormatLogger(logger kitlog.Logger) *erisFormatLogger {
+	return &erisFormatLogger{logger: logger}
+}
diff --git a/logging/loggers/info_trace_logger.go b/logging/loggers/info_trace_logger.go
new file mode 100644
index 0000000000000000000000000000000000000000..e127e10feef184c68b26fa2fe15131e6d17da3ea
--- /dev/null
+++ b/logging/loggers/info_trace_logger.go
@@ -0,0 +1,141 @@
+// 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 loggers
+
+import (
+	"github.com/eris-ltd/eris-db/logging/structure"
+	kitlog "github.com/go-kit/kit/log"
+)
+
+const (
+	InfoChannelName  = "Info"
+	TraceChannelName = "Trace"
+
+	InfoLevelName  = InfoChannelName
+	TraceLevelName = TraceChannelName
+)
+
+type infoTraceLogger struct {
+	infoLogger  *kitlog.Context
+	traceLogger *kitlog.Context
+}
+
+// InfoTraceLogger maintains two independent concurrently-safe channels of
+// logging. The idea behind the independence is that you can ignore one channel
+// with no performance penalty. For more fine grained filtering or aggregation
+// the Info and Trace loggers can be decorated loggers that perform arbitrary
+// filtering/routing/aggregation on log messages.
+type InfoTraceLogger interface {
+	// Send a log message to the default channel
+	kitlog.Logger
+
+	// Send an log message to the Info channel, formed of a sequence of key value
+	// pairs. Info messages should be operationally interesting to a human who is
+	// monitoring the logs. But not necessarily a human who is trying to
+	// understand or debug the system. Any handled errors or warnings should be
+	// sent to the Info channel (where you may wish to tag them with a suitable
+	// key-value pair to categorise them as such).
+	Info(keyvals ...interface{}) error
+
+	// Send an log message to the Trace channel, formed of a sequence of key-value
+	// pairs. Trace messages can be used for any state change in the system that
+	// may be of interest to a machine consumer or a human who is trying to debug
+	// the system or trying to understand the system in detail. If the messages
+	// are very point-like and contain little structure, consider using a metric
+	// instead.
+	Trace(keyvals ...interface{}) error
+
+	// A logging context (see go-kit log's Context). Takes a sequence key values
+	// via With or WithPrefix and ensures future calls to log will have those
+	// contextual values appended to the call to an underlying logger.
+	// Values can be dynamic by passing an instance of the kitlog.Valuer interface
+	// This provides an interface version of the kitlog.Context struct to be used
+	// For implementations that wrap a kitlog.Context. In addition it makes no
+	// assumption about the name or signature of the logging method(s).
+	// See InfoTraceLogger
+
+	// Establish a context by appending contextual key-values to any existing
+	// contextual values
+	With(keyvals ...interface{}) InfoTraceLogger
+
+	// Establish a context by prepending contextual key-values to any existing
+	// contextual values
+	WithPrefix(keyvals ...interface{}) InfoTraceLogger
+}
+
+// Interface assertions
+var _ InfoTraceLogger = (*infoTraceLogger)(nil)
+var _ kitlog.Logger = (InfoTraceLogger)(nil)
+
+func NewInfoTraceLogger(infoLogger, traceLogger kitlog.Logger) InfoTraceLogger {
+	// We will never halt the progress of a log emitter. If log output takes too
+	// long will start dropping log lines by using a ring buffer.
+	// We also guard against any concurrency bugs in underlying loggers by feeding
+	// them from a single channel
+	logger := kitlog.NewContext(NonBlockingLogger(VectorValuedLogger(
+		MultipleChannelLogger(
+			map[string]kitlog.Logger{
+				InfoChannelName:  infoLogger,
+				TraceChannelName: traceLogger,
+			}))))
+	return &infoTraceLogger{
+		infoLogger: logger.With(
+			structure.ChannelKey, InfoChannelName,
+			structure.LevelKey, InfoLevelName,
+		),
+		traceLogger: logger.With(
+			structure.ChannelKey, TraceChannelName,
+			structure.LevelKey, TraceLevelName,
+		),
+	}
+}
+
+func NewNoopInfoTraceLogger() InfoTraceLogger {
+	noopLogger := kitlog.NewNopLogger()
+	return NewInfoTraceLogger(noopLogger, noopLogger)
+}
+
+func (l *infoTraceLogger) With(keyvals ...interface{}) InfoTraceLogger {
+	return &infoTraceLogger{
+		infoLogger:  l.infoLogger.With(keyvals...),
+		traceLogger: l.traceLogger.With(keyvals...),
+	}
+}
+
+func (l *infoTraceLogger) WithPrefix(keyvals ...interface{}) InfoTraceLogger {
+	return &infoTraceLogger{
+		infoLogger:  l.infoLogger.WithPrefix(keyvals...),
+		traceLogger: l.traceLogger.WithPrefix(keyvals...),
+	}
+}
+
+func (l *infoTraceLogger) Info(keyvals ...interface{}) error {
+	// We send Info and Trace log lines down the same pipe to keep them ordered
+	return l.infoLogger.Log(keyvals...)
+}
+
+func (l *infoTraceLogger) Trace(keyvals ...interface{}) error {
+	return l.traceLogger.Log(keyvals...)
+}
+
+// If logged to as a plain kitlog logger presume the message is for Trace
+// This favours keeping Info reasonably quiet. Note that an InfoTraceLogger
+// aware adapter can make its own choices, but we tend to thing of logs from
+// dependencies as less interesting than logs generated by us or specifically
+// routed by us.
+func (l *infoTraceLogger) Log(keyvals ...interface{}) error {
+	l.Trace(keyvals...)
+	return nil
+}
diff --git a/logging/loggers/info_trace_logger_test.go b/logging/loggers/info_trace_logger_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..1717455401d50c787be69f7a9ee99991c3836366
--- /dev/null
+++ b/logging/loggers/info_trace_logger_test.go
@@ -0,0 +1,28 @@
+// 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 loggers
+
+import (
+	"os"
+	"testing"
+
+	kitlog "github.com/go-kit/kit/log"
+)
+
+func TestLogger(t *testing.T) {
+	stderrLogger := kitlog.NewLogfmtLogger(os.Stderr)
+	logger := NewInfoTraceLogger(stderrLogger, stderrLogger)
+	logger.Trace("hello", "barry")
+}
diff --git a/logging/loggers/logging_test.go b/logging/loggers/logging_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..103d8ddf7c295cd5749e66ea5697c4eaa55791cf
--- /dev/null
+++ b/logging/loggers/logging_test.go
@@ -0,0 +1,35 @@
+// 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 loggers
+
+import "errors"
+
+type testLogger struct {
+	logLines [][]interface{}
+	err      error
+}
+
+func newErrorLogger(errMessage string) *testLogger {
+	return &testLogger{err: errors.New(errMessage)}
+}
+
+func newTestLogger() *testLogger {
+	return &testLogger{}
+}
+
+func (tl *testLogger) Log(keyvals ...interface{}) error {
+	tl.logLines = append(tl.logLines, keyvals)
+	return tl.err
+}
diff --git a/logging/loggers/multiple_channel_logger.go b/logging/loggers/multiple_channel_logger.go
new file mode 100644
index 0000000000000000000000000000000000000000..2e2e344f44bc1a69f7c53ed3608f257a09c9304c
--- /dev/null
+++ b/logging/loggers/multiple_channel_logger.go
@@ -0,0 +1,51 @@
+// 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 loggers
+
+import (
+	"fmt"
+
+	"github.com/eris-ltd/eris-db/logging/structure"
+	kitlog "github.com/go-kit/kit/log"
+)
+
+// This represents a 'SELECT ONE' type logger. When logged to it will search
+// for the ChannelKey field, look that up in its map and send the log line there
+// Otherwise logging is a noop (but an error will be returned - which is optional)
+type MultipleChannelLogger map[string]kitlog.Logger
+
+var _ kitlog.Logger = MultipleChannelLogger(nil)
+
+// Like go-kit log's Log method only logs a message to the specified channelName
+// which must be a member of this MultipleChannelLogger
+func (mcl MultipleChannelLogger) Log(keyvals ...interface{}) error {
+	channel := structure.Value(keyvals, structure.ChannelKey)
+	if channel == nil {
+		return fmt.Errorf("MultipleChannelLogger could not select channel because"+
+			" '%s' was not set in log message", structure.ChannelKey)
+	}
+	channelName, ok := channel.(string)
+	if !ok {
+		return fmt.Errorf("MultipleChannelLogger could not select channel because"+
+			" channel was set to non-string value %v", channel)
+	}
+	logger := mcl[channelName]
+	if logger == nil {
+		return fmt.Errorf("Could not log to channel '%s', since it is not "+
+			"registered with this MultipleChannelLogger (the underlying logger may "+
+			"have been nil when passed to NewMultipleChannelLogger)", channelName)
+	}
+	return logger.Log(keyvals...)
+}
diff --git a/logging/loggers/multiple_channel_logger_test.go b/logging/loggers/multiple_channel_logger_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..a140420433a6aef95879457e97db8bdbeff7b5f4
--- /dev/null
+++ b/logging/loggers/multiple_channel_logger_test.go
@@ -0,0 +1,42 @@
+// 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 loggers
+
+import (
+	"runtime"
+	"testing"
+	"time"
+
+	"github.com/eris-ltd/eris-db/logging/structure"
+	kitlog "github.com/go-kit/kit/log"
+	"github.com/stretchr/testify/assert"
+)
+
+func TestMultipleChannelLogger(t *testing.T) {
+	boringLogger, interestingLogger := newTestLogger(), newTestLogger()
+	mcl := kitlog.NewContext(MultipleChannelLogger(map[string]kitlog.Logger{
+		"Boring":      boringLogger,
+		"Interesting": interestingLogger,
+	}))
+	err := mcl.With("time", kitlog.Valuer(func() interface{} { return "aa" })).
+		Log(structure.ChannelKey, "Boring", "foo", "bar")
+	assert.NoError(t, err, "Should log without an error")
+	// Wait for channel to drain
+	time.Sleep(time.Second)
+	runtime.Gosched()
+	assert.Equal(t, []interface{}{"time", "aa", structure.ChannelKey, "Boring",
+		"foo", "bar"},
+		boringLogger.logLines[0])
+}
diff --git a/logging/loggers/multiple_output_logger.go b/logging/loggers/multiple_output_logger.go
new file mode 100644
index 0000000000000000000000000000000000000000..89ae50a978964758ead7891c5e79ece832cd87ce
--- /dev/null
+++ b/logging/loggers/multiple_output_logger.go
@@ -0,0 +1,64 @@
+// 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 loggers
+
+import (
+	"strings"
+
+	kitlog "github.com/go-kit/kit/log"
+)
+
+// This represents an 'AND' type logger. When logged to it will log to each of
+// the loggers in the slice.
+type MultipleOutputLogger []kitlog.Logger
+
+var _ kitlog.Logger = MultipleOutputLogger(nil)
+
+func (mol MultipleOutputLogger) Log(keyvals ...interface{}) error {
+	var errs []error
+	for _, logger := range mol {
+		err := logger.Log(keyvals...)
+		if err != nil {
+			errs = append(errs, err)
+		}
+	}
+	return combineErrors(errs)
+}
+
+// Creates a logger that forks log messages to each of its outputLoggers
+func NewMultipleOutputLogger(outputLoggers ...kitlog.Logger) kitlog.Logger {
+	return MultipleOutputLogger(outputLoggers)
+}
+
+type multipleErrors []error
+
+func combineErrors(errs []error) error {
+	switch len(errs) {
+	case 0:
+		return nil
+	case 1:
+		return errs[0]
+	default:
+		return multipleErrors(errs)
+	}
+}
+
+func (errs multipleErrors) Error() string {
+	var errStrings []string
+	for _, err := range errs {
+		errStrings = append(errStrings, err.Error())
+	}
+	return strings.Join(errStrings, ";")
+}
diff --git a/logging/loggers/multiple_output_logger_test.go b/logging/loggers/multiple_output_logger_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..4f606376af8c44d8441bbb33d6d49d322138a833
--- /dev/null
+++ b/logging/loggers/multiple_output_logger_test.go
@@ -0,0 +1,32 @@
+// 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 loggers
+
+import (
+	"testing"
+
+	"github.com/stretchr/testify/assert"
+)
+
+func TestNewMultipleOutputLogger(t *testing.T) {
+	a, b := newErrorLogger("error a"), newErrorLogger("error b")
+	mol := NewMultipleOutputLogger(a, b)
+	logLine := []interface{}{"msg", "hello"}
+	err := mol.Log(logLine...)
+	expected := [][]interface{}{logLine}
+	assert.Equal(t, expected, a.logLines)
+	assert.Equal(t, expected, b.logLines)
+	assert.IsType(t, multipleErrors{}, err)
+}
diff --git a/logging/loggers/vector_valued_logger.go b/logging/loggers/vector_valued_logger.go
new file mode 100644
index 0000000000000000000000000000000000000000..fa59cdbfaaf48b260cf3b77d592cdad97aa2280d
--- /dev/null
+++ b/logging/loggers/vector_valued_logger.go
@@ -0,0 +1,35 @@
+// 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 loggers
+
+import (
+	"github.com/eris-ltd/eris-db/logging/structure"
+	kitlog "github.com/go-kit/kit/log"
+)
+
+// Treat duplicate key-values as consecutive entries in a vector-valued lookup
+type vectorValuedLogger struct {
+	logger kitlog.Logger
+}
+
+var _ kitlog.Logger = &vectorValuedLogger{}
+
+func (vvl *vectorValuedLogger) Log(keyvals ...interface{}) error {
+	return vvl.logger.Log(structure.Vectorise(keyvals)...)
+}
+
+func VectorValuedLogger(logger kitlog.Logger) *vectorValuedLogger {
+	return &vectorValuedLogger{logger: logger}
+}
diff --git a/logging/loggers/vector_valued_logger_test.go b/logging/loggers/vector_valued_logger_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..157f5bc08fc162d557b295d960aae359a024130c
--- /dev/null
+++ b/logging/loggers/vector_valued_logger_test.go
@@ -0,0 +1,31 @@
+// 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 loggers
+
+import (
+	"testing"
+
+	. "github.com/eris-ltd/eris-db/util/slice"
+	"github.com/stretchr/testify/assert"
+)
+
+func TestVectorValuedLogger(t *testing.T) {
+	logger := newTestLogger()
+	vvl := VectorValuedLogger(logger)
+	vvl.Log("foo", "bar", "seen", 1, "seen", 3, "seen", 2)
+
+	assert.Equal(t, Slice("foo", "bar", "seen", Slice(1, 3, 2)),
+		logger.logLines[0])
+}
diff --git a/logging/metadata.go b/logging/metadata.go
new file mode 100644
index 0000000000000000000000000000000000000000..258ca733c749698d85bc26fca949bc5eed0d5a2b
--- /dev/null
+++ b/logging/metadata.go
@@ -0,0 +1,47 @@
+// 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 logging
+
+import (
+	"time"
+
+	"github.com/eris-ltd/eris-db/logging/loggers"
+	"github.com/eris-ltd/eris-db/logging/structure"
+	kitlog "github.com/go-kit/kit/log"
+	"github.com/go-stack/stack"
+)
+
+const (
+	// To get the Caller information correct on the log, we need to count the
+	// number of calls from a log call in the code to the time it hits a kitlog
+	// context: [log call site (5), Info/Trace (4), MultipleChannelLogger.Log (3),
+	// kitlog.Context.Log (2), kitlog.bindValues (1) (binding occurs),
+	// kitlog.Caller (0), stack.caller]
+	infoTraceLoggerCallDepth = 5
+)
+
+var defaultTimestampUTCValuer kitlog.Valuer = func() interface{} {
+	return time.Now()
+}
+
+func WithMetadata(infoTraceLogger loggers.InfoTraceLogger) loggers.InfoTraceLogger {
+	return infoTraceLogger.With(structure.TimeKey, defaultTimestampUTCValuer,
+		structure.CallerKey, kitlog.Caller(infoTraceLoggerCallDepth),
+		"trace", TraceValuer())
+}
+
+func TraceValuer() kitlog.Valuer {
+	return func() interface{} { return stack.Trace() }
+}
diff --git a/logging/structure/structure.go b/logging/structure/structure.go
new file mode 100644
index 0000000000000000000000000000000000000000..43a55df87f7cd2f93a859dce5980ada59964e843
--- /dev/null
+++ b/logging/structure/structure.go
@@ -0,0 +1,160 @@
+// 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 structure
+
+import (
+	"reflect"
+
+	. "github.com/eris-ltd/eris-db/util/slice"
+)
+
+const (
+	// Log time (time.Time)
+	TimeKey = "time"
+	// Call site for log invocation (go-stack.Call)
+	CallerKey = "caller"
+	// Level name (string)
+	LevelKey = "level"
+	// Channel name in a vector channel logging context
+	ChannelKey = "channel"
+	// Log message (string)
+	MessageKey = "message"
+	// Captured logging source (like tendermint_log15, stdlib_log)
+	CapturedLoggingSourceKey = "captured_logging_source"
+	// Top-level component (choose one) name
+	ComponentKey = "component"
+	// Vector-valued scope
+	ScopeKey = "scope"
+	// Globally unique identifier persisting while a single instance (root process)
+	// of this program/service is running
+	RunId = "run_id"
+)
+
+// Pull the specified values from a structured log line into a map.
+// Assumes keys are single-valued.
+// Returns a map of the key-values from the requested keys and
+// the unmatched remainder keyvals as context as a slice of key-values.
+func ValuesAndContext(keyvals []interface{},
+	keys ...interface{}) (map[interface{}]interface{}, []interface{}) {
+	vals := make(map[interface{}]interface{}, len(keys))
+	context := make([]interface{}, len(keyvals))
+	copy(context, keyvals)
+	deletions := 0
+	// We can't really do better than a linear scan of both lists here. N is small
+	// so screw the asymptotics.
+	// Guard against odd-length list
+	for i := 0; i < 2*(len(keyvals)/2); i += 2 {
+		for k := 0; k < len(keys); k++ {
+			if keyvals[i] == keys[k] {
+				// Pull the matching key-value pair into vals to return
+				vals[keys[k]] = keyvals[i+1]
+				// Delete the key once it's found
+				keys = DeleteAt(keys, k)
+				// And remove the key-value pair from context
+				context = Delete(context, i-deletions, 2)
+				// Keep a track of how much we've shrunk the context to offset next
+				// deletion
+				deletions += 2
+				break
+			}
+		}
+	}
+	return vals, context
+}
+
+// Stateful index that tracks the location of a possible vector value
+type vectorValueindex struct {
+	// Location of the value belonging to a key in output slice
+	valueIndex int
+	// Whether or not the value is currently a vector
+	vector bool
+}
+
+// 'Vectorises' values associated with repeated string keys member by collapsing many values into a single vector value.
+// The result is a copy of keyvals where the first occurrence of each matching key and its first value are replaced by
+// that key and all of its values in a single slice.
+func Vectorise(keyvals []interface{}, vectorKeys ...string) []interface{} {
+	// We rely on working against a single backing array, so we use a capacity that is the maximum possible size of the
+	// slice after vectorising (in the case there are no duplicate keys and this is a no-op)
+	outputKeyvals := make([]interface{}, 0, len(keyvals))
+	// Track the location and vector status of the values in the output
+	valueIndices := make(map[string]*vectorValueindex, len(vectorKeys))
+	elided := 0
+	for i := 0; i < 2*(len(keyvals)/2); i += 2 {
+		key := keyvals[i]
+		val := keyvals[i+1]
+
+		// Only attempt to vectorise string keys
+		if k, ok := key.(string); ok {
+			if valueIndices[k] == nil {
+				// Record that this key has been seen once
+				valueIndices[k] = &vectorValueindex{
+					valueIndex: i + 1 - elided,
+				}
+				// Copy the key-value to output with the single value
+				outputKeyvals = append(outputKeyvals, key, val)
+			} else {
+				// We have seen this key before
+				vi := valueIndices[k]
+				if !vi.vector {
+					// This must be the only second occurrence of the key so now vectorise the value
+					outputKeyvals[vi.valueIndex] = []interface{}{outputKeyvals[vi.valueIndex]}
+					vi.vector = true
+				}
+				// Grow the vector value
+				outputKeyvals[vi.valueIndex] = append(outputKeyvals[vi.valueIndex].([]interface{}), val)
+				// We are now running two more elements behind the input keyvals because we have absorbed this key-value pair
+				elided += 2
+			}
+		} else {
+			// Just copy the key-value to the output for non-string keys
+			outputKeyvals = append(outputKeyvals, key, val)
+		}
+	}
+	return outputKeyvals
+}
+
+// Return a single value corresponding to key in keyvals
+func Value(keyvals []interface{}, key interface{}) interface{} {
+	for i := 0; i < 2*(len(keyvals)/2); i += 2 {
+		if keyvals[i] == key {
+			return keyvals[i+1]
+		}
+	}
+	return nil
+}
+
+// Obtain a canonical key from a value. Useful for structured logging where the
+// type of value alone may be sufficient to determine its key. Providing this
+// function centralises any convention over type names
+func KeyFromValue(val interface{}) string {
+	switch val.(type) {
+	case string:
+		return "text"
+	default:
+		return reflect.TypeOf(val).Name()
+	}
+}
+
+// Maps key values pairs with a function (key, value) -> (new key, new value)
+func MapKeyValues(keyvals []interface{}, fn func(interface{}, interface{}) (interface{}, interface{})) []interface{} {
+	mappedKeyvals := make([]interface{}, len(keyvals))
+	for i := 0; i < 2*(len(keyvals)/2); i += 2 {
+		key := keyvals[i]
+		val := keyvals[i+1]
+		mappedKeyvals[i], mappedKeyvals[i+1] = fn(key, val)
+	}
+	return mappedKeyvals
+}
diff --git a/logging/structure/structure_test.go b/logging/structure/structure_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..bbdd0895f348a8c6ceb99dca26470dce1b34e4ca
--- /dev/null
+++ b/logging/structure/structure_test.go
@@ -0,0 +1,50 @@
+// 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 structure
+
+import (
+	"testing"
+
+	. "github.com/eris-ltd/eris-db/util/slice"
+	"github.com/stretchr/testify/assert"
+)
+
+func TestValuesAndContext(t *testing.T) {
+	keyvals := Slice("hello", 1, "dog", 2, "fish", 3, "fork", 5)
+	vals, ctx := ValuesAndContext(keyvals, "hello", "fish")
+	assert.Equal(t, map[interface{}]interface{}{"hello": 1, "fish": 3}, vals)
+	assert.Equal(t, Slice("dog", 2, "fork", 5), ctx)
+}
+
+func TestVectorise(t *testing.T) {
+	kvs := Slice(
+		"scope", "lawnmower",
+		"hub", "budub",
+		"occupation", "fish brewer",
+		"scope", "hose pipe",
+		"flub", "dub",
+		"scope", "rake",
+		"flub", "brub",
+	)
+
+	kvsVector := Vectorise(kvs, "occupation", "scope")
+	assert.Equal(t, Slice(
+		"scope", Slice("lawnmower", "hose pipe", "rake"),
+		"hub", "budub",
+		"occupation", "fish brewer",
+		"flub", Slice("dub", "brub"),
+	),
+		kvsVector)
+}
diff --git a/logging/terminal.go b/logging/terminal.go
new file mode 100644
index 0000000000000000000000000000000000000000..8a2be393e4ba61152ac58f9d872b5ada94ab2a68
--- /dev/null
+++ b/logging/terminal.go
@@ -0,0 +1,43 @@
+// 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 logging
+
+import (
+	"github.com/eris-ltd/eris-db/logging/structure"
+	"github.com/go-kit/kit/log/term"
+)
+
+func Colors(keyvals ...interface{}) term.FgBgColor {
+	for i := 0; i < len(keyvals)-1; i += 2 {
+		if keyvals[i] != structure.LevelKey {
+			continue
+		}
+		switch keyvals[i+1] {
+		case "debug":
+			return term.FgBgColor{Fg: term.DarkGray}
+		case "info":
+			return term.FgBgColor{Fg: term.Gray}
+		case "warn":
+			return term.FgBgColor{Fg: term.Yellow}
+		case "error":
+			return term.FgBgColor{Fg: term.Red}
+		case "crit":
+			return term.FgBgColor{Fg: term.Gray, Bg: term.DarkRed}
+		default:
+			return term.FgBgColor{}
+		}
+	}
+	return term.FgBgColor{}
+}
diff --git a/manager/config.go b/manager/config.go
index 28c84e21dac88ac0b6763eddbca1c7236e701519..827d25ed5b1fa036628f3b6fc429a12029dada6f 100644
--- a/manager/config.go
+++ b/manager/config.go
@@ -1,21 +1,16 @@
-// Copyright 2015, 2016 Eris Industries (UK) Ltd.
-// This file is part of Eris-RT
-
-// Eris-RT is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-
-// Eris-RT is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License
-// along with Eris-RT.  If not, see <http://www.gnu.org/licenses/>.
-
-// version provides the current Eris-DB version and a VersionIdentifier
-// for the modules to identify their version with.
+// 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 manager
 
diff --git a/manager/eris-mint/accounts.go b/manager/eris-mint/accounts.go
index 58a09b0e765c143dba2595fa4c35d660ad59b40d..9134162940f5f891f886330f71fb3c45ca027c60 100644
--- a/manager/eris-mint/accounts.go
+++ b/manager/eris-mint/accounts.go
@@ -1,22 +1,21 @@
-// Copyright 2015, 2016 Eris Industries (UK) Ltd.
-// This file is part of Eris-RT
+// 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.
 
-// Eris-RT is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-
-// Eris-RT is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License
-// along with Eris-RT.  If not, see <http://www.gnu.org/licenses/>.
+package erismint
 
 // Accounts is part of the pipe for ErisMint and provides the implementation
 // for the pipe to call into the ErisMint application
-package erismint
 
 import (
 	"bytes"
@@ -24,12 +23,11 @@ import (
 	"fmt"
 	"sync"
 
-	tendermint_common "github.com/tendermint/go-common"
-
 	account "github.com/eris-ltd/eris-db/account"
 	core_types "github.com/eris-ltd/eris-db/core/types"
 	definitions "github.com/eris-ltd/eris-db/definitions"
 	event "github.com/eris-ltd/eris-db/event"
+	word256 "github.com/eris-ltd/eris-db/word256"
 )
 
 // NOTE [ben] Compiler check to ensure Accounts successfully implements
@@ -119,7 +117,7 @@ func (this *accounts) StorageAt(address, key []byte) (*core_types.StorageItem,
 	storageRoot := account.StorageRoot
 	storageTree := state.LoadStorage(storageRoot)
 
-	_, value, _ := storageTree.Get(tendermint_common.LeftPadWord256(key).Bytes())
+	_, value, _ := storageTree.Get(word256.LeftPadWord256(key).Bytes())
 	if value == nil {
 		return &core_types.StorageItem{key, []byte{}}, nil
 	}
diff --git a/manager/eris-mint/eris-mint.go b/manager/eris-mint/eris-mint.go
index 772174fe10117394b79e49ac0b98c98d08fd07ff..9ba18441832ecf6bce0b500ba99fca9bc41b3a40 100644
--- a/manager/eris-mint/eris-mint.go
+++ b/manager/eris-mint/eris-mint.go
@@ -1,18 +1,16 @@
-// Copyright 2015, 2016 Eris Industries (UK) Ltd.
-// This file is part of Eris-RT
-
-// Eris-RT is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-
-// Eris-RT is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License
-// along with Eris-RT.  If not, see <http://www.gnu.org/licenses/>.
+// 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 erismint
 
@@ -22,11 +20,12 @@ import (
 	"sync"
 	"time"
 
+	abci "github.com/tendermint/abci/types"
 	tendermint_events "github.com/tendermint/go-events"
 	wire "github.com/tendermint/go-wire"
-	tmsp "github.com/tendermint/tmsp/types"
 
-	log "github.com/eris-ltd/eris-logger"
+	"github.com/eris-ltd/eris-db/logging"
+	"github.com/eris-ltd/eris-db/logging/loggers"
 
 	sm "github.com/eris-ltd/eris-db/manager/eris-mint/state"
 	manager_types "github.com/eris-ltd/eris-db/manager/types"
@@ -46,18 +45,19 @@ type ErisMint struct {
 	checkCache *sm.BlockCache // for CheckTx (eg. so we get nonces right)
 
 	evc  *tendermint_events.EventCache
-	evsw *tendermint_events.EventSwitch
+	evsw tendermint_events.EventSwitch
 
-	nTxs int // count txs in a block
+	nTxs   int // count txs in a block
+	logger loggers.InfoTraceLogger
 }
 
 // NOTE [ben] Compiler check to ensure ErisMint successfully implements
 // eris-db/manager/types.Application
 var _ manager_types.Application = (*ErisMint)(nil)
 
-// NOTE: [ben] also automatically implements tmsp.Application,
+// NOTE: [ben] also automatically implements abci.Application,
 // undesired but unharmful
-// var _ tmsp.Application = (*ErisMint)(nil)
+// var _ abci.Application = (*ErisMint)(nil)
 
 func (app *ErisMint) GetState() *sm.State {
 	app.mtx.Lock()
@@ -72,19 +72,20 @@ func (app *ErisMint) GetCheckCache() *sm.BlockCache {
 	return app.checkCache
 }
 
-func NewErisMint(s *sm.State, evsw *tendermint_events.EventSwitch) *ErisMint {
+func NewErisMint(s *sm.State, evsw tendermint_events.EventSwitch, logger loggers.InfoTraceLogger) *ErisMint {
 	return &ErisMint{
 		state:      s,
 		cache:      sm.NewBlockCache(s),
 		checkCache: sm.NewBlockCache(s),
 		evc:        tendermint_events.NewEventCache(evsw),
 		evsw:       evsw,
+		logger:     logging.WithScope(logger, "ErisMint"),
 	}
 }
 
 // Implements manager/types.Application
-func (app *ErisMint) Info() (info string) {
-	return "ErisDB"
+func (app *ErisMint) Info() (info abci.ResponseInfo) {
+	return abci.ResponseInfo{}
 }
 
 // Implements manager/types.Application
@@ -93,7 +94,7 @@ func (app *ErisMint) SetOption(key string, value string) (log string) {
 }
 
 // Implements manager/types.Application
-func (app *ErisMint) AppendTx(txBytes []byte) tmsp.Result {
+func (app *ErisMint) DeliverTx(txBytes []byte) abci.Result {
 	app.nTxs += 1
 
 	// XXX: if we had tx ids we could cache the decoded txs on CheckTx
@@ -103,61 +104,60 @@ func (app *ErisMint) AppendTx(txBytes []byte) tmsp.Result {
 	buf := bytes.NewBuffer(txBytes)
 	wire.ReadBinaryPtr(tx, buf, len(txBytes), &n, &err)
 	if err != nil {
-		return tmsp.NewError(tmsp.CodeType_EncodingError, fmt.Sprintf("Encoding error: %v", err))
+		return abci.NewError(abci.CodeType_EncodingError, fmt.Sprintf("Encoding error: %v", err))
 	}
 
 	err = sm.ExecTx(app.cache, *tx, true, app.evc)
 	if err != nil {
-		return tmsp.NewError(tmsp.CodeType_InternalError, fmt.Sprintf("Internal error: %v", err))
+		return abci.NewError(abci.CodeType_InternalError, fmt.Sprintf("Internal error: %v", err))
 	}
 
 	receipt := txs.GenerateReceipt(app.state.ChainID, *tx)
 	receiptBytes := wire.BinaryBytes(receipt)
-	return tmsp.NewResultOK(receiptBytes, "Success")
+	return abci.NewResultOK(receiptBytes, "Success")
 }
 
 // Implements manager/types.Application
-func (app *ErisMint) CheckTx(txBytes []byte) tmsp.Result {
+func (app *ErisMint) CheckTx(txBytes []byte) abci.Result {
 	var n int
 	var err error
 	tx := new(txs.Tx)
 	buf := bytes.NewBuffer(txBytes)
 	wire.ReadBinaryPtr(tx, buf, len(txBytes), &n, &err)
 	if err != nil {
-		return tmsp.NewError(tmsp.CodeType_EncodingError, fmt.Sprintf("Encoding error: %v", err))
+		return abci.NewError(abci.CodeType_EncodingError, fmt.Sprintf("Encoding error: %v", err))
 	}
 
-	// TODO: map ExecTx errors to sensible TMSP error codes
+	// TODO: map ExecTx errors to sensible abci error codes
 	err = sm.ExecTx(app.checkCache, *tx, false, nil)
 	if err != nil {
-		return tmsp.NewError(tmsp.CodeType_InternalError, fmt.Sprintf("Internal error: %v", err))
+		return abci.NewError(abci.CodeType_InternalError, fmt.Sprintf("Internal error: %v", err))
 	}
 	receipt := txs.GenerateReceipt(app.state.ChainID, *tx)
 	receiptBytes := wire.BinaryBytes(receipt)
-	return tmsp.NewResultOK(receiptBytes, "Success")
+	return abci.NewResultOK(receiptBytes, "Success")
 }
 
 // Implements manager/types.Application
 // Commit the state (called at end of block)
 // NOTE: CheckTx/AppendTx must not run concurrently with Commit -
 //  the mempool should run during AppendTxs, but lock for Commit and Update
-func (app *ErisMint) Commit() (res tmsp.Result) {
+func (app *ErisMint) Commit() (res abci.Result) {
 	app.mtx.Lock() // the lock protects app.state
 	defer app.mtx.Unlock()
 
 	app.state.LastBlockHeight += 1
-	log.WithFields(log.Fields{
-		"blockheight": app.state.LastBlockHeight,
-	}).Info("Commit block")
+	logging.InfoMsg(app.logger, "Committing block",
+		"last_block_height", app.state.LastBlockHeight)
 
 	// sync the AppendTx cache
 	app.cache.Sync()
 
 	// Refresh the checkCache with the latest commited state
-	log.WithFields(log.Fields{
-		"txs": app.nTxs,
-	}).Info("Reset checkCache")
+	logging.InfoMsg(app.logger, "Resetting checkCache",
+		"txs", app.nTxs)
 	app.checkCache = sm.NewBlockCache(app.state)
+
 	app.nTxs = 0
 
 	// save state to disk
@@ -166,17 +166,16 @@ func (app *ErisMint) Commit() (res tmsp.Result) {
 	// flush events to listeners (XXX: note issue with blocking)
 	app.evc.Flush()
 
-	// MARMOT:
-	// set internal time as two seconds per block
+	// TODO: [ben] over the tendermint 0.6 TMSP interface we have
+	// no access to the block header implemented;
+	// On Tendermint v0.8 load the blockheader into the application
+	// state and remove the fixed 2-"seconds" per block internal clock.
+	// NOTE: set internal time as two seconds per block
 	app.state.LastBlockTime = app.state.LastBlockTime.Add(time.Duration(2) * time.Second)
-	fmt.Printf("\n\nMARMOT TIME: %s\n\n", app.state.LastBlockTime)
-	// MARMOT:
 	appHash := app.state.Hash()
-	fmt.Printf("\n\nMARMOT COMMIT: %X\n\n", appHash)
-	// return tmsp.NewResultOK(app.state.Hash(), "Success")
-	return tmsp.NewResultOK(appHash, "Success")
+	return abci.NewResultOK(appHash, "Success")
 }
 
-func (app *ErisMint) Query(query []byte) (res tmsp.Result) {
-	return tmsp.NewResultOK(nil, "Success")
+func (app *ErisMint) Query(query []byte) (res abci.Result) {
+	return abci.NewResultOK(nil, "Success")
 }
diff --git a/manager/eris-mint/eris-mint_test.go b/manager/eris-mint/eris-mint_test.go
index 294c34e233db0c260c3a0b3fd5993ad789d56231..b37c89532caeac8ffcaa7346419487bc973f97c8 100644
--- a/manager/eris-mint/eris-mint_test.go
+++ b/manager/eris-mint/eris-mint_test.go
@@ -1,18 +1,16 @@
-// Copyright 2015, 2016 Eris Industries (UK) Ltd.
-// This file is part of Eris-RT
-
-// Eris-RT is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-
-// Eris-RT is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License
-// along with Eris-RT.  If not, see <http://www.gnu.org/licenses/>.
+// 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 erismint
 
diff --git a/manager/eris-mint/evm/abi/types.go b/manager/eris-mint/evm/abi/types.go
new file mode 100644
index 0000000000000000000000000000000000000000..09ac0e4c364b73a48514b1f5007fe3704b7e182d
--- /dev/null
+++ b/manager/eris-mint/evm/abi/types.go
@@ -0,0 +1,53 @@
+// 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 abi
+
+// Ethereum defines types and calling conventions for the ABI
+// (application binary interface) here: https://github.com/ethereum/wiki/wiki/Ethereum-Contract-ABI
+// We make a start of representing them here
+
+// We use TypeName rather than Type to reserve 'Type' for a possible future
+// ABI type the can hold an ABI-native type mapping
+type TypeName string
+
+type Arg struct {
+	Name     string
+	TypeName TypeName
+}
+
+type Return struct {
+	Name     string
+	TypeName TypeName
+}
+
+const (
+	// We don't need to be exhaustive here, just make what we used strongly typed
+	AddressTypeName TypeName = "address"
+	IntTypeName     TypeName = "int"
+	Uint64TypeName  TypeName = "uint64"
+	Bytes32TypeName TypeName = "bytes32"
+	StringTypeName  TypeName = "string"
+	BoolTypeName    TypeName = "bool"
+)
+
+const (
+	FunctionSelectorLength = 4
+	AddressLength          = 20
+)
+
+type (
+	Address          [AddressLength]byte
+	FunctionSelector [FunctionSelectorLength]byte
+)
diff --git a/manager/eris-mint/evm/common.go b/manager/eris-mint/evm/common.go
index 00ab93c775f6b4ba8e29c1cc38eca28a9a7920f2..fbbd4c51a33263669eaf4bc699ddc730a2ce84ba 100644
--- a/manager/eris-mint/evm/common.go
+++ b/manager/eris-mint/evm/common.go
@@ -1,3 +1,17 @@
+// 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 vm
 
 import (
diff --git a/manager/eris-mint/evm/test/fake_app_state.go b/manager/eris-mint/evm/fake_app_state.go
similarity index 64%
rename from manager/eris-mint/evm/test/fake_app_state.go
rename to manager/eris-mint/evm/fake_app_state.go
index c27e54256fe7ea102ffea6bd3d12431382f1ec52..3c19b0cf27d39df45bae5480ebf40c4ac4898c6e 100644
--- a/manager/eris-mint/evm/test/fake_app_state.go
+++ b/manager/eris-mint/evm/fake_app_state.go
@@ -1,9 +1,24 @@
+// 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 vm
 
 import (
-	. "github.com/eris-ltd/eris-db/manager/eris-mint/evm"
+	"fmt"
+
 	"github.com/eris-ltd/eris-db/manager/eris-mint/evm/sha3"
-	. "github.com/tendermint/go-common"
+	. "github.com/eris-ltd/eris-db/word256"
 )
 
 type FakeAppState struct {
@@ -23,7 +38,7 @@ func (fas *FakeAppState) UpdateAccount(account *Account) {
 func (fas *FakeAppState) RemoveAccount(account *Account) {
 	_, ok := fas.accounts[account.Address.String()]
 	if !ok {
-		panic(Fmt("Invalid account addr: %X", account.Address))
+		panic(fmt.Sprintf("Invalid account addr: %X", account.Address))
 	} else {
 		// Remove account
 		delete(fas.accounts, account.Address.String())
@@ -41,14 +56,14 @@ func (fas *FakeAppState) CreateAccount(creator *Account) *Account {
 			Nonce:   0,
 		}
 	} else {
-		panic(Fmt("Invalid account addr: %X", addr))
+		panic(fmt.Sprintf("Invalid account addr: %X", addr))
 	}
 }
 
 func (fas *FakeAppState) GetStorage(addr Word256, key Word256) Word256 {
 	_, ok := fas.accounts[addr.String()]
 	if !ok {
-		panic(Fmt("Invalid account addr: %X", addr))
+		panic(fmt.Sprintf("Invalid account addr: %X", addr))
 	}
 
 	value, ok := fas.storage[addr.String()+key.String()]
@@ -62,7 +77,7 @@ func (fas *FakeAppState) GetStorage(addr Word256, key Word256) Word256 {
 func (fas *FakeAppState) SetStorage(addr Word256, key Word256, value Word256) {
 	_, ok := fas.accounts[addr.String()]
 	if !ok {
-		panic(Fmt("Invalid account addr: %X", addr))
+		panic(fmt.Sprintf("Invalid account addr: %X", addr))
 	}
 
 	fas.storage[addr.String()+key.String()] = value
diff --git a/manager/eris-mint/evm/gas.go b/manager/eris-mint/evm/gas.go
index fe4a43d80d5ae2ffddbb75b44f0a5633d70bb43e..9ffc5e56d6d9363aaeabb815d24fdc9dd1b3f602 100644
--- a/manager/eris-mint/evm/gas.go
+++ b/manager/eris-mint/evm/gas.go
@@ -1,3 +1,17 @@
+// 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 vm
 
 const (
diff --git a/manager/eris-mint/evm/log.go b/manager/eris-mint/evm/log.go
index 82880ae975da279da6f2cc43c4f0b547079ef790..8b5565197bf62c487aed2852e7c65998cc5a0019 100644
--- a/manager/eris-mint/evm/log.go
+++ b/manager/eris-mint/evm/log.go
@@ -1,3 +1,17 @@
+// 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 vm
 
 import (
diff --git a/manager/eris-mint/evm/test/log_event_test.go b/manager/eris-mint/evm/log_event_test.go
similarity index 77%
rename from manager/eris-mint/evm/test/log_event_test.go
rename to manager/eris-mint/evm/log_event_test.go
index 5f1eb2f463acfc0842878724c557d4f73d99ea6e..bdb55fb9e39c3a32453b0f5ad989a428c22aa817 100644
--- a/manager/eris-mint/evm/test/log_event_test.go
+++ b/manager/eris-mint/evm/log_event_test.go
@@ -1,3 +1,17 @@
+// 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 vm
 
 import (
@@ -5,10 +19,9 @@ import (
 	"reflect"
 	"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/eris-ltd/eris-db/word256"
 	"github.com/tendermint/go-events"
 )
 
diff --git a/manager/eris-mint/evm/native.go b/manager/eris-mint/evm/native.go
index 860f99bd252a9037168765f2d6aa207cb1df806e..e569474586834661d64d6ba9ee37e2babe90406f 100644
--- a/manager/eris-mint/evm/native.go
+++ b/manager/eris-mint/evm/native.go
@@ -1,11 +1,25 @@
+// 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 vm
 
 import (
 	"crypto/sha256"
 
-	"golang.org/x/crypto/ripemd160"
+	. "github.com/eris-ltd/eris-db/word256"
 
-	. "github.com/tendermint/go-common"
+	"golang.org/x/crypto/ripemd160"
 )
 
 var registeredNativeContracts = make(map[Word256]NativeContract)
diff --git a/manager/eris-mint/evm/opcodes/opcodes.go b/manager/eris-mint/evm/opcodes/opcodes.go
index b4205f2fe9633a80643740da942fbc51b1ff5382..ce064f213d7e94171c23206c6c821f78be1d45f4 100644
--- a/manager/eris-mint/evm/opcodes/opcodes.go
+++ b/manager/eris-mint/evm/opcodes/opcodes.go
@@ -1,8 +1,23 @@
+// 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 opcodes
 
 import (
 	"fmt"
 
+	"github.com/eris-ltd/eris-db/word256"
 	"gopkg.in/fatih/set.v0"
 )
 
@@ -378,6 +393,8 @@ func Bytecode(bytelikes ...interface{}) []byte {
 			if int64(bytes[i]) != b {
 				panic(fmt.Sprintf("The int64 %v does not fit inside a byte", b))
 			}
+		case word256.Word256:
+			return Concat(bytes[:i], b[:], Bytecode(bytelikes[i+1:]...))
 		case []byte:
 			// splice
 			return Concat(bytes[:i], b, Bytecode(bytelikes[i+1:]...))
diff --git a/manager/eris-mint/evm/sha3/sha3.go b/manager/eris-mint/evm/sha3/sha3.go
index da6b381f40da8a51c39aeffd5ca7791d3e74dd66..6f262f217d32a3455e3c5ed220ecf969e4df560c 100644
--- a/manager/eris-mint/evm/sha3/sha3.go
+++ b/manager/eris-mint/evm/sha3/sha3.go
@@ -2,6 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+package sha3
+
 // Package sha3 implements the SHA3 hash algorithm (formerly called Keccak) chosen by NIST in 2012.
 // This file provides a SHA3 implementation which implements the standard hash.Hash interface.
 // Writing input data, including padding, and reading output data are computed in this file.
@@ -9,7 +11,6 @@
 // This is a consequence of the hash interface in which a buffer of bytes is passed in.
 // The internals of the Keccak-f function are computed in keccakf.go.
 // For the detailed specification, refer to the Keccak web site (http://keccak.noekeon.org/).
-package sha3
 
 import (
 	"encoding/binary"
diff --git a/manager/eris-mint/evm/snative.go b/manager/eris-mint/evm/snative.go
index b0a7385e3f96b005f6cf008dd36b22cb5f836449..b30858109c1356304b1d46394969c4f82df2479c 100644
--- a/manager/eris-mint/evm/snative.go
+++ b/manager/eris-mint/evm/snative.go
@@ -1,98 +1,347 @@
+// 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 vm
 
 import (
-	"encoding/hex"
 	"fmt"
 
+	"github.com/eris-ltd/eris-db/common/sanity"
+	"github.com/eris-ltd/eris-db/manager/eris-mint/evm/sha3"
 	ptypes "github.com/eris-ltd/eris-db/permission/types"
-	. "github.com/tendermint/go-common"
+	. "github.com/eris-ltd/eris-db/word256"
+
+	"strings"
+
+	"github.com/eris-ltd/eris-db/manager/eris-mint/evm/abi"
 )
 
-//------------------------------------------------------------------------------------------------
-// Registered SNative contracts
+//
+// SNative (from 'secure natives') are native (go) contracts that are dispatched
+// based on account permissions and can access and modify an account's permissions
+//
+
+// Metadata for SNative contract. Acts as a call target from the EVM. Can be
+// used to generate bindings in a smart contract languages.
+type SNativeContractDescription struct {
+	// Comment describing purpose of SNative contract and reason for assembling
+	// the particular functions
+	Comment string
+	// Name of the SNative contract
+	Name          string
+	functionsByID map[abi.FunctionSelector]*SNativeFunctionDescription
+	functions     []*SNativeFunctionDescription
+}
 
-var PermissionsContract = "permissions_contract"
+// Metadata for SNative functions. Act as call targets for the EVM when
+// collected into an SNativeContractDescription. Can be used to generate
+// bindings in a smart contract languages.
+type SNativeFunctionDescription struct {
+	// Comment describing function's purpose, parameters, and return value
+	Comment string
+	// Function name (used to form signature)
+	Name string
+	// Function arguments (used to form signature)
+	Args []abi.Arg
+	// Function return value
+	Return abi.Return
+	// Permissions required to call function
+	PermFlag ptypes.PermFlag
+	// Native function to which calls will be dispatched when a containing
+	// contract is called with a FunctionSelector matching this NativeContract
+	F NativeContract
+}
 
 func registerSNativeContracts() {
-	registeredNativeContracts[LeftPadWord256([]byte(PermissionsContract))] = permissionsContract
-
-	/*
-		// we could expose these but we moved permission and args checks into the permissionsContract
-		// so calling them would be unsafe ...
-		registeredNativeContracts[LeftPadWord256([]byte("has_base"))] = has_base
-		registeredNativeContracts[LeftPadWord256([]byte("set_base"))] = set_base
-		registeredNativeContracts[LeftPadWord256([]byte("unset_base"))] = unset_base
-		registeredNativeContracts[LeftPadWord256([]byte("set_global"))] = set_global
-		registeredNativeContracts[LeftPadWord256([]byte("has_role"))] = has_role
-		registeredNativeContracts[LeftPadWord256([]byte("add_role"))] = add_role
-		registeredNativeContracts[LeftPadWord256([]byte("rm_role"))] = rm_role
-	*/
-}
-
-//-----------------------------------------------------------------------------
-// snative are native contracts that can access and modify an account's permissions
-
-type SNativeFuncDescription struct {
-	Name     string
-	NArgs    int
-	PermFlag ptypes.PermFlag
-	F        NativeContract
-}
-
-/* The solidity interface used to generate the abi function ids below
-contract Permissions {
-	function has_base(address addr, int permFlag) constant returns (bool value) {}
-	function set_base(address addr, int permFlag, bool value) constant returns (bool val) {}
-	function unset_base(address addr, int permFlag) constant returns (int pf) {}
-	function set_global(address addr, int permFlag, bool value) constant returns (int pf) {}
-	function has_role(address addr, string role) constant returns (bool val) {}
-	function add_role(address addr, string role) constant returns (bool added) {}
-	function rm_role(address addr, string role) constant returns (bool removed) {}
-}
-*/
-
-// function identifiers from the solidity abi
-var PermsMap = map[string]SNativeFuncDescription{
-	"e8145855": SNativeFuncDescription{"has_role", 2, ptypes.HasRole, has_role},
-	"180d26f2": SNativeFuncDescription{"unset_base", 2, ptypes.UnsetBase, unset_base},
-	"3a3fcc59": SNativeFuncDescription{"set_global", 2, ptypes.SetGlobal, set_global},
-	"3fbf7da5": SNativeFuncDescription{"add_role", 2, ptypes.AddRole, add_role},
-	"9ea53314": SNativeFuncDescription{"set_base", 3, ptypes.SetBase, set_base},
-	"bb37737a": SNativeFuncDescription{"has_base", 2, ptypes.HasBase, has_base},
-	"28fd0194": SNativeFuncDescription{"rm_role", 2, ptypes.RmRole, rm_role},
-}
-
-func permissionsContract(appState AppState, caller *Account, args []byte, gas *int64) (output []byte, err error) {
-	if len(args) < 4 {
-		return nil, fmt.Errorf("permissionsContract expects at least a 4-byte function identifier")
-	}
-
-	// map solidity abi function id to snative
-	funcIDbytes := args[:4]
-	args = args[4:]
-	funcID := hex.EncodeToString(funcIDbytes)
-	d, ok := PermsMap[funcID]
-	if !ok {
-		return nil, fmt.Errorf("unknown permissionsContract funcID %s", funcID)
+	for _, contract := range SNativeContracts() {
+		registeredNativeContracts[contract.AddressWord256()] = contract.Dispatch
+	}
+}
+
+// Returns a map of all SNative contracts defined indexed by name
+func SNativeContracts() map[string]*SNativeContractDescription {
+	permFlagTypeName := abi.Uint64TypeName
+	roleTypeName := abi.Bytes32TypeName
+	contracts := []*SNativeContractDescription{
+		NewSNativeContract(`
+		* Interface for managing Secure Native authorizations.
+		* @dev This interface describes the functions exposed by the SNative permissions layer in the Monax blockchain (ErisDB).
+		`,
+			"Permissions",
+			&SNativeFunctionDescription{`
+			* @notice Adds a role to an account
+			* @param _account account address
+			* @param _role role name
+			* @return result whether role was added
+			`,
+				"addRole",
+				[]abi.Arg{
+					arg("_account", abi.AddressTypeName),
+					arg("_role", roleTypeName),
+				},
+				ret("result", abi.BoolTypeName),
+				ptypes.AddRole,
+				addRole},
+
+			&SNativeFunctionDescription{`
+			* @notice Removes a role from an account
+			* @param _account account address
+			* @param _role role name
+			* @return result whether role was removed
+			`,
+				"removeRole",
+				[]abi.Arg{
+					arg("_account", abi.AddressTypeName),
+					arg("_role", roleTypeName),
+				},
+				ret("result", abi.BoolTypeName),
+				ptypes.RmRole,
+				removeRole},
+
+			&SNativeFunctionDescription{`
+			* @notice Indicates whether an account has a role
+			* @param _account account address
+			* @param _role role name
+			* @return result whether account has role
+			`,
+				"hasRole",
+				[]abi.Arg{
+					arg("_account", abi.AddressTypeName),
+					arg("_role", roleTypeName),
+				},
+				ret("result", abi.BoolTypeName),
+				ptypes.HasRole,
+				hasRole},
+
+			&SNativeFunctionDescription{`
+			* @notice Sets the permission flags for an account. Makes them explicitly set (on or off).
+			* @param _account account address
+			* @param _permission the base permissions flags to set for the account
+			* @param _set whether to set or unset the permissions flags at the account level
+			* @return result the effective permissions flags on the account after the call
+			`,
+				"setBase",
+				[]abi.Arg{
+					arg("_account", abi.AddressTypeName),
+					arg("_permission", permFlagTypeName),
+					arg("_set", abi.BoolTypeName),
+				},
+				ret("result", permFlagTypeName),
+				ptypes.SetBase,
+				setBase},
+
+			&SNativeFunctionDescription{`
+			* @notice Unsets the permissions flags for an account. Causes permissions being unset to fall through to global permissions.
+      * @param _account account address
+      * @param _permission the permissions flags to unset for the account
+			* @return result the effective permissions flags on the account after the call
+      `,
+				"unsetBase",
+				[]abi.Arg{
+					arg("_account", abi.AddressTypeName),
+					arg("_permission", permFlagTypeName)},
+				ret("result", permFlagTypeName),
+				ptypes.UnsetBase,
+				unsetBase},
+
+			&SNativeFunctionDescription{`
+			* @notice Indicates whether an account has a subset of permissions set
+			* @param _account account address
+			* @param _permission the permissions flags (mask) to check whether enabled against base permissions for the account
+			* @return result whether account has the passed permissions flags set
+			`,
+				"hasBase",
+				[]abi.Arg{
+					arg("_account", abi.AddressTypeName),
+					arg("_permission", permFlagTypeName)},
+				ret("result", permFlagTypeName),
+				ptypes.HasBase,
+				hasBase},
+
+			&SNativeFunctionDescription{`
+			* @notice Sets the global (default) permissions flags for the entire chain
+			* @param _permission the permissions flags to set
+			* @param _set whether to set (or unset) the permissions flags
+			* @return result the global permissions flags after the call
+			`,
+				"setGlobal",
+				[]abi.Arg{
+					arg("_permission", permFlagTypeName),
+					arg("_set", abi.BoolTypeName)},
+				ret("result", permFlagTypeName),
+				ptypes.SetGlobal,
+				setGlobal},
+		),
 	}
 
+	contractMap := make(map[string]*SNativeContractDescription, len(contracts))
+	for _, contract := range contracts {
+		if _, ok := contractMap[contract.Name]; ok {
+			// If this happens we have a pseudo compile time error that will be caught
+			// on native.go init()
+			panic(fmt.Errorf("Duplicate contract with name %s defined. "+
+				"Contract names must be unique.", contract.Name))
+		}
+		contractMap[contract.Name] = contract
+	}
+	return contractMap
+}
+
+// Create a new SNative contract description object by passing a comment, name
+// and a list of member functions descriptions
+func NewSNativeContract(comment, name string,
+	functions ...*SNativeFunctionDescription) *SNativeContractDescription {
+
+	functionsByID := make(map[abi.FunctionSelector]*SNativeFunctionDescription, len(functions))
+	for _, f := range functions {
+		fid := f.ID()
+		otherF, ok := functionsByID[fid]
+		if ok {
+			panic(fmt.Errorf("Function with ID %x already defined: %s", fid,
+				otherF))
+		}
+		functionsByID[fid] = f
+	}
+	return &SNativeContractDescription{
+		Comment:       comment,
+		Name:          name,
+		functionsByID: functionsByID,
+		functions:     functions,
+	}
+}
+
+// This function is designed to be called from the EVM once a SNative contract
+// has been selected. It is also placed in a registry by registerSNativeContracts
+// So it can be looked up by SNative address
+func (contract *SNativeContractDescription) Dispatch(appState AppState,
+	caller *Account, args []byte, gas *int64) (output []byte, err error) {
+	if len(args) < abi.FunctionSelectorLength {
+		return nil, fmt.Errorf("SNatives dispatch requires a 4-byte function "+
+			"identifier but arguments are only %s bytes long", len(args))
+	}
+
+	function, err := contract.FunctionByID(firstFourBytes(args))
+	if err != nil {
+		return nil, err
+	}
+
+	remainingArgs := args[abi.FunctionSelectorLength:]
+
 	// check if we have permission to call this function
-	if !HasPermission(appState, caller, d.PermFlag) {
-		return nil, ErrInvalidPermission{caller.Address, d.Name}
+	if !HasPermission(appState, caller, function.PermFlag) {
+		return nil, ErrInvalidPermission{caller.Address, function.Name}
 	}
 
 	// ensure there are enough arguments
-	if len(args) != d.NArgs*32 {
-		return nil, fmt.Errorf("%s() takes %d arguments", d.Name)
+	if len(remainingArgs) != function.NArgs()*Word256Length {
+		return nil, fmt.Errorf("%s() takes %d arguments", function.Name,
+			function.NArgs())
 	}
 
 	// call the function
-	return d.F(appState, caller, args, gas)
+	return function.F(appState, caller, remainingArgs, gas)
 }
 
-// TODO: catch errors, log em, return 0s to the vm (should some errors cause exceptions though?)
+// We define the address of an SNative contact as the last 20 bytes of the sha3
+// hash of its name
+func (contract *SNativeContractDescription) Address() abi.Address {
+	var address abi.Address
+	hash := sha3.Sha3([]byte(contract.Name))
+	copy(address[:], hash[len(hash)-abi.AddressLength:])
+	return address
+}
+
+// Get address as a byte slice
+func (contract *SNativeContractDescription) AddressBytes() []byte {
+	address := contract.Address()
+	return address[:]
+}
 
-func has_base(appState AppState, caller *Account, args []byte, gas *int64) (output []byte, err error) {
+// Get address as a left-padded Word256
+func (contract *SNativeContractDescription) AddressWord256() Word256 {
+	return LeftPadWord256(contract.AddressBytes())
+}
+
+// Get function by calling identifier FunctionSelector
+func (contract *SNativeContractDescription) FunctionByID(id abi.FunctionSelector) (*SNativeFunctionDescription, error) {
+	f, ok := contract.functionsByID[id]
+	if !ok {
+		return nil,
+			fmt.Errorf("Unknown SNative function with ID %x", id)
+	}
+	return f, nil
+}
+
+// Get function by name
+func (contract *SNativeContractDescription) FunctionByName(name string) (*SNativeFunctionDescription, error) {
+	for _, f := range contract.functions {
+		if f.Name == name {
+			return f, nil
+		}
+	}
+	return nil, fmt.Errorf("Unknown SNative function with name %s", name)
+}
+
+// Get functions in order of declaration
+func (contract *SNativeContractDescription) Functions() []*SNativeFunctionDescription {
+	functions := make([]*SNativeFunctionDescription, len(contract.functions))
+	copy(functions, contract.functions)
+	return functions
+}
+
+//
+// SNative functions
+//
+
+// Get function signature
+func (function *SNativeFunctionDescription) Signature() string {
+	argTypeNames := make([]string, len(function.Args))
+	for i, arg := range function.Args {
+		argTypeNames[i] = string(arg.TypeName)
+	}
+	return fmt.Sprintf("%s(%s)", function.Name,
+		strings.Join(argTypeNames, ","))
+}
+
+// Get function calling identifier FunctionSelector
+func (function *SNativeFunctionDescription) ID() abi.FunctionSelector {
+	return firstFourBytes(sha3.Sha3([]byte(function.Signature())))
+}
+
+// Get number of function arguments
+func (function *SNativeFunctionDescription) NArgs() int {
+	return len(function.Args)
+}
+
+func arg(name string, abiTypeName abi.TypeName) abi.Arg {
+	return abi.Arg{
+		Name:     name,
+		TypeName: abiTypeName,
+	}
+}
+
+func ret(name string, abiTypeName abi.TypeName) abi.Return {
+	return abi.Return{
+		Name:     name,
+		TypeName: abiTypeName,
+	}
+}
+
+// Permission function defintions
+
+// TODO: catch errors, log em, return 0s to the vm (should some errors cause exceptions though?)
+func hasBase(appState AppState, caller *Account, args []byte, gas *int64) (output []byte, err error) {
 	addr, permNum := returnTwoArgs(args)
 	vmAcc := appState.GetAccount(addr)
 	if vmAcc == nil {
@@ -107,8 +356,8 @@ func has_base(appState AppState, caller *Account, args []byte, gas *int64) (outp
 	return LeftPadWord256([]byte{permInt}).Bytes(), nil
 }
 
-func set_base(appState AppState, caller *Account, args []byte, gas *int64) (output []byte, err error) {
-	addr, permNum, perm := returnThreeArgs(args)
+func setBase(appState AppState, caller *Account, args []byte, gas *int64) (output []byte, err error) {
+	addr, permNum, permVal := returnThreeArgs(args)
 	vmAcc := appState.GetAccount(addr)
 	if vmAcc == nil {
 		return nil, fmt.Errorf("Unknown account %X", addr)
@@ -117,16 +366,16 @@ func set_base(appState AppState, caller *Account, args []byte, gas *int64) (outp
 	if !ValidPermN(permN) {
 		return nil, ptypes.ErrInvalidPermission(permN)
 	}
-	permV := !perm.IsZero()
+	permV := !permVal.IsZero()
 	if err = vmAcc.Permissions.Base.Set(permN, permV); err != nil {
 		return nil, err
 	}
 	appState.UpdateAccount(vmAcc)
 	dbg.Printf("snative.setBasePerm(0x%X, %b, %v)\n", addr.Postfix(20), permN, permV)
-	return perm.Bytes(), nil
+	return effectivePermBytes(vmAcc.Permissions.Base, globalPerms(appState)), nil
 }
 
-func unset_base(appState AppState, caller *Account, args []byte, gas *int64) (output []byte, err error) {
+func unsetBase(appState AppState, caller *Account, args []byte, gas *int64) (output []byte, err error) {
 	addr, permNum := returnTwoArgs(args)
 	vmAcc := appState.GetAccount(addr)
 	if vmAcc == nil {
@@ -141,29 +390,29 @@ func unset_base(appState AppState, caller *Account, args []byte, gas *int64) (ou
 	}
 	appState.UpdateAccount(vmAcc)
 	dbg.Printf("snative.unsetBasePerm(0x%X, %b)\n", addr.Postfix(20), permN)
-	return permNum.Bytes(), nil
+	return effectivePermBytes(vmAcc.Permissions.Base, globalPerms(appState)), nil
 }
 
-func set_global(appState AppState, caller *Account, args []byte, gas *int64) (output []byte, err error) {
-	permNum, perm := returnTwoArgs(args)
+func setGlobal(appState AppState, caller *Account, args []byte, gas *int64) (output []byte, err error) {
+	permNum, permVal := returnTwoArgs(args)
 	vmAcc := appState.GetAccount(ptypes.GlobalPermissionsAddress256)
 	if vmAcc == nil {
-		PanicSanity("cant find the global permissions account")
+		sanity.PanicSanity("cant find the global permissions account")
 	}
 	permN := ptypes.PermFlag(Uint64FromWord256(permNum))
 	if !ValidPermN(permN) {
 		return nil, ptypes.ErrInvalidPermission(permN)
 	}
-	permV := !perm.IsZero()
+	permV := !permVal.IsZero()
 	if err = vmAcc.Permissions.Base.Set(permN, permV); err != nil {
 		return nil, err
 	}
 	appState.UpdateAccount(vmAcc)
 	dbg.Printf("snative.setGlobalPerm(%b, %v)\n", permN, permV)
-	return perm.Bytes(), nil
+	return permBytes(vmAcc.Permissions.Base.ResultantPerms()), nil
 }
 
-func has_role(appState AppState, caller *Account, args []byte, gas *int64) (output []byte, err error) {
+func hasRole(appState AppState, caller *Account, args []byte, gas *int64) (output []byte, err error) {
 	addr, role := returnTwoArgs(args)
 	vmAcc := appState.GetAccount(addr)
 	if vmAcc == nil {
@@ -175,7 +424,7 @@ func has_role(appState AppState, caller *Account, args []byte, gas *int64) (outp
 	return LeftPadWord256([]byte{permInt}).Bytes(), nil
 }
 
-func add_role(appState AppState, caller *Account, args []byte, gas *int64) (output []byte, err error) {
+func addRole(appState AppState, caller *Account, args []byte, gas *int64) (output []byte, err error) {
 	addr, role := returnTwoArgs(args)
 	vmAcc := appState.GetAccount(addr)
 	if vmAcc == nil {
@@ -188,7 +437,7 @@ func add_role(appState AppState, caller *Account, args []byte, gas *int64) (outp
 	return LeftPadWord256([]byte{permInt}).Bytes(), nil
 }
 
-func rm_role(appState AppState, caller *Account, args []byte, gas *int64) (output []byte, err error) {
+func removeRole(appState AppState, caller *Account, args []byte, gas *int64) (output []byte, err error) {
 	addr, role := returnTwoArgs(args)
 	vmAcc := appState.GetAccount(addr)
 	if vmAcc == nil {
@@ -221,6 +470,26 @@ func ValidPermN(n ptypes.PermFlag) bool {
 	return true
 }
 
+// Get the global BasePermissions
+func globalPerms(appState AppState) ptypes.BasePermissions {
+	vmAcc := appState.GetAccount(ptypes.GlobalPermissionsAddress256)
+	if vmAcc == nil {
+		sanity.PanicSanity("cant find the global permissions account")
+	}
+	return vmAcc.Permissions.Base
+}
+
+// Compute the effective permissions from an Account's BasePermissions by
+// taking the bitwise or with the global BasePermissions resultant permissions
+func effectivePermBytes(basePerms ptypes.BasePermissions,
+	globalPerms ptypes.BasePermissions) []byte {
+	return permBytes(basePerms.ResultantPerms() | globalPerms.ResultantPerms())
+}
+
+func permBytes(basePerms ptypes.PermFlag) []byte {
+	return Uint64ToWord256(uint64(basePerms)).Bytes()
+}
+
 // CONTRACT: length has already been checked
 func returnTwoArgs(args []byte) (a Word256, b Word256) {
 	copy(a[:], args[:32])
@@ -242,3 +511,9 @@ func byteFromBool(b bool) byte {
 	}
 	return 0x0
 }
+
+func firstFourBytes(byteSlice []byte) [4]byte {
+	var bs [4]byte
+	copy(bs[:], byteSlice[:4])
+	return bs
+}
diff --git a/manager/eris-mint/evm/snative_test.go b/manager/eris-mint/evm/snative_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..a60b62e15678596380769eb8880681517782102f
--- /dev/null
+++ b/manager/eris-mint/evm/snative_test.go
@@ -0,0 +1,157 @@
+// 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 vm
+
+import (
+	"encoding/hex"
+	"testing"
+
+	"strings"
+
+	"github.com/eris-ltd/eris-db/manager/eris-mint/evm/abi"
+	. "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/word256"
+	"github.com/stretchr/testify/assert"
+)
+
+// Compiling the Permissions solidity contract at
+// (generated by with 'make snatives' function) and passing to
+// https://ethereum.github.io/browser-solidity (toggle details to get list)
+// yields:
+// Keep this updated to drive TestPermissionsContractSignatures
+const compiledSigs = `
+a73f7f8a addRole(address,bytes32)
+225b6574 hasBase(address,uint64)
+ac4ab3fb hasRole(address,bytes32)
+6853920e removeRole(address,bytes32)
+dbd4a8ea setBase(address,uint64,bool)
+c4bc7b70 setGlobal(uint64,bool)
+b7d4dc0d unsetBase(address,uint64)
+`
+
+func TestPermissionsContractSignatures(t *testing.T) {
+	contract := SNativeContracts()["Permissions"]
+
+	nFuncs := len(contract.functions)
+
+	sigMap := idToSignatureMap()
+
+	assert.Len(t, sigMap, nFuncs,
+		"Permissions contract defines %s functions so we need %s "+
+			"signatures in compiledSigs",
+		nFuncs, nFuncs)
+
+	for funcID, signature := range sigMap {
+		assertFunctionIDSignature(t, contract, funcID, signature)
+	}
+}
+
+func TestSNativeContractDescription_Dispatch(t *testing.T) {
+	contract := SNativeContracts()["Permissions"]
+	state := newAppState()
+	caller := &Account{
+		Address: addr(1, 1, 1),
+	}
+	grantee := &Account{
+		Address: addr(2, 2, 2),
+	}
+	state.UpdateAccount(grantee)
+
+	function, err := contract.FunctionByName("addRole")
+	if err != nil {
+		t.Fatalf("Could not get function: %s", err)
+	}
+	funcID := function.ID()
+	gas := int64(1000)
+
+	// Should fail since we have no permissions
+	retValue, err := contract.Dispatch(state, caller, Bytecode(funcID[:],
+		grantee.Address, permFlagToWord256(ptypes.CreateAccount)), &gas)
+	assert.Error(t, err)
+	if err != nil {
+		assert.Contains(t, err.Error(), "does not have permission")
+	}
+
+	// Grant all permissions and dispatch should success
+	caller.Permissions = allAccountPermissions()
+	retValue, err = contract.Dispatch(state, caller, Bytecode(funcID[:],
+		grantee.Address, permFlagToWord256(ptypes.CreateAccount)), &gas)
+	assert.NoError(t, err)
+	assert.Equal(t, retValue, LeftPadBytes([]byte{1}, 32))
+}
+
+func TestSNativeContractDescription_Address(t *testing.T) {
+	contract := NewSNativeContract("A comment",
+		"CoolButVeryLongNamedContractOfDoom")
+	assert.Equal(t, sha3.Sha3(([]byte)(contract.Name))[12:], contract.AddressBytes())
+}
+
+//
+// Helpers
+//
+func assertFunctionIDSignature(t *testing.T, contract *SNativeContractDescription,
+	funcIDHex string, expectedSignature string) {
+	function, err := contract.FunctionByID(funcIDFromHex(t, funcIDHex))
+	assert.NoError(t, err,
+		"Error retrieving SNativeFunctionDescription with ID %s", funcIDHex)
+	if err == nil {
+		assert.Equal(t, expectedSignature, function.Signature())
+	}
+}
+
+func funcIDFromHex(t *testing.T, hexString string) abi.FunctionSelector {
+	bs, err := hex.DecodeString(hexString)
+	assert.NoError(t, err, "Could not decode hex string '%s'", hexString)
+	if len(bs) != 4 {
+		t.Fatalf("FunctionSelector must be 4 bytes but '%s' is %v bytes", hexString,
+			len(bs))
+	}
+	return firstFourBytes(bs)
+}
+
+func permFlagToWord256(permFlag ptypes.PermFlag) Word256 {
+	return Uint64ToWord256(uint64(permFlag))
+}
+
+func addr(rightBytes ...uint8) Word256 {
+	return LeftPadWord256(rightBytes)
+}
+
+func allAccountPermissions() ptypes.AccountPermissions {
+	return ptypes.AccountPermissions{
+		Base: ptypes.BasePermissions{
+			Perms:  ptypes.AllPermFlags,
+			SetBit: ptypes.AllPermFlags,
+		},
+		Roles: []string{},
+	}
+}
+
+// turns the solidity compiler function summary into a map to drive signature
+// test
+func idToSignatureMap() map[string]string {
+	sigMap := make(map[string]string)
+	lines := strings.Split(compiledSigs, "\n")
+	for _, line := range lines {
+		trimmed := strings.Trim(line, " \t")
+		if trimmed != "" {
+			idSig := strings.Split(trimmed, " ")
+			sigMap[idSig[0]] = idSig[1]
+		}
+	}
+	return sigMap
+}
diff --git a/manager/eris-mint/evm/stack.go b/manager/eris-mint/evm/stack.go
index 3f3d727f1fb8e78eb63226ecd952e2f9981ff3f9..8e5df4327810c1a6d4cbf123484cdf0b47aa226f 100644
--- a/manager/eris-mint/evm/stack.go
+++ b/manager/eris-mint/evm/stack.go
@@ -1,9 +1,25 @@
+// 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 vm
 
 import (
 	"fmt"
 
-	. "github.com/tendermint/go-common"
+	"github.com/eris-ltd/eris-db/common/math/integral"
+	"github.com/eris-ltd/eris-db/common/sanity"
+	. "github.com/eris-ltd/eris-db/word256"
 )
 
 // Not goroutine safe
@@ -51,7 +67,7 @@ func (st *Stack) Push(d Word256) {
 // currently only called after Sha3
 func (st *Stack) PushBytes(bz []byte) {
 	if len(bz) != 32 {
-		PanicSanity("Invalid bytes size: expected 32")
+		sanity.PanicSanity("Invalid bytes size: expected 32")
 	}
 	st.Push(LeftPadWord256(bz))
 }
@@ -115,7 +131,7 @@ func (st *Stack) Peek() Word256 {
 func (st *Stack) Print(n int) {
 	fmt.Println("### stack ###")
 	if st.ptr > 0 {
-		nn := MinInt(n, st.ptr)
+		nn := integral.MinInt(n, st.ptr)
 		for j, i := 0, st.ptr-1; i > st.ptr-1-nn; i-- {
 			fmt.Printf("%-3d  %X\n", j, st.data[i])
 			j += 1
diff --git a/manager/eris-mint/evm/types.go b/manager/eris-mint/evm/types.go
index a886546e31f8148f7c2c20511e80cfec69b76714..cd5d8ce04b3baa011ad58536a54e25da00cb55ff 100644
--- a/manager/eris-mint/evm/types.go
+++ b/manager/eris-mint/evm/types.go
@@ -1,8 +1,24 @@
+// 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 vm
 
 import (
+	"fmt"
+
 	ptypes "github.com/eris-ltd/eris-db/permission/types"
-	. "github.com/tendermint/go-common"
+	. "github.com/eris-ltd/eris-db/word256"
 )
 
 const (
@@ -23,7 +39,7 @@ func (acc *Account) String() string {
 	if acc == nil {
 		return "nil-VMAccount"
 	}
-	return Fmt("VMAccount{%X B:%v C:%X N:%v}",
+	return fmt.Sprintf("VMAccount{%X B:%v C:%X N:%v}",
 		acc.Address, acc.Balance, acc.Code, acc.Nonce)
 }
 
diff --git a/manager/eris-mint/evm/vm.go b/manager/eris-mint/evm/vm.go
index 32b7b4fab89958a3f66cbe19d2ee19b2dfa8e7dd..ea883a63224b0e2dad3a788d2b752db842a7fdab 100644
--- a/manager/eris-mint/evm/vm.go
+++ b/manager/eris-mint/evm/vm.go
@@ -1,3 +1,17 @@
+// 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 vm
 
 import (
@@ -6,27 +20,31 @@ import (
 	"fmt"
 	"math/big"
 
+	"github.com/eris-ltd/eris-db/common/math/integral"
+	"github.com/eris-ltd/eris-db/common/sanity"
 	. "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"
-	. "github.com/tendermint/go-common"
+	. "github.com/eris-ltd/eris-db/word256"
+
 	"github.com/tendermint/go-events"
 )
 
 var (
-	ErrUnknownAddress      = errors.New("Unknown address")
-	ErrInsufficientBalance = errors.New("Insufficient balance")
-	ErrInvalidJumpDest     = errors.New("Invalid jump dest")
-	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")
-	ErrCallStackOverflow   = errors.New("Call stack overflow")
-	ErrCallStackUnderflow  = errors.New("Call stack underflow")
-	ErrDataStackOverflow   = errors.New("Data stack overflow")
-	ErrDataStackUnderflow  = errors.New("Data stack underflow")
-	ErrInvalidContract     = errors.New("Invalid contract")
+	ErrUnknownAddress         = errors.New("Unknown address")
+	ErrInsufficientBalance    = errors.New("Insufficient balance")
+	ErrInvalidJumpDest        = errors.New("Invalid jump dest")
+	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")
+	ErrCallStackOverflow      = errors.New("Call stack overflow")
+	ErrCallStackUnderflow     = errors.New("Call stack underflow")
+	ErrDataStackOverflow      = errors.New("Data stack overflow")
+	ErrDataStackUnderflow     = errors.New("Data stack underflow")
+	ErrInvalidContract        = errors.New("Invalid contract")
+	ErrNativeContractCodeCopy = errors.New("Tried to copy native contract code")
 )
 
 type ErrPermission struct {
@@ -93,7 +111,7 @@ func HasPermission(appState AppState, acc *Account, perm ptypes.PermFlag) bool {
 	v, err := acc.Permissions.Base.Get(perm)
 	if _, ok := err.(ptypes.ErrValueNotSet); ok {
 		if appState == nil {
-			log.Warn(Fmt("\n\n***** Unknown permission %b! ********\n\n", perm))
+			log.Warn(fmt.Sprintf("\n\n***** Unknown permission %b! ********\n\n", perm))
 			return false
 		}
 		return HasPermission(nil, appState.GetAccount(ptypes.GlobalPermissionsAddress256), perm)
@@ -140,7 +158,7 @@ func (vm *VM) Call(caller, callee *Account, code, input []byte, value int64, gas
 			err := transfer(callee, caller, value)
 			if err != nil {
 				// data has been corrupted in ram
-				PanicCrisis("Could not return value to caller")
+				sanity.PanicCrisis("Could not return value to caller")
 			}
 		}
 	}
@@ -567,13 +585,17 @@ func (vm *VM) call(caller, callee *Account, code, input []byte, value int64, gas
 			}
 			acc := vm.appState.GetAccount(addr)
 			if acc == nil {
-				return nil, firstErr(err, ErrUnknownAddress)
+				if _, ok := registeredNativeContracts[addr]; !ok {
+					return nil, firstErr(err, ErrUnknownAddress)
+				}
+				dbg.Printf(" => returning code size of 1 to indicated existence of native contract at %X\n", addr)
+				stack.Push(One256)
+			} else {
+				code := acc.Code
+				l := int64(len(code))
+				stack.Push64(l)
+				dbg.Printf(" => %d\n", l)
 			}
-			code := acc.Code
-			l := int64(len(code))
-			stack.Push64(l)
-			dbg.Printf(" => %d\n", l)
-
 		case EXTCODECOPY: // 0x3C
 			addr := stack.Pop()
 			if useGasNegative(gas, GasGetAccount, &err) {
@@ -581,6 +603,10 @@ func (vm *VM) call(caller, callee *Account, code, input []byte, value int64, gas
 			}
 			acc := vm.appState.GetAccount(addr)
 			if acc == nil {
+				if _, ok := registeredNativeContracts[addr]; ok {
+					dbg.Printf(" => attempted to copy native contract at %X but this is not supported\n", addr)
+					return nil, firstErr(err, ErrNativeContractCodeCopy)
+				}
 				return nil, firstErr(err, ErrUnknownAddress)
 			}
 			code := acc.Code
@@ -931,7 +957,7 @@ func copyslice(src []byte) (dest []byte) {
 }
 
 func rightMostBytes(data []byte, n int) []byte {
-	size := MinInt(len(data), n)
+	size := integral.MinInt(len(data), n)
 	offset := len(data) - size
 	return data[offset:]
 }
diff --git a/manager/eris-mint/evm/test/vm_test.go b/manager/eris-mint/evm/vm_test.go
similarity index 94%
rename from manager/eris-mint/evm/test/vm_test.go
rename to manager/eris-mint/evm/vm_test.go
index 53895c0da1b590c7754c290ed5922b086a437010..fe85590b46299b80ca8831545e02e815c926ff7b 100644
--- a/manager/eris-mint/evm/test/vm_test.go
+++ b/manager/eris-mint/evm/vm_test.go
@@ -1,3 +1,17 @@
+// 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 vm
 
 import (
@@ -10,12 +24,11 @@ import (
 
 	"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/eris-ltd/eris-db/word256"
 	"github.com/stretchr/testify/assert"
-	. "github.com/tendermint/go-common"
 	"github.com/tendermint/go-events"
 )
 
diff --git a/manager/eris-mint/namereg.go b/manager/eris-mint/namereg.go
index 25d95ffad3f97d19b654e8917c2e45a47900087d..cfc589eba271a126e46e1f4b8faafc57153ed1c7 100644
--- a/manager/eris-mint/namereg.go
+++ b/manager/eris-mint/namereg.go
@@ -1,21 +1,17 @@
-// Copyright 2015, 2016 Eris Industries (UK) Ltd.
-// This file is part of Eris-RT
+// 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.
 
-// Eris-RT is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-
-// Eris-RT is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License
-// along with Eris-RT.  If not, see <http://www.gnu.org/licenses/>.
-
-// NameReg is part of the pipe for ErisMint and provides the implementation
-// for the pipe to call into the ErisMint application
 package erismint
 
 import (
@@ -30,7 +26,9 @@ import (
 	event "github.com/eris-ltd/eris-db/event"
 )
 
-// The net struct.
+// NameReg is part of the pipe for ErisMint and provides the implementation
+// for the pipe to call into the ErisMint application
+
 type namereg struct {
 	erisMint      *ErisMint
 	filterFactory *event.FilterFactory
diff --git a/manager/eris-mint/pipe.go b/manager/eris-mint/pipe.go
index dc9b64875319a7fb50c6fb6c269778f2d9272d5a..f900b3f09d07989dbe8bdc8d244b5a8e2f5966b1 100644
--- a/manager/eris-mint/pipe.go
+++ b/manager/eris-mint/pipe.go
@@ -1,18 +1,16 @@
-// Copyright 2015, 2016 Eris Industries (UK) Ltd.
-// This file is part of Eris-RT
-
-// Eris-RT is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-
-// Eris-RT is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License
-// along with Eris-RT.  If not, see <http://www.gnu.org/licenses/>.
+// 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 erismint
 
@@ -20,15 +18,12 @@ import (
 	"bytes"
 	"fmt"
 
-	tm_common "github.com/tendermint/go-common"
+	abci_types "github.com/tendermint/abci/types"
 	crypto "github.com/tendermint/go-crypto"
 	db "github.com/tendermint/go-db"
 	go_events "github.com/tendermint/go-events"
 	wire "github.com/tendermint/go-wire"
 	tm_types "github.com/tendermint/tendermint/types"
-	tmsp_types "github.com/tendermint/tmsp/types"
-
-	log "github.com/eris-ltd/eris-logger"
 
 	"github.com/eris-ltd/eris-db/account"
 	blockchain_types "github.com/eris-ltd/eris-db/blockchain/types"
@@ -38,12 +33,15 @@ import (
 	core_types "github.com/eris-ltd/eris-db/core/types"
 	"github.com/eris-ltd/eris-db/definitions"
 	edb_event "github.com/eris-ltd/eris-db/event"
+	genesis "github.com/eris-ltd/eris-db/genesis"
+	"github.com/eris-ltd/eris-db/logging"
+	"github.com/eris-ltd/eris-db/logging/loggers"
 	vm "github.com/eris-ltd/eris-db/manager/eris-mint/evm"
 	"github.com/eris-ltd/eris-db/manager/eris-mint/state"
-	state_types "github.com/eris-ltd/eris-db/manager/eris-mint/state/types"
 	manager_types "github.com/eris-ltd/eris-db/manager/types"
 	rpc_tm_types "github.com/eris-ltd/eris-db/rpc/tendermint/core/types"
 	"github.com/eris-ltd/eris-db/txs"
+	"github.com/eris-ltd/eris-db/word256"
 )
 
 type erisMintPipe struct {
@@ -57,8 +55,9 @@ type erisMintPipe struct {
 	namereg         *namereg
 	transactor      *transactor
 	// Genesis cache
-	genesisDoc   *state_types.GenesisDoc
+	genesisDoc   *genesis.GenesisDoc
 	genesisState *state.State
+	logger       loggers.InfoTraceLogger
 }
 
 // NOTE [ben] Compiler check to ensure erisMintPipe successfully implements
@@ -70,7 +69,8 @@ var _ definitions.Pipe = (*erisMintPipe)(nil)
 var _ definitions.TendermintPipe = (*erisMintPipe)(nil)
 
 func NewErisMintPipe(moduleConfig *config.ModuleConfig,
-	eventSwitch *go_events.EventSwitch) (*erisMintPipe, error) {
+	eventSwitch go_events.EventSwitch,
+	logger loggers.InfoTraceLogger) (*erisMintPipe, error) {
 
 	startedState, genesisDoc, err := startState(moduleConfig.DataDir,
 		moduleConfig.Config.GetString("db_backend"), moduleConfig.GenesisFile,
@@ -78,17 +78,17 @@ func NewErisMintPipe(moduleConfig *config.ModuleConfig,
 	if err != nil {
 		return nil, fmt.Errorf("Failed to start state: %v", err)
 	}
+	logger = logging.WithScope(logger, "ErisMintPipe")
 	// assert ChainId matches genesis ChainId
-	log.WithFields(log.Fields{
-		"chainId":         startedState.ChainID,
-		"lastBlockHeight": startedState.LastBlockHeight,
-		"lastBlockHash":   startedState.LastBlockHash,
-	}).Debug("Loaded state")
+	logging.InfoMsg(logger, "Loaded state",
+		"chainId", startedState.ChainID,
+		"lastBlockHeight", startedState.LastBlockHeight,
+		"lastBlockHash", startedState.LastBlockHash)
 	// start the application
-	erisMint := NewErisMint(startedState, eventSwitch)
+	erisMint := NewErisMint(startedState, eventSwitch, logger)
 
 	// initialise the components of the pipe
-	events := edb_event.NewEvents(eventSwitch)
+	events := edb_event.NewEvents(eventSwitch, logger)
 	accounts := newAccounts(erisMint)
 	namereg := newNameReg(erisMint)
 
@@ -108,6 +108,7 @@ func NewErisMintPipe(moduleConfig *config.ModuleConfig,
 		// authority - this is a sort of dependency injection pattern
 		consensusEngine: nil,
 		blockchain:      nil,
+		logger:          logger,
 	}
 
 	// NOTE: [Silas]
@@ -139,28 +140,28 @@ func NewErisMintPipe(moduleConfig *config.ModuleConfig,
 // If no state can be loaded, the JSON genesis file will be loaded into the
 // state database as the zero state.
 func startState(dataDir, backend, genesisFile, chainId string) (*state.State,
-	*state_types.GenesisDoc, error) {
+	*genesis.GenesisDoc, error) {
 	// avoid Tendermints PanicSanity and return a clean error
-	if backend != db.DBBackendMemDB &&
-		backend != db.DBBackendLevelDB {
+	if backend != db.MemDBBackendStr &&
+		backend != db.LevelDBBackendStr {
 		return nil, nil, fmt.Errorf("Database backend %s is not supported by %s",
 			backend, GetErisMintVersion)
 	}
 
 	stateDB := db.NewDB("erismint", backend, dataDir)
 	newState := state.LoadState(stateDB)
-	var genesisDoc *state_types.GenesisDoc
+	var genesisDoc *genesis.GenesisDoc
 	if newState == nil {
 		genesisDoc, newState = state.MakeGenesisStateFromFile(stateDB, genesisFile)
 		newState.Save()
 		buf, n, err := new(bytes.Buffer), new(int), new(error)
 		wire.WriteJSON(genesisDoc, buf, n, err)
-		stateDB.Set(state_types.GenDocKey, buf.Bytes())
+		stateDB.Set(genesis.GenDocKey, buf.Bytes())
 		if *err != nil {
 			return nil, nil, fmt.Errorf("Unable to write genesisDoc to db: %v", err)
 		}
 	} else {
-		loadedGenesisDocBytes := stateDB.Get(state_types.GenDocKey)
+		loadedGenesisDocBytes := stateDB.Get(genesis.GenDocKey)
 		err := new(error)
 		wire.ReadJSONPtr(&genesisDoc, loadedGenesisDocBytes, err)
 		if *err != nil {
@@ -168,12 +169,8 @@ func startState(dataDir, backend, genesisFile, chainId string) (*state.State,
 		}
 		// assert loaded genesis doc has the same chainId as the provided chainId
 		if genesisDoc.ChainID != chainId {
-			log.WithFields(log.Fields{
-				"chainId from loaded genesis": genesisDoc.ChainID,
-				"chainId from configuration":  chainId,
-			}).Warn("Conflicting chainIds")
-			// return nil, nil, fmt.Errorf("ChainId (%s) loaded from genesis document in existing database does not match configuration chainId (%s).",
-			// genesisDoc.ChainID, chainId)
+			return nil, nil, fmt.Errorf("ChainId (%s) loaded from genesis document in existing database does not match"+
+				" configuration chainId (%s).", genesisDoc.ChainID, chainId)
 		}
 	}
 
@@ -183,6 +180,10 @@ func startState(dataDir, backend, genesisFile, chainId string) (*state.State,
 //------------------------------------------------------------------------------
 // Implement definitions.Pipe for erisMintPipe
 
+func (pipe *erisMintPipe) Logger() loggers.InfoTraceLogger {
+	return pipe.logger
+}
+
 func (pipe *erisMintPipe) Accounts() definitions.Accounts {
 	return pipe.accounts
 }
@@ -253,11 +254,9 @@ func (pipe *erisMintPipe) Subscribe(event string,
 	subscriptionId, err := edb_event.GenerateSubId()
 	if err != nil {
 		return nil, err
+		logging.InfoMsg(pipe.logger, "Subscribing to event",
+			"event", event, "subscriptionId", subscriptionId)
 	}
-
-	log.WithFields(log.Fields{"event": event, "subscriptionId": subscriptionId}).
-		Info("Subscribing to event")
-
 	pipe.consensusAndManagerEvents().Subscribe(subscriptionId, event,
 		func(eventData txs.EventData) {
 			result := rpc_tm_types.ErisDBResult(&rpc_tm_types.ResultEvent{event,
@@ -272,8 +271,8 @@ func (pipe *erisMintPipe) Subscribe(event string,
 }
 
 func (pipe *erisMintPipe) Unsubscribe(subscriptionId string) (*rpc_tm_types.ResultUnsubscribe, error) {
-	log.WithFields(log.Fields{"subscriptionId": subscriptionId}).
-		Info("Unsubscribing from event")
+	logging.InfoMsg(pipe.logger, "Unsubscribing from event",
+		"subscriptionId", subscriptionId)
 	pipe.consensusAndManagerEvents().Unsubscribe(subscriptionId)
 	return &rpc_tm_types.ResultUnsubscribe{SubscriptionId: subscriptionId}, nil
 }
@@ -351,13 +350,8 @@ func (pipe *erisMintPipe) Genesis() (*rpc_tm_types.ResultGenesis, error) {
 func (pipe *erisMintPipe) GetAccount(address []byte) (*rpc_tm_types.ResultGetAccount,
 	error) {
 	cache := pipe.erisMint.GetCheckCache()
-	// cache := mempoolReactor.Mempool.GetCache()
 	account := cache.GetAccount(address)
-	if account == nil {
-		log.Warn("Nil Account")
-		return &rpc_tm_types.ResultGetAccount{nil}, nil
-	}
-	return &rpc_tm_types.ResultGetAccount{account}, nil
+	return &rpc_tm_types.ResultGetAccount{Account: account}, nil
 }
 
 func (pipe *erisMintPipe) ListAccounts() (*rpc_tm_types.ResultListAccounts, error) {
@@ -384,7 +378,7 @@ func (pipe *erisMintPipe) GetStorage(address, key []byte) (*rpc_tm_types.ResultG
 	storageTree := state.LoadStorage(storageRoot)
 
 	_, value, exists := storageTree.Get(
-		tm_common.LeftPadWord256(key).Bytes())
+		word256.LeftPadWord256(key).Bytes())
 	if !exists {
 		// value == nil {
 		return &rpc_tm_types.ResultGetStorage{key, nil}, nil
@@ -426,12 +420,12 @@ func (pipe *erisMintPipe) Call(fromAddress, toAddress, data []byte) (*rpc_tm_typ
 		fromAddress = []byte{}
 	}
 	callee := toVMAccount(outAcc)
-	caller := &vm.Account{Address: tm_common.LeftPadWord256(fromAddress)}
+	caller := &vm.Account{Address: word256.LeftPadWord256(fromAddress)}
 	txCache := state.NewTxCache(cache)
 	gasLimit := st.GetGasLimit()
 	params := vm.Params{
 		BlockHeight: int64(st.LastBlockHeight),
-		BlockHash:   tm_common.LeftPadWord256(st.LastBlockHash),
+		BlockHash:   word256.LeftPadWord256(st.LastBlockHash),
 		BlockTime:   st.LastBlockTime.Unix(),
 		GasLimit:    gasLimit,
 	}
@@ -452,13 +446,13 @@ func (pipe *erisMintPipe) CallCode(fromAddress, code, data []byte) (*rpc_tm_type
 	error) {
 	st := pipe.erisMint.GetState()
 	cache := pipe.erisMint.GetCheckCache()
-	callee := &vm.Account{Address: tm_common.LeftPadWord256(fromAddress)}
-	caller := &vm.Account{Address: tm_common.LeftPadWord256(fromAddress)}
+	callee := &vm.Account{Address: word256.LeftPadWord256(fromAddress)}
+	caller := &vm.Account{Address: word256.LeftPadWord256(fromAddress)}
 	txCache := state.NewTxCache(cache)
 	gasLimit := st.GetGasLimit()
 	params := vm.Params{
 		BlockHeight: int64(st.LastBlockHeight),
-		BlockHash:   tm_common.LeftPadWord256(st.LastBlockHash),
+		BlockHash:   word256.LeftPadWord256(st.LastBlockHash),
 		BlockTime:   st.LastBlockTime.Unix(),
 		GasLimit:    gasLimit,
 	}
@@ -538,7 +532,7 @@ func (pipe *erisMintPipe) ListNames() (*rpc_tm_types.ResultListNames, error) {
 }
 
 func (pipe *erisMintPipe) broadcastTx(tx txs.Tx,
-	callback func(res *tmsp_types.Response)) (*rpc_tm_types.ResultBroadcastTx, error) {
+	callback func(res *abci_types.Response)) (*rpc_tm_types.ResultBroadcastTx, error) {
 
 	txBytes, err := txs.EncodeTx(tx)
 	if err != nil {
@@ -558,9 +552,9 @@ func (pipe *erisMintPipe) BroadcastTxAsync(tx txs.Tx) (*rpc_tm_types.ResultBroad
 }
 
 func (pipe *erisMintPipe) BroadcastTxSync(tx txs.Tx) (*rpc_tm_types.ResultBroadcastTx, error) {
-	responseChannel := make(chan *tmsp_types.Response, 1)
+	responseChannel := make(chan *abci_types.Response, 1)
 	_, err := pipe.broadcastTx(tx,
-		func(res *tmsp_types.Response) {
+		func(res *abci_types.Response) {
 			responseChannel <- res
 		})
 	if err != nil {
@@ -568,7 +562,7 @@ func (pipe *erisMintPipe) BroadcastTxSync(tx txs.Tx) (*rpc_tm_types.ResultBroadc
 	}
 	// NOTE: [ben] This Response is set in /consensus/tendermint/local_client.go
 	// a call to Application, here implemented by ErisMint, over local callback,
-	// or TMSP RPC call.  Hence the result is determined by ErisMint/erismint.go
+	// or abci RPC call.  Hence the result is determined by ErisMint/erismint.go
 	// CheckTx() Result (Result converted to ReqRes into Response returned here)
 	// NOTE: [ben] BroadcastTx just calls CheckTx in Tendermint (oddly... [Silas])
 	response := <-responseChannel
@@ -582,17 +576,18 @@ func (pipe *erisMintPipe) BroadcastTxSync(tx txs.Tx) (*rpc_tm_types.ResultBroadc
 		Log:  responseCheckTx.Log,
 	}
 	switch responseCheckTx.Code {
-	case tmsp_types.CodeType_OK:
+	case abci_types.CodeType_OK:
 		return resultBroadCastTx, nil
-	case tmsp_types.CodeType_EncodingError:
+	case abci_types.CodeType_EncodingError:
 		return resultBroadCastTx, fmt.Errorf(resultBroadCastTx.Log)
-	case tmsp_types.CodeType_InternalError:
+	case abci_types.CodeType_InternalError:
 		return resultBroadCastTx, fmt.Errorf(resultBroadCastTx.Log)
 	default:
-		log.WithFields(log.Fields{
-			"application":    GetErisMintVersion().GetVersionString(),
-			"TMSP_code_type": responseCheckTx.Code,
-		}).Warn("Unknown error returned from Tendermint CheckTx on BroadcastTxSync")
+		logging.InfoMsg(pipe.logger, "Unknown error returned from Tendermint CheckTx on BroadcastTxSync",
+			"application", GetErisMintVersion().GetVersionString(),
+			"abci_code_type", responseCheckTx.Code,
+			"abci_log", responseCheckTx.Log,
+		)
 		return resultBroadCastTx, fmt.Errorf("Unknown error returned: " + responseCheckTx.Log)
 	}
 }
diff --git a/manager/eris-mint/state/block_cache.go b/manager/eris-mint/state/block_cache.go
index 31210114e07acf57ab95aab0b1ec7b996c193445..e162ce5c3b185388484e91dca2b7ae7e7916b675 100644
--- a/manager/eris-mint/state/block_cache.go
+++ b/manager/eris-mint/state/block_cache.go
@@ -1,15 +1,31 @@
+// 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 state
 
 import (
 	"bytes"
+	"fmt"
 	"sort"
 
-	. "github.com/tendermint/go-common"
-	dbm "github.com/tendermint/go-db"
-	"github.com/tendermint/go-merkle"
-
 	acm "github.com/eris-ltd/eris-db/account"
+	"github.com/eris-ltd/eris-db/common/sanity"
 	core_types "github.com/eris-ltd/eris-db/core/types"
+	. "github.com/eris-ltd/eris-db/word256"
+
+	dbm "github.com/tendermint/go-db"
+	"github.com/tendermint/go-merkle"
 )
 
 func makeStorage(db dbm.DB, root []byte) merkle.Tree {
@@ -61,7 +77,7 @@ func (cache *BlockCache) UpdateAccount(acc *acm.Account) {
 	addr := acc.Address
 	_, storage, removed, _ := cache.accounts[string(addr)].unpack()
 	if removed {
-		PanicSanity("UpdateAccount on a removed account")
+		sanity.PanicSanity("UpdateAccount on a removed account")
 	}
 	cache.accounts[string(addr)] = accountInfo{acc, storage, false, true}
 }
@@ -69,7 +85,7 @@ func (cache *BlockCache) UpdateAccount(acc *acm.Account) {
 func (cache *BlockCache) RemoveAccount(addr []byte) {
 	_, _, removed, _ := cache.accounts[string(addr)].unpack()
 	if removed {
-		PanicSanity("RemoveAccount on a removed account")
+		sanity.PanicSanity("RemoveAccount on a removed account")
 	}
 	cache.accounts[string(addr)] = accountInfo{nil, nil, true, false}
 }
@@ -88,7 +104,7 @@ func (cache *BlockCache) GetStorage(addr Word256, key Word256) (value Word256) {
 	// Get or load storage
 	acc, storage, removed, dirty := cache.accounts[string(addr.Postfix(20))].unpack()
 	if removed {
-		PanicSanity("GetStorage() on removed account")
+		sanity.PanicSanity("GetStorage() on removed account")
 	}
 	if acc != nil && storage == nil {
 		storage = makeStorage(cache.db, acc.StorageRoot)
@@ -111,7 +127,7 @@ func (cache *BlockCache) GetStorage(addr Word256, key Word256) (value Word256) {
 func (cache *BlockCache) SetStorage(addr Word256, key Word256, value Word256) {
 	_, _, removed, _ := cache.accounts[string(addr.Postfix(20))].unpack()
 	if removed {
-		PanicSanity("SetStorage() on a removed account")
+		sanity.PanicSanity("SetStorage() on a removed account")
 	}
 	cache.storages[Tuple256{addr, key}] = storageInfo{value, true}
 }
@@ -141,7 +157,7 @@ func (cache *BlockCache) UpdateNameRegEntry(entry *core_types.NameRegEntry) {
 func (cache *BlockCache) RemoveNameRegEntry(name string) {
 	_, removed, _ := cache.names[name].unpack()
 	if removed {
-		PanicSanity("RemoveNameRegEntry on a removed entry")
+		sanity.PanicSanity("RemoveNameRegEntry on a removed entry")
 	}
 	cache.names[name] = nameInfo{nil, true, false}
 }
@@ -208,7 +224,7 @@ func (cache *BlockCache) Sync() {
 		if removed {
 			removed := cache.backend.RemoveAccount([]byte(addrStr))
 			if !removed {
-				PanicCrisis(Fmt("Could not remove account to be removed: %X", acc.Address))
+				sanity.PanicCrisis(fmt.Sprintf("Could not remove account to be removed: %X", acc.Address))
 			}
 		} else {
 			if acc == nil {
@@ -241,7 +257,7 @@ func (cache *BlockCache) Sync() {
 		if removed {
 			removed := cache.backend.RemoveNameRegEntry(nameStr)
 			if !removed {
-				PanicCrisis(Fmt("Could not remove namereg entry to be removed: %s", nameStr))
+				sanity.PanicCrisis(fmt.Sprintf("Could not remove namereg entry to be removed: %s", nameStr))
 			}
 		} else {
 			if entry == nil {
diff --git a/manager/eris-mint/state/common.go b/manager/eris-mint/state/common.go
index 78315627205b958179113970622090efb85b3c26..4f096d804e6808def4a1e14e97ae8f87b39fb3e3 100644
--- a/manager/eris-mint/state/common.go
+++ b/manager/eris-mint/state/common.go
@@ -1,9 +1,23 @@
+// 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 state
 
 import (
 	acm "github.com/eris-ltd/eris-db/account"
 	"github.com/eris-ltd/eris-db/manager/eris-mint/evm"
-	. "github.com/tendermint/go-common"
+	. "github.com/eris-ltd/eris-db/word256"
 )
 
 type AccountGetter interface {
diff --git a/manager/eris-mint/state/execution.go b/manager/eris-mint/state/execution.go
index ceefbbd8368a2491e1a743f87b823fd40558935e..80b5474f5868cd0493bb8f639730dfb3df6d11c5 100644
--- a/manager/eris-mint/state/execution.go
+++ b/manager/eris-mint/state/execution.go
@@ -1,3 +1,17 @@
+// 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 state
 
 import (
@@ -5,15 +19,15 @@ import (
 	"errors"
 	"fmt"
 
-	. "github.com/tendermint/go-common"
-	"github.com/tendermint/go-events"
-
 	acm "github.com/eris-ltd/eris-db/account"
+	"github.com/eris-ltd/eris-db/common/sanity"
+	core_types "github.com/eris-ltd/eris-db/core/types"
 	"github.com/eris-ltd/eris-db/manager/eris-mint/evm"
 	ptypes "github.com/eris-ltd/eris-db/permission/types" // for GlobalPermissionAddress ...
-
-	core_types "github.com/eris-ltd/eris-db/core/types"
 	"github.com/eris-ltd/eris-db/txs"
+	. "github.com/eris-ltd/eris-db/word256"
+
+	"github.com/tendermint/go-events"
 )
 
 // ExecBlock stuff is now taken care of by the consensus engine.
@@ -203,6 +217,12 @@ func getOrMakeOutputs(state AccountGetter, accounts map[string]*acm.Account, out
 	return accounts, nil
 }
 
+// Since all ethereum accounts implicitly exist we sometimes lazily create an Account object to represent them
+// only when needed. Sometimes we need to create an unknown Account knowing only its address (which is expected to
+// be a deterministic hash of its associated public key) and not its public key. When we eventually receive a
+// transaction acting on behalf of that account we will be given a public key that we can check matches the address.
+// If it does then we will associate the public key with the stub account already registered in the system once and
+// for all time.
 func checkInputPubKey(acc *acm.Account, in *txs.TxInput) error {
 	if acc.PubKey == nil {
 		if in.PubKey == nil {
@@ -222,7 +242,7 @@ func validateInputs(accounts map[string]*acm.Account, signBytes []byte, ins []*t
 	for _, in := range ins {
 		acc := accounts[string(in.Address)]
 		if acc == nil {
-			PanicSanity("validateInputs() expects account in accounts")
+			sanity.PanicSanity("validateInputs() expects account in accounts")
 		}
 		err = validateInput(acc, signBytes, in)
 		if err != nil {
@@ -273,10 +293,10 @@ func adjustByInputs(accounts map[string]*acm.Account, ins []*txs.TxInput) {
 	for _, in := range ins {
 		acc := accounts[string(in.Address)]
 		if acc == nil {
-			PanicSanity("adjustByInputs() expects account in accounts")
+			sanity.PanicSanity("adjustByInputs() expects account in accounts")
 		}
 		if acc.Balance < in.Amount {
-			PanicSanity("adjustByInputs() expects sufficient funds")
+			sanity.PanicSanity("adjustByInputs() expects sufficient funds")
 		}
 		acc.Balance -= in.Amount
 
@@ -288,7 +308,7 @@ func adjustByOutputs(accounts map[string]*acm.Account, outs []*txs.TxOutput) {
 	for _, out := range outs {
 		acc := accounts[string(out.Address)]
 		if acc == nil {
-			PanicSanity("adjustByOutputs() expects account in accounts")
+			sanity.PanicSanity("adjustByOutputs() expects account in accounts")
 		}
 		acc.Balance += out.Amount
 	}
@@ -362,7 +382,7 @@ func ExecTx(blockCache *BlockCache, tx txs.Tx, runCall bool, evc events.Fireable
 		// Validate input
 		inAcc = blockCache.GetAccount(tx.Input.Address)
 		if inAcc == nil {
-			log.Info(Fmt("Can't find in account %X", tx.Input.Address))
+			log.Info(fmt.Sprintf("Can't find in account %X", tx.Input.Address))
 			return txs.ErrTxInvalidAddress
 		}
 
@@ -379,24 +399,24 @@ func ExecTx(blockCache *BlockCache, tx txs.Tx, runCall bool, evc events.Fireable
 
 		// pubKey should be present in either "inAcc" or "tx.Input"
 		if err := checkInputPubKey(inAcc, tx.Input); err != nil {
-			log.Info(Fmt("Can't find pubkey for %X", tx.Input.Address))
+			log.Info(fmt.Sprintf("Can't find pubkey for %X", tx.Input.Address))
 			return err
 		}
 		signBytes := acm.SignBytes(_s.ChainID, tx)
 		err := validateInput(inAcc, signBytes, tx.Input)
 		if err != nil {
-			log.Info(Fmt("validateInput failed on %X: %v", tx.Input.Address, err))
+			log.Info(fmt.Sprintf("validateInput failed on %X: %v", tx.Input.Address, err))
 			return err
 		}
 		if tx.Input.Amount < tx.Fee {
-			log.Info(Fmt("Sender did not send enough to cover the fee %X", tx.Input.Address))
+			log.Info(fmt.Sprintf("Sender did not send enough to cover the fee %X", tx.Input.Address))
 			return txs.ErrTxInsufficientFunds
 		}
 
 		if !createContract {
 			// Validate output
 			if len(tx.Address) != 20 {
-				log.Info(Fmt("Destination address is not 20 bytes %X", tx.Address))
+				log.Info(fmt.Sprintf("Destination address is not 20 bytes %X", tx.Address))
 				return txs.ErrTxInvalidAddress
 			}
 			// check if its a native contract
@@ -410,7 +430,7 @@ func ExecTx(blockCache *BlockCache, tx txs.Tx, runCall bool, evc events.Fireable
 			outAcc = blockCache.GetAccount(tx.Address)
 		}
 
-		log.Info(Fmt("Out account: %v", outAcc))
+		log.Info(fmt.Sprintf("Out account: %v", outAcc))
 
 		// Good!
 		value := tx.Input.Amount - tx.Fee
@@ -448,10 +468,10 @@ func ExecTx(blockCache *BlockCache, tx txs.Tx, runCall bool, evc events.Fireable
 				// you have to wait a block to avoid a re-ordering attack
 				// that will take your fees
 				if outAcc == nil {
-					log.Info(Fmt("%X tries to call %X but it does not exist.",
+					log.Info(fmt.Sprintf("%X tries to call %X but it does not exist.",
 						inAcc.Address, tx.Address))
 				} else {
-					log.Info(Fmt("%X tries to call %X but code is blank.",
+					log.Info(fmt.Sprintf("%X tries to call %X but code is blank.",
 						inAcc.Address, tx.Address))
 				}
 				err = txs.ErrTxInvalidAddress
@@ -462,14 +482,14 @@ func ExecTx(blockCache *BlockCache, tx txs.Tx, runCall bool, evc events.Fireable
 			if createContract {
 				// We already checked for permission
 				callee = txCache.CreateAccount(caller)
-				log.Info(Fmt("Created new contract %X", callee.Address))
+				log.Info(fmt.Sprintf("Created new contract %X", callee.Address))
 				code = tx.Data
 			} else {
 				callee = toVMAccount(outAcc)
-				log.Info(Fmt("Calling contract %X with code %X", callee.Address, callee.Code))
+				log.Info(fmt.Sprintf("Calling contract %X with code %X", callee.Address, callee.Code))
 				code = callee.Code
 			}
-			log.Info(Fmt("Code for this contract: %X", code))
+			log.Info(fmt.Sprintf("Code for this contract: %X", code))
 
 			// Run VM call and sync txCache to blockCache.
 			{ // Capture scope for goto.
@@ -482,7 +502,7 @@ func ExecTx(blockCache *BlockCache, tx txs.Tx, runCall bool, evc events.Fireable
 				ret, err = vmach.Call(caller, callee, code, tx.Data, value, &gas)
 				if err != nil {
 					// Failure. Charge the gas fee. The 'value' was otherwise not transferred.
-					log.Info(Fmt("Error on execution: %v", err))
+					log.Info(fmt.Sprintf("Error on execution: %v", err))
 					goto CALL_COMPLETE
 				}
 
@@ -528,7 +548,7 @@ func ExecTx(blockCache *BlockCache, tx txs.Tx, runCall bool, evc events.Fireable
 		// Validate input
 		inAcc = blockCache.GetAccount(tx.Input.Address)
 		if inAcc == nil {
-			log.Info(Fmt("Can't find in account %X", tx.Input.Address))
+			log.Info(fmt.Sprintf("Can't find in account %X", tx.Input.Address))
 			return txs.ErrTxInvalidAddress
 		}
 		// check permission
@@ -537,18 +557,18 @@ func ExecTx(blockCache *BlockCache, tx txs.Tx, runCall bool, evc events.Fireable
 		}
 		// pubKey should be present in either "inAcc" or "tx.Input"
 		if err := checkInputPubKey(inAcc, tx.Input); err != nil {
-			log.Info(Fmt("Can't find pubkey for %X", tx.Input.Address))
+			log.Info(fmt.Sprintf("Can't find pubkey for %X", tx.Input.Address))
 			return err
 		}
 		signBytes := acm.SignBytes(_s.ChainID, tx)
 		err := validateInput(inAcc, signBytes, tx.Input)
 		if err != nil {
-			log.Info(Fmt("validateInput failed on %X: %v", tx.Input.Address, err))
+			log.Info(fmt.Sprintf("validateInput failed on %X: %v", tx.Input.Address, err))
 			return err
 		}
 		// fee is in addition to the amount which is used to determine the TTL
 		if tx.Input.Amount < tx.Fee {
-			log.Info(Fmt("Sender did not send enough to cover the fee %X", tx.Input.Address))
+			log.Info(fmt.Sprintf("Sender did not send enough to cover the fee %X", tx.Input.Address))
 			return txs.ErrTxInsufficientFunds
 		}
 
@@ -576,7 +596,7 @@ func ExecTx(blockCache *BlockCache, tx txs.Tx, runCall bool, evc events.Fireable
 			if entry.Expires > lastBlockHeight {
 				// ensure we are owner
 				if bytes.Compare(entry.Owner, tx.Input.Address) != 0 {
-					log.Info(Fmt("Sender %X is trying to update a name (%s) for which he is not owner", tx.Input.Address, tx.Name))
+					log.Info(fmt.Sprintf("Sender %X is trying to update a name (%s) for which he is not owner", tx.Input.Address, tx.Name))
 					return txs.ErrTxPermissionDenied
 				}
 			} else {
@@ -594,7 +614,7 @@ func ExecTx(blockCache *BlockCache, tx txs.Tx, runCall bool, evc events.Fireable
 				// and changing the data
 				if expired {
 					if expiresIn < txs.MinNameRegistrationPeriod {
-						return errors.New(Fmt("Names must be registered for at least %d blocks", txs.MinNameRegistrationPeriod))
+						return errors.New(fmt.Sprintf("Names must be registered for at least %d blocks", txs.MinNameRegistrationPeriod))
 					}
 					entry.Expires = lastBlockHeight + expiresIn
 					entry.Owner = tx.Input.Address
@@ -606,7 +626,7 @@ func ExecTx(blockCache *BlockCache, tx txs.Tx, runCall bool, evc events.Fireable
 					credit := oldCredit + value
 					expiresIn = int(credit / costPerBlock)
 					if expiresIn < txs.MinNameRegistrationPeriod {
-						return errors.New(Fmt("Names must be registered for at least %d blocks", txs.MinNameRegistrationPeriod))
+						return errors.New(fmt.Sprintf("Names must be registered for at least %d blocks", txs.MinNameRegistrationPeriod))
 					}
 					entry.Expires = lastBlockHeight + expiresIn
 					log.Info("Updated namereg entry", "name", entry.Name, "expiresIn", expiresIn, "oldCredit", oldCredit, "value", value, "credit", credit)
@@ -616,7 +636,7 @@ func ExecTx(blockCache *BlockCache, tx txs.Tx, runCall bool, evc events.Fireable
 			}
 		} else {
 			if expiresIn < txs.MinNameRegistrationPeriod {
-				return errors.New(Fmt("Names must be registered for at least %d blocks", txs.MinNameRegistrationPeriod))
+				return errors.New(fmt.Sprintf("Names must be registered for at least %d blocks", txs.MinNameRegistrationPeriod))
 			}
 			// entry does not exist, so create it
 			entry = &core_types.NameRegEntry{
@@ -828,7 +848,7 @@ func ExecTx(blockCache *BlockCache, tx txs.Tx, runCall bool, evc events.Fireable
 		// Validate input
 		inAcc = blockCache.GetAccount(tx.Input.Address)
 		if inAcc == nil {
-			log.Debug(Fmt("Can't find in account %X", tx.Input.Address))
+			log.Debug(fmt.Sprintf("Can't find in account %X", tx.Input.Address))
 			return txs.ErrTxInvalidAddress
 		}
 
@@ -840,13 +860,13 @@ func ExecTx(blockCache *BlockCache, tx txs.Tx, runCall bool, evc events.Fireable
 
 		// pubKey should be present in either "inAcc" or "tx.Input"
 		if err := checkInputPubKey(inAcc, tx.Input); err != nil {
-			log.Debug(Fmt("Can't find pubkey for %X", tx.Input.Address))
+			log.Debug(fmt.Sprintf("Can't find pubkey for %X", tx.Input.Address))
 			return err
 		}
 		signBytes := acm.SignBytes(_s.ChainID, tx)
 		err := validateInput(inAcc, signBytes, tx.Input)
 		if err != nil {
-			log.Debug(Fmt("validateInput failed on %X: %v", tx.Input.Address, err))
+			log.Debug(fmt.Sprintf("validateInput failed on %X: %v", tx.Input.Address, err))
 			return err
 		}
 
@@ -871,7 +891,7 @@ func ExecTx(blockCache *BlockCache, tx txs.Tx, runCall bool, evc events.Fireable
 			err = permAcc.Permissions.Base.Unset(args.Permission)
 		case *ptypes.SetGlobalArgs:
 			if permAcc = blockCache.GetAccount(ptypes.GlobalPermissionsAddress); permAcc == nil {
-				PanicSanity("can't find global permissions account")
+				sanity.PanicSanity("can't find global permissions account")
 			}
 			err = permAcc.Permissions.Base.Set(args.Permission, args.Value)
 		case *ptypes.HasRoleArgs:
@@ -891,7 +911,7 @@ func ExecTx(blockCache *BlockCache, tx txs.Tx, runCall bool, evc events.Fireable
 				return fmt.Errorf("Role (%s) does not exist for account %X", args.Role, args.Address)
 			}
 		default:
-			PanicSanity(Fmt("invalid permission function: %s", ptypes.PermFlagToString(permFlag)))
+			sanity.PanicSanity(fmt.Sprintf("invalid permission function: %s", ptypes.PermFlagToString(permFlag)))
 		}
 
 		// TODO: maybe we want to take funds on error and allow txs in that don't do anythingi?
@@ -916,7 +936,7 @@ func ExecTx(blockCache *BlockCache, tx txs.Tx, runCall bool, evc events.Fireable
 
 	default:
 		// binary decoding should not let this happen
-		PanicSanity("Unknown Tx type")
+		sanity.PanicSanity("Unknown Tx type")
 		return nil
 	}
 }
@@ -926,7 +946,7 @@ func ExecTx(blockCache *BlockCache, tx txs.Tx, runCall bool, evc events.Fireable
 // Get permission on an account or fall back to global value
 func HasPermission(state AccountGetter, acc *acm.Account, perm ptypes.PermFlag) bool {
 	if perm > ptypes.AllPermFlags {
-		PanicSanity("Checking an unknown permission in state should never happen")
+		sanity.PanicSanity("Checking an unknown permission in state should never happen")
 	}
 
 	if acc == nil {
@@ -939,14 +959,14 @@ func HasPermission(state AccountGetter, acc *acm.Account, perm ptypes.PermFlag)
 	v, err := acc.Permissions.Base.Get(perm)
 	if _, ok := err.(ptypes.ErrValueNotSet); ok {
 		if state == nil {
-			PanicSanity("All known global permissions should be set!")
+			sanity.PanicSanity("All known global permissions should be set!")
 		}
 		log.Info("Permission for account is not set. Querying GlobalPermissionsAddress", "perm", permString)
 		return HasPermission(nil, state.GetAccount(ptypes.GlobalPermissionsAddress), perm)
 	} else if v {
-		log.Info("Account has permission", "address", Fmt("%X", acc.Address), "perm", permString)
+		log.Info("Account has permission", "address", fmt.Sprintf("%X", acc.Address), "perm", permString)
 	} else {
-		log.Info("Account does not have permission", "address", Fmt("%X", acc.Address), "perm", permString)
+		log.Info("Account does not have permission", "address", fmt.Sprintf("%X", acc.Address), "perm", permString)
 	}
 	return v
 }
@@ -1005,5 +1025,5 @@ type InvalidTxError struct {
 }
 
 func (txErr InvalidTxError) Error() string {
-	return Fmt("Invalid tx: [%v] reason: [%v]", txErr.Tx, txErr.Reason)
+	return fmt.Sprintf("Invalid tx: [%v] reason: [%v]", txErr.Tx, txErr.Reason)
 }
diff --git a/manager/eris-mint/state/genesis_test.go b/manager/eris-mint/state/genesis_test.go
index 73e7f92f4d4ad04f135f1270f6173dc5cae61832..1aa25bc05bbd580eb33231004e0034d8f5e922b3 100644
--- a/manager/eris-mint/state/genesis_test.go
+++ b/manager/eris-mint/state/genesis_test.go
@@ -1,3 +1,17 @@
+// 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 state
 
 import (
@@ -9,10 +23,10 @@ import (
 	"time"
 
 	acm "github.com/eris-ltd/eris-db/account"
-	. "github.com/eris-ltd/eris-db/manager/eris-mint/state/types"
+	"github.com/eris-ltd/eris-db/common/random"
+	genesis "github.com/eris-ltd/eris-db/genesis"
 	ptypes "github.com/eris-ltd/eris-db/permission/types"
 
-	. "github.com/tendermint/go-common"
 	tdb "github.com/tendermint/go-db"
 	"github.com/tendermint/tendermint/types"
 )
@@ -31,7 +45,7 @@ var g1 = fmt.Sprintf(`
         {
             "address": "%X",
             "amount": %d,
-	    "name": "%s",
+	    	"name": "%s",
             "permissions": {
 		    "base": {
 			    "perms": %d,
@@ -60,7 +74,7 @@ var g1 = fmt.Sprintf(`
 `, chain_id, addr1, amt1, accName, perms, setbit, roles1[0], roles1[1])
 
 func TestGenesisReadable(t *testing.T) {
-	genDoc := GenesisDocFromJSON([]byte(g1))
+	genDoc := genesis.GenesisDocFromJSON([]byte(g1))
 	if genDoc.ChainID != chain_id {
 		t.Fatalf("Incorrect chain id. Got %d, expected %d\n", genDoc.ChainID, chain_id)
 	}
@@ -82,7 +96,7 @@ func TestGenesisReadable(t *testing.T) {
 }
 
 func TestGenesisMakeState(t *testing.T) {
-	genDoc := GenesisDocFromJSON([]byte(g1))
+	genDoc := genesis.GenesisDocFromJSON([]byte(g1))
 	db := tdb.NewMemDB()
 	st := MakeGenesisState(db, genDoc)
 	acc := st.GetAccount(addr1)
@@ -108,37 +122,37 @@ func RandAccount(randBalance bool, minBalance int64) (*acm.Account, *acm.PrivAcc
 	acc := &acm.Account{
 		Address:     privAccount.PubKey.Address(),
 		PubKey:      privAccount.PubKey,
-		Sequence:    RandInt(),
+		Sequence:    random.RandInt(),
 		Balance:     minBalance,
 		Permissions: perms,
 	}
 	if randBalance {
-		acc.Balance += int64(RandUint32())
+		acc.Balance += int64(random.RandUint32())
 	}
 	return acc, privAccount
 }
 
-func RandGenesisDoc(numAccounts int, randBalance bool, minBalance int64, numValidators int, randBonded bool, minBonded int64) (*GenesisDoc, []*acm.PrivAccount, []*types.PrivValidator) {
-	accounts := make([]GenesisAccount, numAccounts)
+func RandGenesisDoc(numAccounts int, randBalance bool, minBalance int64, numValidators int, randBonded bool, minBonded int64) (*genesis.GenesisDoc, []*acm.PrivAccount, []*types.PrivValidator) {
+	accounts := make([]genesis.GenesisAccount, numAccounts)
 	privAccounts := make([]*acm.PrivAccount, numAccounts)
 	defaultPerms := ptypes.DefaultAccountPermissions
 	for i := 0; i < numAccounts; i++ {
 		account, privAccount := RandAccount(randBalance, minBalance)
-		accounts[i] = GenesisAccount{
+		accounts[i] = genesis.GenesisAccount{
 			Address:     account.Address,
 			Amount:      account.Balance,
 			Permissions: &defaultPerms, // This will get copied into each state.Account.
 		}
 		privAccounts[i] = privAccount
 	}
-	validators := make([]GenesisValidator, numValidators)
+	validators := make([]genesis.GenesisValidator, numValidators)
 	privValidators := make([]*types.PrivValidator, numValidators)
 	for i := 0; i < numValidators; i++ {
 		valInfo, privVal := types.RandValidator(randBonded, minBonded)
-		validators[i] = GenesisValidator{
+		validators[i] = genesis.GenesisValidator{
 			PubKey: valInfo.PubKey,
 			Amount: valInfo.VotingPower,
-			UnbondTo: []BasicAccount{
+			UnbondTo: []genesis.BasicAccount{
 				{
 					Address: valInfo.PubKey.Address(),
 					Amount:  valInfo.VotingPower,
@@ -148,7 +162,7 @@ func RandGenesisDoc(numAccounts int, randBalance bool, minBalance int64, numVali
 		privValidators[i] = privVal
 	}
 	sort.Sort(types.PrivValidatorsByAddress(privValidators))
-	return &GenesisDoc{
+	return &genesis.GenesisDoc{
 		GenesisTime: time.Now(),
 		ChainID:     "tendermint_test",
 		Accounts:    accounts,
diff --git a/manager/eris-mint/state/log.go b/manager/eris-mint/state/log.go
index 5b102b5703e0474c1ee2db377f3b95c7a8705c3c..d8e71b796dd6dc0599c7bebea5257b0a2283c1d7 100644
--- a/manager/eris-mint/state/log.go
+++ b/manager/eris-mint/state/log.go
@@ -1,3 +1,17 @@
+// 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 state
 
 import (
diff --git a/manager/eris-mint/state/permissions_test.go b/manager/eris-mint/state/permissions_test.go
index 523a5ffc8b2a75a13749c8ba924d4c6ded2e824a..c8497f1330c4ac88bddfc0b621d0c21081eae7a3 100644
--- a/manager/eris-mint/state/permissions_test.go
+++ b/manager/eris-mint/state/permissions_test.go
@@ -1,25 +1,37 @@
+// 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 state
 
 import (
 	"bytes"
-	"encoding/hex"
 	"fmt"
 	"strconv"
 	"testing"
 	"time"
 
 	acm "github.com/eris-ltd/eris-db/account"
+	genesis "github.com/eris-ltd/eris-db/genesis"
 	"github.com/eris-ltd/eris-db/manager/eris-mint/evm"
-	. "github.com/eris-ltd/eris-db/manager/eris-mint/state/types"
+	. "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/eris-ltd/eris-db/word256"
 
-	. "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"
 	"github.com/tendermint/go-events"
-
 	"github.com/tendermint/tendermint/config/tendermint_test"
 )
 
@@ -28,8 +40,9 @@ func init() {
 }
 
 var (
-	dbBackend = "memdb"
-	dbDir     = ""
+	dbBackend           = "memdb"
+	dbDir               = ""
+	permissionsContract = vm.SNativeContracts()["Permissions"]
 )
 
 /*
@@ -111,30 +124,30 @@ var (
 	PermsAllFalse = ptypes.ZeroAccountPermissions
 )
 
-func newBaseGenDoc(globalPerm, accountPerm ptypes.AccountPermissions) GenesisDoc {
-	genAccounts := []GenesisAccount{}
+func newBaseGenDoc(globalPerm, accountPerm ptypes.AccountPermissions) genesis.GenesisDoc {
+	genAccounts := []genesis.GenesisAccount{}
 	for _, u := range user[:5] {
 		accountPermCopy := accountPerm // Create new instance for custom overridability.
-		genAccounts = append(genAccounts, GenesisAccount{
+		genAccounts = append(genAccounts, genesis.GenesisAccount{
 			Address:     u.Address,
 			Amount:      1000000,
 			Permissions: &accountPermCopy,
 		})
 	}
 
-	return GenesisDoc{
+	return genesis.GenesisDoc{
 		GenesisTime: time.Now(),
 		ChainID:     chainID,
-		Params: &GenesisParams{
+		Params: &genesis.GenesisParams{
 			GlobalPermissions: &globalPerm,
 		},
 		Accounts: genAccounts,
-		Validators: []GenesisValidator{
-			GenesisValidator{
+		Validators: []genesis.GenesisValidator{
+			genesis.GenesisValidator{
 				PubKey: user[0].PubKey.(crypto.PubKeyEd25519),
 				Amount: 10,
-				UnbondTo: []BasicAccount{
-					BasicAccount{
+				UnbondTo: []genesis.BasicAccount{
+					genesis.BasicAccount{
 						Address: user[0].Address,
 					},
 				},
@@ -886,7 +899,7 @@ func TestSNativeCALL(t *testing.T) {
 
 	fmt.Println("\n#### HasBase")
 	// HasBase
-	snativeAddress, pF, data := snativePermTestInputCALL("has_base", user[3], ptypes.Bond, false)
+	snativeAddress, pF, data := snativePermTestInputCALL("hasBase", user[3], ptypes.Bond, false)
 	testSNativeCALLExpectFail(t, blockCache, doug, snativeAddress, data)
 	testSNativeCALLExpectPass(t, blockCache, doug, pF, snativeAddress, data, func(ret []byte) error {
 		// return value should be true or false as a 32 byte array...
@@ -898,10 +911,10 @@ func TestSNativeCALL(t *testing.T) {
 
 	fmt.Println("\n#### SetBase")
 	// SetBase
-	snativeAddress, pF, data = snativePermTestInputCALL("set_base", user[3], ptypes.Bond, false)
+	snativeAddress, pF, data = snativePermTestInputCALL("setBase", user[3], ptypes.Bond, false)
 	testSNativeCALLExpectFail(t, blockCache, doug, snativeAddress, data)
 	testSNativeCALLExpectPass(t, blockCache, doug, pF, snativeAddress, data, func(ret []byte) error { return nil })
-	snativeAddress, pF, data = snativePermTestInputCALL("has_base", user[3], ptypes.Bond, false)
+	snativeAddress, pF, data = snativePermTestInputCALL("hasBase", user[3], ptypes.Bond, false)
 	testSNativeCALLExpectPass(t, blockCache, doug, pF, snativeAddress, data, func(ret []byte) error {
 		// return value should be true or false as a 32 byte array...
 		if !IsZeros(ret) {
@@ -909,9 +922,9 @@ func TestSNativeCALL(t *testing.T) {
 		}
 		return nil
 	})
-	snativeAddress, pF, data = snativePermTestInputCALL("set_base", user[3], ptypes.CreateContract, true)
+	snativeAddress, pF, data = snativePermTestInputCALL("setBase", user[3], ptypes.CreateContract, true)
 	testSNativeCALLExpectPass(t, blockCache, doug, pF, snativeAddress, data, func(ret []byte) error { return nil })
-	snativeAddress, pF, data = snativePermTestInputCALL("has_base", user[3], ptypes.CreateContract, false)
+	snativeAddress, pF, data = snativePermTestInputCALL("hasBase", user[3], ptypes.CreateContract, false)
 	testSNativeCALLExpectPass(t, blockCache, 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) {
@@ -922,10 +935,10 @@ func TestSNativeCALL(t *testing.T) {
 
 	fmt.Println("\n#### UnsetBase")
 	// UnsetBase
-	snativeAddress, pF, data = snativePermTestInputCALL("unset_base", user[3], ptypes.CreateContract, false)
+	snativeAddress, pF, data = snativePermTestInputCALL("unsetBase", user[3], ptypes.CreateContract, false)
 	testSNativeCALLExpectFail(t, blockCache, doug, snativeAddress, data)
 	testSNativeCALLExpectPass(t, blockCache, doug, pF, snativeAddress, data, func(ret []byte) error { return nil })
-	snativeAddress, pF, data = snativePermTestInputCALL("has_base", user[3], ptypes.CreateContract, false)
+	snativeAddress, pF, data = snativePermTestInputCALL("hasBase", user[3], ptypes.CreateContract, false)
 	testSNativeCALLExpectPass(t, blockCache, doug, pF, snativeAddress, data, func(ret []byte) error {
 		if !IsZeros(ret) {
 			return fmt.Errorf("Expected 0. Got %X", ret)
@@ -935,10 +948,10 @@ func TestSNativeCALL(t *testing.T) {
 
 	fmt.Println("\n#### SetGlobal")
 	// SetGlobalPerm
-	snativeAddress, pF, data = snativePermTestInputCALL("set_global", user[3], ptypes.CreateContract, true)
+	snativeAddress, pF, data = snativePermTestInputCALL("setGlobal", user[3], ptypes.CreateContract, true)
 	testSNativeCALLExpectFail(t, blockCache, doug, snativeAddress, data)
 	testSNativeCALLExpectPass(t, blockCache, doug, pF, snativeAddress, data, func(ret []byte) error { return nil })
-	snativeAddress, pF, data = snativePermTestInputCALL("has_base", user[3], ptypes.CreateContract, false)
+	snativeAddress, pF, data = snativePermTestInputCALL("hasBase", user[3], ptypes.CreateContract, false)
 	testSNativeCALLExpectPass(t, blockCache, 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) {
@@ -949,7 +962,7 @@ func TestSNativeCALL(t *testing.T) {
 
 	fmt.Println("\n#### HasRole")
 	// HasRole
-	snativeAddress, pF, data = snativeRoleTestInputCALL("has_role", user[3], "bumble")
+	snativeAddress, pF, data = snativeRoleTestInputCALL("hasRole", user[3], "bumble")
 	testSNativeCALLExpectFail(t, blockCache, doug, snativeAddress, data)
 	testSNativeCALLExpectPass(t, blockCache, doug, pF, snativeAddress, data, func(ret []byte) error {
 		if !IsZeros(ret[:31]) || ret[31] != byte(1) {
@@ -960,17 +973,17 @@ func TestSNativeCALL(t *testing.T) {
 
 	fmt.Println("\n#### AddRole")
 	// AddRole
-	snativeAddress, pF, data = snativeRoleTestInputCALL("has_role", user[3], "chuck")
+	snativeAddress, pF, data = snativeRoleTestInputCALL("hasRole", user[3], "chuck")
 	testSNativeCALLExpectPass(t, blockCache, doug, pF, snativeAddress, data, func(ret []byte) error {
 		if !IsZeros(ret) {
 			return fmt.Errorf("Expected 0. Got %X", ret)
 		}
 		return nil
 	})
-	snativeAddress, pF, data = snativeRoleTestInputCALL("add_role", user[3], "chuck")
+	snativeAddress, pF, data = snativeRoleTestInputCALL("addRole", user[3], "chuck")
 	testSNativeCALLExpectFail(t, blockCache, doug, snativeAddress, data)
 	testSNativeCALLExpectPass(t, blockCache, doug, pF, snativeAddress, data, func(ret []byte) error { return nil })
-	snativeAddress, pF, data = snativeRoleTestInputCALL("has_role", user[3], "chuck")
+	snativeAddress, pF, data = snativeRoleTestInputCALL("hasRole", user[3], "chuck")
 	testSNativeCALLExpectPass(t, blockCache, doug, pF, snativeAddress, data, func(ret []byte) error {
 		if !IsZeros(ret[:31]) || ret[31] != byte(1) {
 			return fmt.Errorf("Expected 1. Got %X", ret)
@@ -980,10 +993,10 @@ func TestSNativeCALL(t *testing.T) {
 
 	fmt.Println("\n#### RmRole")
 	// RmRole
-	snativeAddress, pF, data = snativeRoleTestInputCALL("rm_role", user[3], "chuck")
+	snativeAddress, pF, data = snativeRoleTestInputCALL("removeRole", user[3], "chuck")
 	testSNativeCALLExpectFail(t, blockCache, doug, snativeAddress, data)
 	testSNativeCALLExpectPass(t, blockCache, doug, pF, snativeAddress, data, func(ret []byte) error { return nil })
-	snativeAddress, pF, data = snativeRoleTestInputCALL("has_role", user[3], "chuck")
+	snativeAddress, pF, data = snativeRoleTestInputCALL("hasRole", user[3], "chuck")
 	testSNativeCALLExpectPass(t, blockCache, doug, pF, snativeAddress, data, func(ret []byte) error {
 		if !IsZeros(ret) {
 			return fmt.Errorf("Expected 0. Got %X", ret)
@@ -1007,14 +1020,14 @@ func TestSNativeTx(t *testing.T) {
 
 	fmt.Println("\n#### SetBase")
 	// SetBase
-	snativeArgs := snativePermTestInputTx("set_base", user[3], ptypes.Bond, false)
+	snativeArgs := snativePermTestInputTx("setBase", user[3], ptypes.Bond, false)
 	testSNativeTxExpectFail(t, blockCache, snativeArgs)
 	testSNativeTxExpectPass(t, blockCache, ptypes.SetBase, snativeArgs)
 	acc := blockCache.GetAccount(user[3].Address)
 	if v, _ := acc.Permissions.Base.Get(ptypes.Bond); v {
 		t.Fatal("expected permission to be set false")
 	}
-	snativeArgs = snativePermTestInputTx("set_base", user[3], ptypes.CreateContract, true)
+	snativeArgs = snativePermTestInputTx("setBase", user[3], ptypes.CreateContract, true)
 	testSNativeTxExpectPass(t, blockCache, ptypes.SetBase, snativeArgs)
 	acc = blockCache.GetAccount(user[3].Address)
 	if v, _ := acc.Permissions.Base.Get(ptypes.CreateContract); !v {
@@ -1023,7 +1036,7 @@ func TestSNativeTx(t *testing.T) {
 
 	fmt.Println("\n#### UnsetBase")
 	// UnsetBase
-	snativeArgs = snativePermTestInputTx("unset_base", user[3], ptypes.CreateContract, false)
+	snativeArgs = snativePermTestInputTx("unsetBase", user[3], ptypes.CreateContract, false)
 	testSNativeTxExpectFail(t, blockCache, snativeArgs)
 	testSNativeTxExpectPass(t, blockCache, ptypes.UnsetBase, snativeArgs)
 	acc = blockCache.GetAccount(user[3].Address)
@@ -1033,7 +1046,7 @@ func TestSNativeTx(t *testing.T) {
 
 	fmt.Println("\n#### SetGlobal")
 	// SetGlobalPerm
-	snativeArgs = snativePermTestInputTx("set_global", user[3], ptypes.CreateContract, true)
+	snativeArgs = snativePermTestInputTx("setGlobal", user[3], ptypes.CreateContract, true)
 	testSNativeTxExpectFail(t, blockCache, snativeArgs)
 	testSNativeTxExpectPass(t, blockCache, ptypes.SetGlobal, snativeArgs)
 	acc = blockCache.GetAccount(ptypes.GlobalPermissionsAddress)
@@ -1043,7 +1056,7 @@ func TestSNativeTx(t *testing.T) {
 
 	fmt.Println("\n#### AddRole")
 	// AddRole
-	snativeArgs = snativeRoleTestInputTx("add_role", user[3], "chuck")
+	snativeArgs = snativeRoleTestInputTx("addRole", user[3], "chuck")
 	testSNativeTxExpectFail(t, blockCache, snativeArgs)
 	testSNativeTxExpectPass(t, blockCache, ptypes.AddRole, snativeArgs)
 	acc = blockCache.GetAccount(user[3].Address)
@@ -1053,7 +1066,7 @@ func TestSNativeTx(t *testing.T) {
 
 	fmt.Println("\n#### RmRole")
 	// RmRole
-	snativeArgs = snativeRoleTestInputTx("rm_role", user[3], "chuck")
+	snativeArgs = snativeRoleTestInputTx("removeRole", user[3], "chuck")
 	testSNativeTxExpectFail(t, blockCache, snativeArgs)
 	testSNativeTxExpectPass(t, blockCache, ptypes.RmRole, snativeArgs)
 	acc = blockCache.GetAccount(user[3].Address)
@@ -1183,72 +1196,71 @@ func boolToWord256(v bool) Word256 {
 	return LeftPadWord256([]byte{vint})
 }
 
-func permNameToFuncID(s string) []byte {
-	for k, v := range vm.PermsMap {
-		if s == v.Name {
-			b, _ := hex.DecodeString(k)
-			return b
-		}
+func permNameToFuncID(name string) []byte {
+	function, err := permissionsContract.FunctionByName(name)
+	if err != nil {
+		panic("didn't find snative function signature!")
 	}
-	panic("didn't find snative function signature!")
+	id := function.ID()
+	return id[:]
 }
 
 func snativePermTestInputCALL(name string, user *acm.PrivAccount, perm ptypes.PermFlag, val bool) (addr []byte, pF ptypes.PermFlag, data []byte) {
-	addr = LeftPadWord256([]byte(vm.PermissionsContract)).Postfix(20)
+	addr = permissionsContract.AddressBytes()
 	switch name {
-	case "has_base", "unset_base":
+	case "hasBase", "unsetBase":
 		data = LeftPadBytes(user.Address, 32)
 		data = append(data, Uint64ToWord256(uint64(perm)).Bytes()...)
-	case "set_base":
+	case "setBase":
 		data = LeftPadBytes(user.Address, 32)
 		data = append(data, Uint64ToWord256(uint64(perm)).Bytes()...)
 		data = append(data, boolToWord256(val).Bytes()...)
-	case "set_global":
+	case "setGlobal":
 		data = Uint64ToWord256(uint64(perm)).Bytes()
 		data = append(data, boolToWord256(val).Bytes()...)
 	}
 	data = append(permNameToFuncID(name), data...)
 	var err error
 	if pF, err = ptypes.PermStringToFlag(name); err != nil {
-		panic(Fmt("failed to convert perm string (%s) to flag", name))
+		panic(fmt.Sprintf("failed to convert perm string (%s) to flag", name))
 	}
 	return
 }
 
 func snativePermTestInputTx(name string, user *acm.PrivAccount, perm ptypes.PermFlag, val bool) (snativeArgs ptypes.PermArgs) {
 	switch name {
-	case "has_base":
+	case "hasBase":
 		snativeArgs = &ptypes.HasBaseArgs{user.Address, perm}
-	case "unset_base":
+	case "unsetBase":
 		snativeArgs = &ptypes.UnsetBaseArgs{user.Address, perm}
-	case "set_base":
+	case "setBase":
 		snativeArgs = &ptypes.SetBaseArgs{user.Address, perm, val}
-	case "set_global":
+	case "setGlobal":
 		snativeArgs = &ptypes.SetGlobalArgs{perm, val}
 	}
 	return
 }
 
 func snativeRoleTestInputCALL(name string, user *acm.PrivAccount, role string) (addr []byte, pF ptypes.PermFlag, data []byte) {
-	addr = LeftPadWord256([]byte(vm.PermissionsContract)).Postfix(20)
+	addr = permissionsContract.AddressBytes()
 	data = LeftPadBytes(user.Address, 32)
 	data = append(data, RightPadBytes([]byte(role), 32)...)
 	data = append(permNameToFuncID(name), data...)
 
 	var err error
 	if pF, err = ptypes.PermStringToFlag(name); err != nil {
-		panic(Fmt("failed to convert perm string (%s) to flag", name))
+		panic(fmt.Sprintf("failed to convert perm string (%s) to flag", name))
 	}
 	return
 }
 
 func snativeRoleTestInputTx(name string, user *acm.PrivAccount, role string) (snativeArgs ptypes.PermArgs) {
 	switch name {
-	case "has_role":
+	case "hasRole":
 		snativeArgs = &ptypes.HasRoleArgs{user.Address, role}
-	case "add_role":
+	case "addRole":
 		snativeArgs = &ptypes.AddRoleArgs{user.Address, role}
-	case "rm_role":
+	case "removeRole":
 		snativeArgs = &ptypes.RmRoleArgs{user.Address, role}
 	}
 	return
diff --git a/manager/eris-mint/state/state.go b/manager/eris-mint/state/state.go
index 6a3945ae3ed9fb075aef188a23b0d59d056f8e1c..3d61775422fe5014a0e961deaf59925843f48728 100644
--- a/manager/eris-mint/state/state.go
+++ b/manager/eris-mint/state/state.go
@@ -1,3 +1,17 @@
+// 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 state
 
 import (
@@ -8,17 +22,17 @@ import (
 	"time"
 
 	acm "github.com/eris-ltd/eris-db/account"
-	. "github.com/eris-ltd/eris-db/manager/eris-mint/state/types"
+	genesis "github.com/eris-ltd/eris-db/genesis"
 	ptypes "github.com/eris-ltd/eris-db/permission/types"
 	"github.com/eris-ltd/eris-db/txs"
 
-	. "github.com/tendermint/go-common"
 	dbm "github.com/tendermint/go-db"
 	"github.com/tendermint/go-events"
 	"github.com/tendermint/go-merkle"
 	"github.com/tendermint/go-wire"
 
 	core_types "github.com/eris-ltd/eris-db/core/types"
+	"github.com/eris-ltd/eris-db/util"
 	"github.com/tendermint/tendermint/types"
 )
 
@@ -77,7 +91,7 @@ func LoadState(db dbm.DB) *State {
 		s.nameReg.Load(nameRegHash)
 		if *err != nil {
 			// DATA HAS BEEN CORRUPTED OR THE SPEC HAS CHANGED
-			Exit(Fmt("Data has been corrupted or its spec has changed: %v\n", *err))
+			util.Fatalf("Data has been corrupted or its spec has changed: %v\n", *err)
 		}
 		// TODO: ensure that buf is completely read.
 	}
@@ -101,7 +115,10 @@ func (s *State) Save() {
 	//wire.WriteByteSlice(s.validatorInfos.Hash(), buf, n, err)
 	wire.WriteByteSlice(s.nameReg.Hash(), buf, n, err)
 	if *err != nil {
-		PanicCrisis(*err)
+		// TODO: [Silas] Do something better than this, really serialising ought to
+		// be error-free
+		util.Fatalf("Could not serialise state in order to save the state, "+
+			"cannot continue, error: %s", *err)
 	}
 	s.DB.Set(stateKey, buf.Bytes())
 }
@@ -153,9 +170,9 @@ func (s *State) ComputeBlockStateHash(block *types.Block) error {
 }
 */
 
-func (s *State) GetGenesisDoc() (*GenesisDoc, error) {
-	var genesisDoc *GenesisDoc
-	loadedGenesisDocBytes := s.DB.Get(GenDocKey)
+func (s *State) GetGenesisDoc() (*genesis.GenesisDoc, error) {
+	var genesisDoc *genesis.GenesisDoc
+	loadedGenesisDocBytes := s.DB.Get(genesis.GenDocKey)
 	err := new(error)
 	wire.ReadJSONPtr(&genesisDoc, loadedGenesisDocBytes, err)
 	if *err != nil {
@@ -398,25 +415,27 @@ func (s *State) SetFireable(evc events.Fireable) {
 //-----------------------------------------------------------------------------
 // Genesis
 
-func MakeGenesisStateFromFile(db dbm.DB, genDocFile string) (*GenesisDoc, *State) {
+func MakeGenesisStateFromFile(db dbm.DB, genDocFile string) (*genesis.GenesisDoc, *State) {
 	jsonBlob, err := ioutil.ReadFile(genDocFile)
 	if err != nil {
-		Exit(Fmt("Couldn't read GenesisDoc file: %v", err))
+		util.Fatalf("Couldn't read GenesisDoc file: %v", err)
 	}
-	genDoc := GenesisDocFromJSON(jsonBlob)
+	genDoc := genesis.GenesisDocFromJSON(jsonBlob)
 	return genDoc, MakeGenesisState(db, genDoc)
 }
 
-func MakeGenesisState(db dbm.DB, genDoc *GenesisDoc) *State {
+func MakeGenesisState(db dbm.DB, genDoc *genesis.GenesisDoc) *State {
 	if len(genDoc.Validators) == 0 {
-		Exit(Fmt("The genesis file has no validators"))
+		util.Fatalf("The genesis file has no validators")
 	}
 
 	if genDoc.GenesisTime.IsZero() {
-		// MARMOT: really?
-		// set time to 11/18/2016 @ 4:09am (UTC)
+		// NOTE: [ben] change GenesisTime to requirement on v0.17
+		// GenesisTime needs to be deterministic across the chain
+		// and should be required in the genesis file;
+		// the requirement is not yet enforced when lacking set
+		// time to 11/18/2016 @ 4:09am (UTC)
 		genDoc.GenesisTime = time.Unix(1479442162, 0)
-		// genDoc.GenesisTime = time.Now()
 	}
 
 	// Make accounts state tree
diff --git a/manager/eris-mint/state/state_test.go b/manager/eris-mint/state/state_test.go
index dd6e07b9b6b9e1a3301e5529b411ffafee7c6251..b9d032ed3cadeddf8548603b556f217c68424089 100644
--- a/manager/eris-mint/state/state_test.go
+++ b/manager/eris-mint/state/state_test.go
@@ -1,18 +1,30 @@
+// 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 state
 
 import (
 	"bytes"
 	"encoding/hex"
 	"testing"
-	//"time"
-
-	"github.com/tendermint/go-common"
-	"github.com/tendermint/tendermint/config/tendermint_test"
-	// 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"
+	"github.com/eris-ltd/eris-db/word256"
+
+	"github.com/tendermint/tendermint/config/tendermint_test"
 )
 
 func init() {
@@ -429,7 +441,7 @@ func TestCreates(t *testing.T) {
 	state.UpdateAccount(newAcc1)
 	state.UpdateAccount(newAcc2)
 
-	createData = append(createData, common.LeftPadBytes(acc2.Address, 32)...)
+	createData = append(createData, word256.LeftPadBytes(acc2.Address, 32)...)
 
 	// call the pre-factory, triggering the factory to run a create
 	tx := &txs.CallTx{
@@ -452,7 +464,7 @@ func TestCreates(t *testing.T) {
 
 	acc1 = state.GetAccount(acc1.Address)
 	storage := state.LoadStorage(acc1.StorageRoot)
-	_, firstCreatedAddress, _ := storage.Get(common.LeftPadBytes([]byte{0}, 32))
+	_, firstCreatedAddress, _ := storage.Get(word256.LeftPadBytes([]byte{0}, 32))
 
 	acc0 = state.GetAccount(acc0.Address)
 	// call the pre-factory, triggering the factory to run a create
@@ -476,7 +488,7 @@ func TestCreates(t *testing.T) {
 
 	acc1 = state.GetAccount(acc1.Address)
 	storage = state.LoadStorage(acc1.StorageRoot)
-	_, secondCreatedAddress, _ := storage.Get(common.LeftPadBytes([]byte{0}, 32))
+	_, secondCreatedAddress, _ := storage.Get(word256.LeftPadBytes([]byte{0}, 32))
 
 	if bytes.Equal(firstCreatedAddress, secondCreatedAddress) {
 		t.Errorf("Multiple contracts created with the same address!")
@@ -507,7 +519,7 @@ func TestContractSend(t *testing.T) {
 	newAcc1.Code = callerCode
 	state.UpdateAccount(newAcc1)
 
-	sendData = append(sendData, common.LeftPadBytes(acc2.Address, 32)...)
+	sendData = append(sendData, word256.LeftPadBytes(acc2.Address, 32)...)
 	sendAmt := int64(10)
 	acc2Balance := acc2.Balance
 
diff --git a/manager/eris-mint/state/tx_cache.go b/manager/eris-mint/state/tx_cache.go
index 858dc68d719d945588315b2c050c3bc3e99dba44..810e85c9765a8dd84a39d0360c82f16dcb002135 100644
--- a/manager/eris-mint/state/tx_cache.go
+++ b/manager/eris-mint/state/tx_cache.go
@@ -1,12 +1,29 @@
+// 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 state
 
 import (
+	"fmt"
+
 	acm "github.com/eris-ltd/eris-db/account"
+	"github.com/eris-ltd/eris-db/common/sanity"
 	"github.com/eris-ltd/eris-db/manager/eris-mint/evm"
 	ptypes "github.com/eris-ltd/eris-db/permission/types" // for GlobalPermissionAddress ...
 	"github.com/eris-ltd/eris-db/txs"
+	. "github.com/eris-ltd/eris-db/word256"
 
-	. "github.com/tendermint/go-common"
 	"github.com/tendermint/go-crypto"
 )
 
@@ -16,6 +33,8 @@ type TxCache struct {
 	storages map[Tuple256]Word256
 }
 
+var _ vm.AppState = &TxCache{}
+
 func NewTxCache(backend *BlockCache) *TxCache {
 	return &TxCache{
 		backend:  backend,
@@ -44,7 +63,7 @@ func (cache *TxCache) UpdateAccount(acc *vm.Account) {
 	addr := acc.Address
 	_, removed := cache.accounts[addr].unpack()
 	if removed {
-		PanicSanity("UpdateAccount on a removed account")
+		sanity.PanicSanity("UpdateAccount on a removed account")
 	}
 	cache.accounts[addr] = vmAccountInfo{acc, false}
 }
@@ -53,7 +72,7 @@ func (cache *TxCache) RemoveAccount(acc *vm.Account) {
 	addr := acc.Address
 	_, removed := cache.accounts[addr].unpack()
 	if removed {
-		PanicSanity("RemoveAccount on a removed account")
+		sanity.PanicSanity("RemoveAccount on a removed account")
 	}
 	cache.accounts[addr] = vmAccountInfo{acc, true}
 }
@@ -85,7 +104,7 @@ func (cache *TxCache) CreateAccount(creator *vm.Account) *vm.Account {
 		return account
 	} else {
 		// either we've messed up nonce handling, or sha3 is broken
-		PanicSanity(Fmt("Could not create account, address already exists: %X", addr))
+		sanity.PanicSanity(fmt.Sprintf("Could not create account, address already exists: %X", addr))
 		return nil
 	}
 }
@@ -109,7 +128,7 @@ func (cache *TxCache) GetStorage(addr Word256, key Word256) Word256 {
 func (cache *TxCache) SetStorage(addr Word256, key Word256, value Word256) {
 	_, removed := cache.accounts[addr].unpack()
 	if removed {
-		PanicSanity("SetStorage() on a removed account")
+		sanity.PanicSanity("SetStorage() on a removed account")
 	}
 	cache.storages[Tuple256{addr, key}] = value
 }
diff --git a/manager/eris-mint/state/tx_cache_test.go b/manager/eris-mint/state/tx_cache_test.go
index a943ec72844fa37791c4771d78b5931231512ff4..4b30fa4a866b18475d467d2be8b3555bbba32796 100644
--- a/manager/eris-mint/state/tx_cache_test.go
+++ b/manager/eris-mint/state/tx_cache_test.go
@@ -1,3 +1,17 @@
+// 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 state
 
 import (
diff --git a/manager/eris-mint/state/types/genesis.go b/manager/eris-mint/state/types/genesis.go
deleted file mode 100644
index 806d701b29b2ce0daf3e9f5d99862917e7f8b5db..0000000000000000000000000000000000000000
--- a/manager/eris-mint/state/types/genesis.go
+++ /dev/null
@@ -1,61 +0,0 @@
-package types
-
-import (
-	"time"
-
-	ptypes "github.com/eris-ltd/eris-db/permission/types"
-	. "github.com/tendermint/go-common"
-	"github.com/tendermint/go-crypto"
-	"github.com/tendermint/go-wire"
-)
-
-//------------------------------------------------------------
-// we store the gendoc in the db
-
-var GenDocKey = []byte("GenDocKey")
-
-//------------------------------------------------------------
-// core types for a genesis definition
-
-type BasicAccount struct {
-	Address []byte `json:"address"`
-	Amount  int64  `json:"amount"`
-}
-
-type GenesisAccount struct {
-	Address     []byte                     `json:"address"`
-	Amount      int64                      `json:"amount"`
-	Name        string                     `json:"name"`
-	Permissions *ptypes.AccountPermissions `json:"permissions"`
-}
-
-type GenesisValidator struct {
-	PubKey   crypto.PubKey  `json:"pub_key"`
-	Amount   int64          `json:"amount"`
-	Name     string         `json:"name"`
-	UnbondTo []BasicAccount `json:"unbond_to"`
-}
-
-type GenesisParams struct {
-	GlobalPermissions *ptypes.AccountPermissions `json:"global_permissions"`
-}
-
-type GenesisDoc struct {
-	GenesisTime time.Time          `json:"genesis_time"`
-	ChainID     string             `json:"chain_id"`
-	Params      *GenesisParams     `json:"params"`
-	Accounts    []GenesisAccount   `json:"accounts"`
-	Validators  []GenesisValidator `json:"validators"`
-}
-
-//------------------------------------------------------------
-// Make genesis state from file
-
-func GenesisDocFromJSON(jsonBlob []byte) (genState *GenesisDoc) {
-	var err error
-	wire.ReadJSONPtr(&genState, jsonBlob, &err)
-	if err != nil {
-		Exit(Fmt("Couldn't read GenesisDoc: %v", err))
-	}
-	return
-}
diff --git a/manager/eris-mint/transactor.go b/manager/eris-mint/transactor.go
index 953c519f45a77caac632cbcefb0b5b35dacc9e2b..c29f51b59b7b27a31d3346a575827f034a053ae9 100644
--- a/manager/eris-mint/transactor.go
+++ b/manager/eris-mint/transactor.go
@@ -1,21 +1,17 @@
-// Copyright 2015, 2016 Eris Industries (UK) Ltd.
-// This file is part of Eris-RT
+// 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.
 
-// Eris-RT is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-
-// Eris-RT is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License
-// along with Eris-RT.  If not, see <http://www.gnu.org/licenses/>.
-
-// Transactor is part of the pipe for ErisMint and provides the implementation
-// for the pipe to call into the ErisMint application
 package erismint
 
 import (
@@ -25,18 +21,20 @@ import (
 	"sync"
 	"time"
 
-	cmn "github.com/tendermint/go-common"
-	"github.com/tendermint/go-crypto"
-	tEvents "github.com/tendermint/go-events"
-
 	"github.com/eris-ltd/eris-db/account"
 	core_types "github.com/eris-ltd/eris-db/core/types"
 	event "github.com/eris-ltd/eris-db/event"
 	"github.com/eris-ltd/eris-db/manager/eris-mint/evm"
 	"github.com/eris-ltd/eris-db/manager/eris-mint/state"
 	"github.com/eris-ltd/eris-db/txs"
+	"github.com/eris-ltd/eris-db/word256"
+
+	"github.com/tendermint/go-crypto"
+	tEvents "github.com/tendermint/go-events"
 )
 
+// Transactor is part of the pipe for ErisMint and provides the implementation
+// for the pipe to call into the ErisMint application
 type transactor struct {
 	chainID       string
 	eventSwitch   tEvents.Fireable
@@ -77,12 +75,12 @@ func (this *transactor) Call(fromAddress, toAddress, data []byte) (
 		fromAddress = []byte{}
 	}
 	callee := toVMAccount(outAcc)
-	caller := &vm.Account{Address: cmn.LeftPadWord256(fromAddress)}
+	caller := &vm.Account{Address: word256.LeftPadWord256(fromAddress)}
 	txCache := state.NewTxCache(cache)
 	gasLimit := st.GetGasLimit()
 	params := vm.Params{
 		BlockHeight: int64(st.LastBlockHeight),
-		BlockHash:   cmn.LeftPadWord256(st.LastBlockHash),
+		BlockHash:   word256.LeftPadWord256(st.LastBlockHash),
 		BlockTime:   st.LastBlockTime.Unix(),
 		GasLimit:    gasLimit,
 	}
@@ -108,14 +106,14 @@ func (this *transactor) CallCode(fromAddress, code, data []byte) (
 		fromAddress = []byte{}
 	}
 	cache := this.erisMint.GetCheckCache() // XXX: DON'T MUTATE THIS CACHE (used internally for CheckTx)
-	callee := &vm.Account{Address: cmn.LeftPadWord256(fromAddress)}
-	caller := &vm.Account{Address: cmn.LeftPadWord256(fromAddress)}
+	callee := &vm.Account{Address: word256.LeftPadWord256(fromAddress)}
+	caller := &vm.Account{Address: word256.LeftPadWord256(fromAddress)}
 	txCache := state.NewTxCache(cache)
 	st := this.erisMint.GetState() // for block height, time
 	gasLimit := st.GetGasLimit()
 	params := vm.Params{
 		BlockHeight: int64(st.LastBlockHeight),
-		BlockHash:   cmn.LeftPadWord256(st.LastBlockHash),
+		BlockHash:   word256.LeftPadWord256(st.LastBlockHash),
 		BlockTime:   st.LastBlockTime.Unix(),
 		GasLimit:    gasLimit,
 	}
@@ -424,7 +422,7 @@ func (this *transactor) SignTx(tx txs.Tx, privAccounts []*account.PrivAccount) (
 // No idea what this does.
 func toVMAccount(acc *account.Account) *vm.Account {
 	return &vm.Account{
-		Address: cmn.LeftPadWord256(acc.Address),
+		Address: word256.LeftPadWord256(acc.Address),
 		Balance: acc.Balance,
 		Code:    acc.Code,
 		Nonce:   int64(acc.Sequence),
diff --git a/manager/eris-mint/version.go b/manager/eris-mint/version.go
index 34cdb4b5324a9b8a52eeaa36334ffda0b01057b1..734e5cea30254f5e501a9b2461644eced8033e84 100644
--- a/manager/eris-mint/version.go
+++ b/manager/eris-mint/version.go
@@ -1,18 +1,16 @@
-// Copyright 2015, 2016 Eris Industries (UK) Ltd.
-// This file is part of Eris-RT
-
-// Eris-RT is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-
-// Eris-RT is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License
-// along with Eris-RT.  If not, see <http://www.gnu.org/licenses/>.
+// 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 erismint
 
@@ -28,7 +26,7 @@ const (
 	// Major version component of the current release
 	erisMintVersionMajor = 0
 	// Minor version component of the current release
-	erisMintVersionMinor = 12
+	erisMintVersionMinor = 16
 	// Patch version component of the current release
 	erisMintVersionPatch = 0
 )
@@ -36,8 +34,7 @@ const (
 // Define the compatible consensus engines this application manager
 // is compatible and has been tested with.
 var compatibleConsensus = [...]string{
-	"tendermint-0.6",
-	// "tmsp-0.6",
+	"tendermint-0.8",
 }
 
 func GetErisMintVersion() *version.VersionIdentifier {
diff --git a/manager/manager.go b/manager/manager.go
index 406648cd3ef36bc56857a55689c3b233870e633a..d9a3b3d548044fbedbcc70ed292fd0eecaed1efe 100644
--- a/manager/manager.go
+++ b/manager/manager.go
@@ -1,18 +1,16 @@
-// Copyright 2015, 2016 Eris Industries (UK) Ltd.
-// This file is part of Eris-RT
-
-// Eris-RT is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-
-// Eris-RT is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License
-// along with Eris-RT.  If not, see <http://www.gnu.org/licenses/>.
+// 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 manager
 
@@ -21,12 +19,13 @@ import (
 
 	events "github.com/tendermint/go-events"
 
-	log "github.com/eris-ltd/eris-logger"
-
 	config "github.com/eris-ltd/eris-db/config"
 	definitions "github.com/eris-ltd/eris-db/definitions"
 	erismint "github.com/eris-ltd/eris-db/manager/eris-mint"
 	// types       "github.com/eris-ltd/eris-db/manager/types"
+
+	"github.com/eris-ltd/eris-db/logging"
+	"github.com/eris-ltd/eris-db/logging/loggers"
 )
 
 // NewApplicationPipe returns an initialised Pipe interface
@@ -35,18 +34,18 @@ import (
 // of an application.  It is feasible this will be insufficient to support
 // different types of applications later down the line.
 func NewApplicationPipe(moduleConfig *config.ModuleConfig,
-	evsw *events.EventSwitch, consensusMinorVersion string) (definitions.Pipe,
+	evsw events.EventSwitch, logger loggers.InfoTraceLogger,
+	consensusMinorVersion string) (definitions.Pipe,
 	error) {
 	switch moduleConfig.Name {
 	case "erismint":
 		if err := erismint.AssertCompatibleConsensus(consensusMinorVersion); err != nil {
 			return nil, err
 		}
-		log.WithFields(log.Fields{
-			"compatibleConsensus": consensusMinorVersion,
-			"erisMintVersion":     erismint.GetErisMintVersion().GetVersionString(),
-		}).Debug("Loading ErisMint")
-		return erismint.NewErisMintPipe(moduleConfig, evsw)
+		logging.InfoMsg(logger, "Loading ErisMint",
+			"compatibleConsensus", consensusMinorVersion,
+			"erisMintVersion", erismint.GetErisMintVersion().GetVersionString())
+		return erismint.NewErisMintPipe(moduleConfig, evsw, logger)
 	}
 	return nil, fmt.Errorf("Failed to return Pipe for %s", moduleConfig.Name)
 }
diff --git a/manager/types/application.go b/manager/types/application.go
index cfcf2b82cc35cfc01c6b9da487f6908143183534..dbfe2b273bc5797b9ea9aec77e25b9c81e2b930a 100644
--- a/manager/types/application.go
+++ b/manager/types/application.go
@@ -1,26 +1,24 @@
-// Copyright 2015, 2016 Eris Industries (UK) Ltd.
-// This file is part of Eris-RT
-
-// Eris-RT is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-
-// Eris-RT is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License
-// along with Eris-RT.  If not, see <http://www.gnu.org/licenses/>.
+// 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 types
 
 import (
-	// TODO: [ben] this is currently only used for tmsp result type; but should
-	// be removed as tmsp dependencies shouldn't feature in the application
+	// TODO: [ben] this is currently only used for abci result type; but should
+	// be removed as abci dependencies shouldn't feature in the application
 	// manager
-	tmsp_types "github.com/tendermint/tmsp/types"
+	abci_types "github.com/tendermint/abci/types"
 )
 
 // NOTE: [ben] this interface is likely to be changed.  Currently it is taken
@@ -32,16 +30,16 @@ type Application interface {
 
 	// Info returns application information as a string
 	// NOTE: [ben] likely to move
-	Info() (info string)
+	Info() (info abci_types.ResponseInfo)
 
 	// Set application option (e.g. mode=mempool, mode=consensus)
 	// NOTE: [ben] taken from tendermint, but it is unclear what the use is,
-	// specifically, when will tendermint call this over tmsp ?
+	// specifically, when will tendermint call this over abci ?
 	SetOption(key string, value string) (log string)
 
 	// Append transaction applies a transaction to the state regardless of
 	// whether the transaction is valid or not.
-	// Currently AppendTx is taken from tmsp, and returns a result.
+	// Currently AppendTx is taken from abci, and returns a result.
 	// This will be altered, as AppendTransaction needs to more strongly reflect
 	// the theoretical logic:
 	//   Append(StateN, Transaction) = StateN+1
@@ -51,18 +49,18 @@ type Application interface {
 	// TODO: implementation notes:
 	// 1. at this point the transaction should already be strongly typed
 	// 2.
-	AppendTx(tx []byte) tmsp_types.Result
+	DeliverTx(tx []byte) abci_types.Result
 
 	// Check Transaction validates a transaction before being allowed into the
 	// consensus' engine memory pool.  This is the original defintion and
-	// intention as taken from tmsp, but should be remapped to the more
+	// intention as taken from abci, but should be remapped to the more
 	// general concept of basic, cheap verification;
 	// Check Transaction does not alter the state, but does require an immutable
 	// copy of the state. In particular there is no consensus on ordering yet.
 	// TODO: implementation notes:
 	// 1. at this point the transaction should already be strongly typed
 	// 2.
-	CheckTx(tx []byte) tmsp_types.Result
+	CheckTx(tx []byte) abci_types.Result
 
 	// Commit returns the root hash of the current application state
 	// NOTE: [ben] Because the concept of the block has been erased here
@@ -70,14 +68,14 @@ type Application interface {
 	// the opposit the principle of explicit stateless functions.
 	// This will be amended when we introduce the concept of (streaming)
 	// blocks in the pipe.
-	Commit() tmsp_types.Result
+	Commit() abci_types.Result
 
 	// Query for state.  This query request is not passed over the p2p network
 	// and is called from Tendermint rpc directly up to the application.
 	// NOTE: [ben] Eris-DB will give preference to queries from the local client
 	// directly over the Eris-DB rpc.
 	// We will support this for Tendermint compatibility.
-	Query(query []byte) tmsp_types.Result
+	Query(query []byte) abci_types.Result
 }
 
 // Tendermint has a separate interface for reintroduction of blocks
@@ -85,7 +83,7 @@ type BlockchainAware interface {
 
 	// Initialise the blockchain
 	// validators: genesis validators from tendermint core
-	InitChain(validators []*tmsp_types.Validator)
+	InitChain(validators []*abci_types.Validator)
 
 	// Signals the beginning of a block;
 	// NOTE: [ben] currently not supported by tendermint
@@ -95,5 +93,5 @@ type BlockchainAware interface {
 	// validators: changed validators from app to Tendermint
 	// NOTE: [ben] currently not supported by tendermint
 	// not yet well defined what the change set contains.
-	EndBlock(height uint64) (validators []*tmsp_types.Validator)
+	EndBlock(height uint64) (validators []*abci_types.Validator)
 }
diff --git a/permission/types/errors.go b/permission/types/errors.go
index 4b1d7cb945a40bcc614546ea08587c6478c90c23..fe023ca8e4a2a4e0817a9a85961981b5f8dba745 100644
--- a/permission/types/errors.go
+++ b/permission/types/errors.go
@@ -1,3 +1,17 @@
+// 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 types
 
 import (
diff --git a/permission/types/permissions.go b/permission/types/permissions.go
index 5cdcdaf8ca1e8ba4f5a2e605ed90f3521c757740..94f31e31888311f1bc21a2b3d9771b8b191d071d 100644
--- a/permission/types/permissions.go
+++ b/permission/types/permissions.go
@@ -1,16 +1,31 @@
+// 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 types
 
 import (
 	"fmt"
+	"strings"
 
-	. "github.com/tendermint/go-common"
+	"github.com/eris-ltd/eris-db/word256"
 )
 
 //------------------------------------------------------------------------------------------------
 
 var (
-	GlobalPermissionsAddress    = Zero256[:20]
-	GlobalPermissionsAddress256 = Zero256
+	GlobalPermissionsAddress    = word256.Zero256[:20]
+	GlobalPermissionsAddress256 = word256.Zero256
 )
 
 // A particular permission
@@ -112,6 +127,12 @@ func (p *BasePermissions) IsSet(ty PermFlag) bool {
 	return p.SetBit&ty > 0
 }
 
+// Returns the Perms PermFlag masked with SetBit bit field to give the resultant
+// permissions enabled by this BasePermissions
+func (p *BasePermissions) ResultantPerms() PermFlag {
+	return p.Perms & p.SetBit
+}
+
 func (p BasePermissions) String() string {
 	return fmt.Sprintf("Base: %b; Set: %b", p.Perms, p.SetBit)
 }
@@ -125,7 +146,7 @@ type AccountPermissions struct {
 
 // Returns true if the role is found
 func (aP *AccountPermissions) HasRole(role string) bool {
-	role = string(RightPadBytes([]byte(role), 32))
+	role = string(word256.RightPadBytes([]byte(role), 32))
 	for _, r := range aP.Roles {
 		if r == role {
 			return true
@@ -136,7 +157,7 @@ func (aP *AccountPermissions) HasRole(role string) bool {
 
 // Returns true if the role is added, and false if it already exists
 func (aP *AccountPermissions) AddRole(role string) bool {
-	role = string(RightPadBytes([]byte(role), 32))
+	role = string(word256.RightPadBytes([]byte(role), 32))
 	for _, r := range aP.Roles {
 		if r == role {
 			return false
@@ -148,7 +169,7 @@ func (aP *AccountPermissions) AddRole(role string) bool {
 
 // Returns true if the role is removed, and false if it is not found
 func (aP *AccountPermissions) RmRole(role string) bool {
-	role = string(RightPadBytes([]byte(role), 32))
+	role = string(word256.RightPadBytes([]byte(role), 32))
 	for i, r := range aP.Roles {
 		if r == role {
 			post := []string{}
@@ -162,6 +183,21 @@ func (aP *AccountPermissions) RmRole(role string) bool {
 	return false
 }
 
+// Clone clones the account permissions
+func (accountPermissions *AccountPermissions) Clone() AccountPermissions {
+	// clone base permissions
+	basePermissionsClone := accountPermissions.Base
+	// clone roles []string
+	rolesClone := make([]string, len(accountPermissions.Roles))
+	// strings are immutable so copy suffices
+	copy(rolesClone, accountPermissions.Roles)
+
+	return AccountPermissions{
+		Base:  basePermissionsClone,
+		Roles: rolesClone,
+	}
+}
+
 //--------------------------------------------------------------------------------
 // string utilities
 
@@ -183,54 +219,56 @@ func PermFlagToString(pf PermFlag) (perm string) {
 	case Name:
 		perm = "name"
 	case HasBase:
-		perm = "has_base"
+		perm = "hasBase"
 	case SetBase:
-		perm = "set_base"
+		perm = "setBase"
 	case UnsetBase:
-		perm = "unset_base"
+		perm = "unsetBase"
 	case SetGlobal:
-		perm = "set_global"
+		perm = "setGlobal"
 	case HasRole:
-		perm = "has_role"
+		perm = "hasRole"
 	case AddRole:
-		perm = "add_role"
+		perm = "addRole"
 	case RmRole:
-		perm = "rm_role"
+		perm = "removeRole"
 	default:
 		perm = "#-UNKNOWN-#"
 	}
 	return
 }
 
+// PermStringToFlag maps camel- and snake case strings to the
+// the corresponding permission flag.
 func PermStringToFlag(perm string) (pf PermFlag, err error) {
-	switch perm {
+	switch strings.ToLower(perm) {
 	case "root":
 		pf = Root
 	case "send":
 		pf = Send
 	case "call":
 		pf = Call
-	case "create_contract":
+	case "createcontract", "create_contract":
 		pf = CreateContract
-	case "create_account":
+	case "createaccount", "create_account":
 		pf = CreateAccount
 	case "bond":
 		pf = Bond
 	case "name":
 		pf = Name
-	case "has_base":
+	case "hasbase", "has_base":
 		pf = HasBase
-	case "set_base":
+	case "setbase", "set_base":
 		pf = SetBase
-	case "unset_base":
+	case "unsetbase", "unset_base":
 		pf = UnsetBase
-	case "set_global":
+	case "setglobal", "set_global":
 		pf = SetGlobal
-	case "has_role":
+	case "hasrole", "has_role":
 		pf = HasRole
-	case "add_role":
+	case "addrole", "add_role":
 		pf = AddRole
-	case "rm_role":
+	case "removerole", "rmrole", "rm_role":
 		pf = RmRole
 	default:
 		err = fmt.Errorf("Unknown permission %s", perm)
diff --git a/permission/types/snatives.go b/permission/types/snatives.go
index 57315ac937f1c6a58a97410d3f8fe5a0045b3dcd..f7fe543affd37a0435192f10490db99aa89ffdfd 100644
--- a/permission/types/snatives.go
+++ b/permission/types/snatives.go
@@ -1,3 +1,17 @@
+// 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 types
 
 import (
@@ -25,6 +39,10 @@ const (
 	PermArgsTypeRmRole    = byte(0x07)
 )
 
+// TODO: [ben] this registration needs to be lifted up
+// and centralised in core; here it pulls in go-wire dependency
+// while it suffices to have the type bytes defined;
+// ---
 // for wire.readReflect
 var _ = wire.RegisterInterface(
 	struct{ PermArgs }{},
diff --git a/permission/types/util.go b/permission/types/util.go
new file mode 100644
index 0000000000000000000000000000000000000000..fddf0b9eb2b161b1f4df36733afcba29c429ae75
--- /dev/null
+++ b/permission/types/util.go
@@ -0,0 +1,49 @@
+// 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 types
+
+// ConvertMapStringIntToPermissions converts a map of string-integer pairs and a slice of
+// strings for the roles to an AccountPermissions type.  The integer needs to be greater
+// than zero to set the permission.  For all unmentioned permissions the ZeroBasePermissions
+// is defaulted to.
+// TODO: [ben] re-evaluate the use of int for setting the permission.
+func ConvertPermissionsMapAndRolesToAccountPermissions(permissions map[string]int, roles []string) (*AccountPermissions, error) {
+	var err error
+	accountPermissions := &AccountPermissions{}
+	accountPermissions.Base, err = convertPermissionsMapStringIntToBasePermissions(permissions)
+	if err != nil {
+		return nil, err
+	}
+	accountPermissions.Roles = roles
+	return accountPermissions, nil
+}
+
+// convertPermissionsMapStringIntToBasePermissions converts a map of string-integer pairs to
+// BasePermissions.
+func convertPermissionsMapStringIntToBasePermissions(permissions map[string]int) (BasePermissions, error) {
+	// initialise basePermissions as ZeroBasePermissions
+	basePermissions := ZeroBasePermissions
+
+	for permissionName, value := range permissions {
+		permissionsFlag, err := PermStringToFlag(permissionName)
+		if err != nil {
+			return basePermissions, err
+		}
+		// sets the permissions bitflag and the setbit flag for the permission.
+		basePermissions.Set(permissionsFlag, value > 0)
+	}
+
+	return basePermissions, nil
+}
diff --git a/rpc/codec.go b/rpc/codec.go
index d6fa05bb1a23917d474e760804cd83052c50032f..750a5a88e8a6ea672fe635ef41c2f69d2c36274d 100644
--- a/rpc/codec.go
+++ b/rpc/codec.go
@@ -1,3 +1,17 @@
+// 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 (
@@ -9,5 +23,6 @@ type Codec interface {
 	EncodeBytes(interface{}) ([]byte, error)
 	Encode(interface{}, io.Writer) error
 	DecodeBytes(interface{}, []byte) error
+	DecodeBytesPtr(interface{}, []byte) error
 	Decode(interface{}, io.Reader) error
 }
diff --git a/rpc/jsonrpc.go b/rpc/jsonrpc.go
index 72115138ad53350c8619c1fdce1ba67720e78a17..fc04317a43ebd77faa3850e9f781fedb1e627143 100644
--- a/rpc/jsonrpc.go
+++ b/rpc/jsonrpc.go
@@ -1,3 +1,17 @@
+// 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 (
@@ -14,6 +28,7 @@ const (
 )
 
 // Request and Response objects. Id is a string. Error data not used.
+// Refer to JSON-RPC specification http://www.jsonrpc.org/specification
 type (
 	RPCRequest struct {
 		JSONRPC string          `json:"jsonrpc"`
@@ -22,35 +37,61 @@ type (
 		Id      string          `json:"id"`
 	}
 
-	RPCResponse struct {
+	// RPCResponse MUST follow the JSON-RPC specification for Response object
+	// reference: http://www.jsonrpc.org/specification#response_object
+	RPCResponse interface {
+		AssertIsRPCResponse() bool
+	}
+
+	// RPCResultResponse MUST NOT contain the error member if no error occurred
+	RPCResultResponse struct {
 		Result  interface{} `json:"result"`
-		Error   *RPCError   `json:"error"`
 		Id      string      `json:"id"`
 		JSONRPC string      `json:"jsonrpc"`
 	}
 
+	// RPCErrorResponse MUST NOT contain the result member if an error occured
+	RPCErrorResponse struct {
+		Error   *RPCError `json:"error"`
+		Id      string    `json:"id"`
+		JSONRPC string    `json:"jsonrpc"`
+	}
+
+	// RPCError MUST be included in the Response object if an error occured
 	RPCError struct {
 		Code    int    `json:"code"`
 		Message string `json:"message"`
+		// Note: Data is currently unused, and the data member may be omitted
+		// Data  interface{} `json:"data"`
 	}
 )
 
-// Create a new response object from a result.
-func NewRPCResponse(id string, res interface{}) *RPCResponse {
-	return &RPCResponse{
+// NewRPCResponse creates a new response object from a result
+func NewRPCResponse(id string, res interface{}) RPCResponse {
+	return RPCResponse(&RPCResultResponse{
 		Result:  res,
-		Error:   nil,
 		Id:      id,
 		JSONRPC: "2.0",
-	}
+	})
 }
 
-// Create a new error-response object from the error code and message.
-func NewRPCErrorResponse(id string, code int, message string) *RPCResponse {
-	return &RPCResponse{
-		Result:  nil,
+// NewRPCErrorResponse creates a new error-response object from the error code and message
+func NewRPCErrorResponse(id string, code int, message string) RPCResponse {
+	return RPCResponse(&RPCErrorResponse{
 		Error:   &RPCError{code, message},
 		Id:      id,
 		JSONRPC: "2.0",
-	}
+	})
+}
+
+// AssertIsRPCResponse implements a marker method for RPCResultResponse
+// to implement the interface RPCResponse
+func (rpcResultResponse *RPCResultResponse) AssertIsRPCResponse() bool {
+	return true
+}
+
+// AssertIsRPCResponse implements a marker method for RPCErrorResponse
+// to implement the interface RPCResponse
+func (rpcErrorResponse *RPCErrorResponse) AssertIsRPCResponse() bool {
+	return true
 }
diff --git a/rpc/rpc_test.go b/rpc/rpc_test.go
index f728d822bd1251f9147aaeac9e199672b7092d25..fbdfca374c8cd4a764ea064d06e74ce5b5ca0e4b 100644
--- a/rpc/rpc_test.go
+++ b/rpc/rpc_test.go
@@ -1,3 +1,17 @@
+// 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 (
@@ -10,12 +24,11 @@ import (
 func TestNewJsonRpcResponse(t *testing.T) {
 	id := "testId"
 	data := "a string"
-	resp := &RPCResponse{
+	resp := RPCResponse(&RPCResultResponse{
 		Result:  data,
-		Error:   nil,
 		Id:      id,
 		JSONRPC: "2.0",
-	}
+	})
 	respGen := NewRPCResponse(id, data)
 	assert.Equal(t, respGen, resp)
 }
@@ -25,12 +38,11 @@ func TestNewJsonRpcErrorResponse(t *testing.T) {
 	id := "testId"
 	code := 100
 	message := "the error"
-	resp := &RPCResponse{
-		Result:  nil,
+	resp := RPCResponse(&RPCErrorResponse{
 		Error:   &RPCError{code, message},
 		Id:      id,
 		JSONRPC: "2.0",
-	}
+	})
 	respGen := NewRPCErrorResponse(id, code, message)
 	assert.Equal(t, respGen, resp)
 }
diff --git a/rpc/tendermint/client/client.go b/rpc/tendermint/client/client.go
index 3afe9c606858987803a5a928f69955880781b60a..978c5a1fd99fcbf28f56e86ed0de3b629d7df656 100644
--- a/rpc/tendermint/client/client.go
+++ b/rpc/tendermint/client/client.go
@@ -1,3 +1,17 @@
+// 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 (
diff --git a/rpc/tendermint/client/client_test.go b/rpc/tendermint/client/client_test.go
index 2580508d828b88b457cc683f78a21c145aee5e9b..105a9d2b92fddd75508c9eadbe209859fbf88b44 100644
--- a/rpc/tendermint/client/client_test.go
+++ b/rpc/tendermint/client/client_test.go
@@ -1,8 +1,23 @@
+// 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 (
-	"github.com/stretchr/testify/assert"
 	"testing"
+
+	"github.com/stretchr/testify/assert"
 )
 
 func TestMapsAndValues(t *testing.T) {
@@ -30,5 +45,4 @@ func TestMapsAndValues(t *testing.T) {
 
 	_, _, err = mapAndValues("Foo", 4, 4, "Bar")
 	assert.Error(t, err, "Should be an error to provide non-string keys")
-
 }
diff --git a/rpc/tendermint/core/routes.go b/rpc/tendermint/core/routes.go
index 718c628ec7d3bb15f03ccc03f2d2cf68cf27c388..76df394f4c144ee0eb41a7fce621a9623c489470 100644
--- a/rpc/tendermint/core/routes.go
+++ b/rpc/tendermint/core/routes.go
@@ -1,3 +1,17 @@
+// 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 core
 
 import (
diff --git a/rpc/tendermint/core/types/responses.go b/rpc/tendermint/core/types/responses.go
index c6494d919f3868507d562eeb3c0f0c30aa831f2e..220ace4b49328834bd4393453f3055f03aed4880 100644
--- a/rpc/tendermint/core/types/responses.go
+++ b/rpc/tendermint/core/types/responses.go
@@ -1,18 +1,32 @@
+// 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 types
 
 import (
 	acm "github.com/eris-ltd/eris-db/account"
 	core_types "github.com/eris-ltd/eris-db/core/types"
-	stypes "github.com/eris-ltd/eris-db/manager/eris-mint/state/types"
+	genesis "github.com/eris-ltd/eris-db/genesis"
 	"github.com/eris-ltd/eris-db/txs"
 	tendermint_types "github.com/tendermint/tendermint/types"
 
 	consensus_types "github.com/eris-ltd/eris-db/consensus/types"
+	abcitypes "github.com/tendermint/abci/types"
 	"github.com/tendermint/go-crypto"
 	"github.com/tendermint/go-p2p"
 	"github.com/tendermint/go-rpc/types"
 	"github.com/tendermint/go-wire"
-	tmsptypes "github.com/tendermint/tmsp/types"
 )
 
 type ResultGetStorage struct {
@@ -111,7 +125,7 @@ type ResultGetAccount struct {
 }
 
 type ResultBroadcastTx struct {
-	Code tmsptypes.CodeType `json:"code"`
+	Code abcitypes.CodeType `json:"code"`
 	Data []byte             `json:"data"`
 	Log  string             `json:"log"`
 }
@@ -126,7 +140,7 @@ type ResultGetName struct {
 }
 
 type ResultGenesis struct {
-	Genesis *stypes.GenesisDoc `json:"genesis"`
+	Genesis *genesis.GenesisDoc `json:"genesis"`
 }
 
 type ResultSignTx struct {
diff --git a/rpc/tendermint/core/types/responses_test.go b/rpc/tendermint/core/types/responses_test.go
index bf009eab11b57c3dd3df384f8cf903c3ae2f01a4..73e5e97d98d603bebe019042cf7992e569121db0 100644
--- a/rpc/tendermint/core/types/responses_test.go
+++ b/rpc/tendermint/core/types/responses_test.go
@@ -1,3 +1,17 @@
+// 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 types
 
 import (
diff --git a/rpc/tendermint/core/types/responses_util.go b/rpc/tendermint/core/types/responses_util.go
index 13b21a1451f404e9b681a6699b256138ab3ebbe9..6e0bf52eae97e0795b4f4e4612cea5251e88aaa4 100644
--- a/rpc/tendermint/core/types/responses_util.go
+++ b/rpc/tendermint/core/types/responses_util.go
@@ -1,18 +1,16 @@
-// Copyright 2015, 2016 Eris Industries (UK) Ltd.
-// This file is part of Eris-RT
-
-// Eris-RT is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-
-// Eris-RT is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License
-// along with Eris-RT.  If not, see <http://www.gnu.org/licenses/>.
+// 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 types
 
diff --git a/rpc/tendermint/core/websocket.go b/rpc/tendermint/core/websocket.go
index 6824b78e052becb787ccf8092870cb4a73b37c2a..6bc85f4d053a2488357ebd9ff0e8843163637435 100644
--- a/rpc/tendermint/core/websocket.go
+++ b/rpc/tendermint/core/websocket.go
@@ -1,18 +1,16 @@
-// Copyright 2015, 2016 Eris Industries (UK) Ltd.
-// This file is part of Eris-RT
-
-// Eris-RT is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-
-// Eris-RT is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License
-// along with Eris-RT.  If not, see <http://www.gnu.org/licenses/>.
+// 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 core
 
@@ -35,7 +33,7 @@ type TendermintWebsocketServer struct {
 }
 
 func NewTendermintWebsocketServer(config *server.ServerConfig,
-	tendermintPipe definitions.TendermintPipe, evsw *events.EventSwitch) (
+	tendermintPipe definitions.TendermintPipe, evsw events.EventSwitch) (
 	*TendermintWebsocketServer, error) {
 
 	if tendermintPipe == nil {
diff --git a/rpc/tendermint/test/common.go b/rpc/tendermint/test/common.go
index 76909182df98801eab3e08db5b5c4bbfd03617cf..8151401f60dfa76dc6108753db7069f4dbdcbf82 100644
--- a/rpc/tendermint/test/common.go
+++ b/rpc/tendermint/test/common.go
@@ -1,11 +1,24 @@
-// +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 test
 
 import (
 	"fmt"
 
+	vm "github.com/eris-ltd/eris-db/manager/eris-mint/evm"
 	rpc_core "github.com/eris-ltd/eris-db/rpc/tendermint/core"
 	"github.com/eris-ltd/eris-db/test/fixtures"
 )
@@ -17,6 +30,7 @@ func TestWrapper(runner func() int) int {
 
 	defer ffs.RemoveAll()
 
+	vm.SetDebug(true)
 	err := initGlobalVariables(ffs)
 
 	if err != nil {
diff --git a/rpc/tendermint/test/common_test.go b/rpc/tendermint/test/common_test.go
index aabfc84f3388060f1831a623812e097eef74dbf2..5b2a1455c161aa75320800e5c89180554b91e1f5 100644
--- a/rpc/tendermint/test/common_test.go
+++ b/rpc/tendermint/test/common_test.go
@@ -1,6 +1,20 @@
 // +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 test
 
 import (
diff --git a/rpc/tendermint/test/config.go b/rpc/tendermint/test/config.go
index ff33cb30f4aca019aea9a400e434e7539a786bb9..84fcaeb7997c7b31cc45843d65a1fde9785963c9 100644
--- a/rpc/tendermint/test/config.go
+++ b/rpc/tendermint/test/config.go
@@ -1,20 +1,32 @@
+// 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 test
 
-var defaultConfig = `# Copyright 2015, 2016 Eris Industries (UK) Ltd.
-# This file is part of Eris-RT
-#
-# Eris-RT is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
+var defaultConfig = `# 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
 #
-# Eris-RT is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
+#    http://www.apache.org/licenses/LICENSE-2.0
 #
-# You should have received a copy of the GNU General Public License
-# along with Eris-RT.  If not, see <http://www.gnu.org/licenses/>.
+# 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..
 
 # This is a TOML configuration for Eris-DB chains
 
@@ -40,12 +52,12 @@ genesis_file = "genesis.json"
   [chain.consensus]
   # consensus defines the module to use for consensus and
   # this will define the peer-to-peer consensus network;
-  # accepted values are "noops", "tmsp", "tendermint"
+  # accepted values are "noops", "abci", "tendermint"
   name = "tendermint"
   # version is the major and minor semantic version;
   # the version will be asserted on
   major_version = 0
-  minor_version = 6
+  minor_version = 8
   # relative path to consensus' module root folder
   relative_root = "tendermint"
 
@@ -61,7 +73,7 @@ genesis_file = "genesis.json"
   # version is the major and minor semantic version;
   # the version will be asserted on
   major_version = 0
-  minor_version = 12
+  minor_version = 16
   # relative path to application manager root folder
   relative_root = "erismint"
 
@@ -123,21 +135,19 @@ genesis_file = "genesis.json"
 
 ################################################################################
 ##
-## Tendermint Socket Protocol (TMSP)
-## version 0.6.0
+## Tendermint Socket Protocol (abci)
 ##
-## TMSP expects a tendermint consensus process to run and connect to Eris-DB
+## abci expects a tendermint consensus process to run and connect to Eris-DB
 ##
 ################################################################################
 
-[tmsp]
+[abci]
 # listener address for accepting tendermint socket protocol connections
 listener = "tcp://0.0.0.0:46658"
 
 ################################################################################
-##
+##yeah we had partial support for that with TMSP
 ## Tendermint
-## version 0.6.0
 ##
 ## in-process execution of Tendermint consensus engine
 ##
@@ -174,7 +184,7 @@ private_validator_file = "priv_validator.json"
 	# NOTE: value is ignored when run in-process as RPC is
 	# handled by [servers.tendermint]
   rpc_laddr = ""
-  # proxy application address - used for tmsp connections,
+  # proxy application address - used for abci connections,
   # and this port should not be exposed for in-process Tendermint
   proxy_app = "tcp://127.0.0.1:46658"
 
@@ -207,7 +217,7 @@ private_validator_file = "priv_validator.json"
 ################################################################################
 ##
 ## Eris-Mint
-## version 0.12.0
+## version 0.16.0
 ##
 ## The original Ethereum virtual machine with IAVL merkle trees
 ## and tendermint/go-wire encoding
diff --git a/rpc/tendermint/test/genesis.go b/rpc/tendermint/test/genesis.go
index 3136a9339323cbfd1f5508daae335de335c9ef10..9ca0e6e83c0575b733b841f0af44402adc83d19d 100644
--- a/rpc/tendermint/test/genesis.go
+++ b/rpc/tendermint/test/genesis.go
@@ -1,3 +1,17 @@
+// 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 test
 
 // priv keys generated deterministically eg rpc/tests/shared.go
diff --git a/rpc/tendermint/test/rpc_client_test.go b/rpc/tendermint/test/rpc_client_test.go
index 7183f2df8f1effbafe76705e344fd1658c01852a..d53ff9d713ffcee49a4646c7d303fd55a42a51ec 100644
--- a/rpc/tendermint/test/rpc_client_test.go
+++ b/rpc/tendermint/test/rpc_client_test.go
@@ -1,22 +1,35 @@
 // +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 test
 
 import (
 	"bytes"
 	"fmt"
-	"testing"
-
 	"golang.org/x/crypto/ripemd160"
-
+	"testing"
 	"time"
 
 	consensus_types "github.com/eris-ltd/eris-db/consensus/types"
 	edbcli "github.com/eris-ltd/eris-db/rpc/tendermint/client"
 	"github.com/eris-ltd/eris-db/txs"
+	"github.com/eris-ltd/eris-db/word256"
+
 	"github.com/stretchr/testify/assert"
-	tm_common "github.com/tendermint/go-common"
 	rpcclient "github.com/tendermint/go-rpc/client"
 	_ "github.com/tendermint/tendermint/config/tendermint_test"
 )
@@ -123,8 +136,8 @@ func TestGetStorage(t *testing.T) {
 			" created a contract but the contract address is empty")
 
 		v := getStorage(t, client, contractAddr, []byte{0x1})
-		got := tm_common.LeftPadWord256(v)
-		expected := tm_common.LeftPadWord256([]byte{0x5})
+		got := word256.LeftPadWord256(v)
+		expected := word256.LeftPadWord256([]byte{0x5})
 		if got.Compare(expected) != 0 {
 			t.Fatalf("Wrong storage value. Got %x, expected %x", got.Bytes(),
 				expected.Bytes())
@@ -148,8 +161,8 @@ func TestCallCode(t *testing.T) {
 		// 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(tm_common.LeftPadWord256([]byte{0x5}).Bytes(),
-			tm_common.LeftPadWord256([]byte{0x6}).Bytes()...)
+		data = append(word256.LeftPadWord256([]byte{0x5}).Bytes(),
+			word256.LeftPadWord256([]byte{0x6}).Bytes()...)
 		expected = []byte{0xb}
 		callCode(t, client, user[0].PubKey.Address(), code, data, expected)
 	})
@@ -279,6 +292,8 @@ func TestNameReg(t *testing.T) {
 func TestBlockchainInfo(t *testing.T) {
 	wsc := newWSClient()
 	testWithAllClients(t, func(t *testing.T, clientName string, client rpcclient.Client) {
+		// 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)
 
@@ -286,20 +301,25 @@ func TestBlockchainInfo(t *testing.T) {
 		if err != nil {
 			t.Fatalf("Failed to get blockchain info: %v", err)
 		}
-		//TODO: [Silas] reintroduce this when Tendermint changes logic to fire
-		// NewBlock after saving a block
-		// see https://github.com/tendermint/tendermint/issues/273
-		//assert.Equal(t, 4, resp.LastHeight, "Last height should be 4 after waiting for first 4 blocks")
+		lastBlockHeight := resp.LastHeight
+		nMetaBlocks := len(resp.BlockMetas)
+		assert.True(t, 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 4 BlockMetas after waiting for first 4 blocks")
-
-		lastBlockHash := resp.BlockMetas[nBlocks-1].Hash
-		for i := nBlocks - 2; i >= 0; i-- {
-			assert.Equal(t, lastBlockHash, resp.BlockMetas[i].Header.LastBlockHash,
+			"Should see at least 4 BlockMetas after waiting for 4 blocks")
+		// For the maximum number (default to 20) of retrieved block headers,
+		// check that they correctly chain to each other.
+		lastBlockHash := resp.BlockMetas[nMetaBlocks-1].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].Hash
 		}
 
+		// Now retrieve only two blockheaders (h=1, and h=2) and check that we got
+		// two results.
 		resp, err = edbcli.BlockchainInfo(client, 1, 2)
 		assert.NoError(t, err)
 		assert.Equal(t, 2, len(resp.BlockMetas),
diff --git a/rpc/tendermint/test/runner/main.go b/rpc/tendermint/test/runner/main.go
index a6836357833531d32e6218ff5001b58adb37505e..a47649dad23f61cb7c4457c3499896984182014b 100644
--- a/rpc/tendermint/test/runner/main.go
+++ b/rpc/tendermint/test/runner/main.go
@@ -1,6 +1,20 @@
 // +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 main
 
 import (
diff --git a/rpc/tendermint/test/shared.go b/rpc/tendermint/test/shared.go
index d211bd5d11c6fd7c078ce12665366f0a48d0a134..98044412e36986d6cbf302c75b1fc6b21e4d9c9c 100644
--- a/rpc/tendermint/test/shared.go
+++ b/rpc/tendermint/test/shared.go
@@ -1,29 +1,42 @@
+// 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 test
 
 import (
 	"bytes"
 	"hash/fnv"
+	"path"
 	"strconv"
 	"testing"
 
 	acm "github.com/eris-ltd/eris-db/account"
 	"github.com/eris-ltd/eris-db/core"
 	core_types "github.com/eris-ltd/eris-db/core/types"
+	"github.com/eris-ltd/eris-db/logging/lifecycle"
 	edbcli "github.com/eris-ltd/eris-db/rpc/tendermint/client"
 	rpc_core "github.com/eris-ltd/eris-db/rpc/tendermint/core"
 	rpc_types "github.com/eris-ltd/eris-db/rpc/tendermint/core/types"
 	"github.com/eris-ltd/eris-db/server"
 	"github.com/eris-ltd/eris-db/test/fixtures"
 	"github.com/eris-ltd/eris-db/txs"
+	"github.com/eris-ltd/eris-db/word256"
 
+	genesis "github.com/eris-ltd/eris-db/genesis"
+	"github.com/spf13/viper"
 	"github.com/tendermint/go-crypto"
 	rpcclient "github.com/tendermint/go-rpc/client"
-
-	"path"
-
-	state_types "github.com/eris-ltd/eris-db/manager/eris-mint/state/types"
-	"github.com/spf13/viper"
-	tm_common "github.com/tendermint/go-common"
 	"github.com/tendermint/tendermint/types"
 )
 
@@ -34,7 +47,7 @@ var (
 	mempoolCount      = 0
 	chainID           string
 	websocketAddr     string
-	genesisDoc        *state_types.GenesisDoc
+	genesisDoc        *genesis.GenesisDoc
 	websocketEndpoint string
 	user              = makeUsers(5) // make keys
 	jsonRpcClient     rpcclient.Client
@@ -49,7 +62,7 @@ func initGlobalVariables(ffs *fixtures.FileFixtures) error {
 	rootWorkDir = ffs.AddDir("rootWorkDir")
 	rootDataDir := ffs.AddDir("rootDataDir")
 	genesisFile := ffs.AddFile("rootWorkDir/genesis.json", defaultGenesis)
-	genesisDoc = state_types.GenesisDocFromJSON([]byte(defaultGenesis))
+	genesisDoc = genesis.GenesisDocFromJSON([]byte(defaultGenesis))
 
 	if ffs.Error != nil {
 		return ffs.Error
@@ -83,7 +96,14 @@ func initGlobalVariables(ffs *fixtures.FileFixtures) error {
 	// Set up priv_validator.json before we start tendermint (otherwise it will
 	// create its own one.
 	saveNewPriv()
-	testCore, err = core.NewCore("testCore", consensusConfig, managerConfig)
+	logger := lifecycle.NewStdErrLogger()
+	// To spill tendermint logs on the floor:
+	// lifecycle.CaptureTendermintLog15Output(loggers.NewNoopInfoTraceLogger())
+	lifecycle.CaptureTendermintLog15Output(logger)
+	lifecycle.CaptureStdlibLogOutput(logger)
+
+	testCore, err = core.NewCore("testCore", consensusConfig, managerConfig,
+		logger)
 	if err != nil {
 		return err
 	}
@@ -234,7 +254,7 @@ func callCode(t *testing.T, client rpcclient.Client, fromAddress, code, data,
 	}
 	ret := resp.Return
 	// NOTE: we don't flip memory when it comes out of RETURN (?!)
-	if bytes.Compare(ret, tm_common.LeftPadWord256(expected).Bytes()) != 0 {
+	if bytes.Compare(ret, word256.LeftPadWord256(expected).Bytes()) != 0 {
 		t.Fatalf("Conflicting return value. Got %x, expected %x", ret, expected)
 	}
 }
@@ -247,7 +267,7 @@ func callContract(t *testing.T, client rpcclient.Client, fromAddress, toAddress,
 	}
 	ret := resp.Return
 	// NOTE: we don't flip memory when it comes out of RETURN (?!)
-	if bytes.Compare(ret, tm_common.LeftPadWord256(expected).Bytes()) != 0 {
+	if bytes.Compare(ret, word256.LeftPadWord256(expected).Bytes()) != 0 {
 		t.Fatalf("Conflicting return value. Got %x, expected %x", ret, expected)
 	}
 }
@@ -286,14 +306,14 @@ func simpleContract() ([]byte, []byte, []byte) {
 	// push code to the stack
 	//code := append([]byte{byte(0x60 + lenCode - 1)}, RightPadWord256(contractCode).Bytes()...)
 	code := append([]byte{0x7f},
-		tm_common.RightPadWord256(contractCode).Bytes()...)
+		word256.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, tm_common.LeftPadBytes([]byte{0xb}, 32)
+	return code, contractCode, word256.LeftPadBytes([]byte{0xb}, 32)
 }
 
 // simple call contract calls another contract
@@ -321,5 +341,5 @@ func simpleCallContract(addr []byte) ([]byte, []byte, []byte) {
 	code = append(code, []byte{0x60, byte(lenCode), 0x60, 0x0, 0xf3}...)
 	code = append(code, contractCode...)
 	// return init code, contract code, expected return
-	return code, contractCode, tm_common.LeftPadBytes([]byte{0xb}, 32)
+	return code, contractCode, word256.LeftPadBytes([]byte{0xb}, 32)
 }
diff --git a/rpc/tendermint/test/websocket_client_test.go b/rpc/tendermint/test/websocket_client_test.go
index 60e665bdce2a2ecfdf4791deec6c75672446523c..5f799041f652d2425611c474e78faff6970141ab 100644
--- a/rpc/tendermint/test/websocket_client_test.go
+++ b/rpc/tendermint/test/websocket_client_test.go
@@ -1,6 +1,20 @@
 // +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 test
 
 import (
diff --git a/rpc/tendermint/test/websocket_helpers.go b/rpc/tendermint/test/websocket_helpers.go
index b5a7f79f002d54601677142adc8fd82d991df8ba..46408e5d42fd1e9ab3d9d27d7cc0bb5d0353a27c 100644
--- a/rpc/tendermint/test/websocket_helpers.go
+++ b/rpc/tendermint/test/websocket_helpers.go
@@ -1,3 +1,17 @@
+// 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 test
 
 import (
diff --git a/rpc/v0/codec.go b/rpc/v0/codec.go
index 1fd379bea6e5e330827421c9a56813ea165d0d76..344c1c98f12977352419dcd1247659b0de59e4ec 100644
--- a/rpc/v0/codec.go
+++ b/rpc/v0/codec.go
@@ -1,18 +1,16 @@
-// Copyright 2015, 2016 Eris Industries (UK) Ltd.
-// This file is part of Eris-RT
-
-// Eris-RT is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-
-// Eris-RT is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License
-// along with Eris-RT.  If not, see <http://www.gnu.org/licenses/>.
+// 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_v0
 
@@ -47,6 +45,8 @@ func (this *TCodec) EncodeBytes(v interface{}) ([]byte, error) {
 	return wire.JSONBytes(v), nil
 }
 
+// TODO: [ben] implement EncodeBytesPtr ?
+
 // Decode from an io.Reader.
 func (this *TCodec) Decode(v interface{}, r io.Reader) error {
 	bts, errR := ioutil.ReadAll(r)
@@ -64,3 +64,10 @@ func (this *TCodec) DecodeBytes(v interface{}, bts []byte) error {
 	wire.ReadJSON(v, bts, &err)
 	return err
 }
+
+// Decode from a byte array pointer.
+func (this *TCodec) DecodeBytesPtr(v interface{}, bts []byte) error {
+	var err error
+	wire.ReadJSONPtr(v, bts, &err)
+	return err
+}
diff --git a/rpc/v0/json_service.go b/rpc/v0/json_service.go
index 4c43f533432fdd1e2da6c1dc5f46233ede862069..77bc4ffaa32a8c6e6e6f38104ecf440494b5951e 100644
--- a/rpc/v0/json_service.go
+++ b/rpc/v0/json_service.go
@@ -1,3 +1,17 @@
+// 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_v0
 
 import (
@@ -6,8 +20,6 @@ import (
 
 	"github.com/gin-gonic/gin"
 
-	log "github.com/eris-ltd/eris-logger"
-
 	definitions "github.com/eris-ltd/eris-db/definitions"
 	event "github.com/eris-ltd/eris-db/event"
 	rpc "github.com/eris-ltd/eris-db/rpc"
@@ -125,10 +137,8 @@ func (this *ErisDbJsonService) writeError(msg, id string, code int, w http.Respo
 
 // Helper for writing responses.
 func (this *ErisDbJsonService) writeResponse(id string, result interface{}, w http.ResponseWriter) {
-	log.Debug("Result: %v\n", result)
 	response := rpc.NewRPCResponse(id, result)
 	err := this.codec.Encode(response, w)
-	log.Debug("Response: %v\n", response)
 	if err != nil {
 		this.writeError("Internal error: "+err.Error(), id, rpc.INTERNAL_ERROR, w)
 		return
diff --git a/rpc/v0/json_service_data_test.go b/rpc/v0/json_service_data_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..96be04138a4d5399650a4ae00570049754600b88
--- /dev/null
+++ b/rpc/v0/json_service_data_test.go
@@ -0,0 +1,71 @@
+// 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_v0
+
+import (
+	"encoding/json"
+	"testing"
+
+	"github.com/eris-ltd/eris-db/rpc"
+	"github.com/eris-ltd/eris-db/txs"
+
+	"github.com/stretchr/testify/assert"
+)
+
+var testBroadcastCallTxJsonRequest = []byte(`
+{
+  "id": "57EC1D39-7B3D-4F96-B286-8FC128177AFC4",
+  "jsonrpc": "2.0",
+  "method": "erisdb.broadcastTx",
+  "params": [
+    2,
+    {
+      "address": "5A9083BB0EFFE4C8EB2ADD29174994F73E77D418",
+      "data": "2F2397A00000000000000000000000000000000000000000000000000000000000003132",
+      "fee": 1,
+      "gas_limit": 1000000,
+      "input": {
+        "address": "BE18FDCBF12BF99F4D75325E17FF2E78F1A35FE8",
+        "amount": 1,
+        "pub_key": [
+          1,
+          "8D1611925948DC2EDDF739FB65CE517757D286155A039B28441C3349BE9A8C38"
+        ],
+        "sequence": 2,
+        "signature": [
+          1,
+          "B090D622F143ECEDA9B9E7B15485CE7504453C05434951CF867B013D80ED1BD2A0CA32846FC175D234CDFB9D5C3D792759E8FE79FD4DB3006B24950EE3C37D00"
+        ]
+      }
+    }
+  ]
+}`)
+
+// 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 TestCallTxJsonFormatCodec(t *testing.T) {
+	codec := NewTCodec()
+	param := new(txs.Tx)
+
+	// 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.DecodeBytesPtr(param, request.Params),
+		"RPC codec failed to decode params as transaction type.")
+	_, ok := (*param).(*txs.CallTx)
+	assert.True(t, ok, "Type byte 0x02 should unmarshal into CallTx.")
+}
diff --git a/rpc/v0/methods.go b/rpc/v0/methods.go
index eaa82ff06eda12db9a282e62de845b0fc506df22..6a26848cc8f3a6cb38afe01b704a19d98f57c611 100644
--- a/rpc/v0/methods.go
+++ b/rpc/v0/methods.go
@@ -1,3 +1,17 @@
+// 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_v0
 
 import (
@@ -345,12 +359,13 @@ func (erisDbMethods *ErisDbMethods) CallCode(request *rpc.RPCRequest, requester
 }
 
 func (erisDbMethods *ErisDbMethods) BroadcastTx(request *rpc.RPCRequest, requester interface{}) (interface{}, int, error) {
-	param := &txs.CallTx{}
-	err := erisDbMethods.codec.DecodeBytes(param, request.Params)
+	// Accept all transaction types as parameter for broadcast.
+	param := new(txs.Tx)
+	err := erisDbMethods.codec.DecodeBytesPtr(param, request.Params)
 	if err != nil {
 		return nil, rpc.INVALID_PARAMS, err
 	}
-	receipt, errC := erisDbMethods.pipe.Transactor().BroadcastTx(param)
+	receipt, errC := erisDbMethods.pipe.Transactor().BroadcastTx(*param)
 	if errC != nil {
 		return nil, rpc.INTERNAL_ERROR, errC
 	}
diff --git a/rpc/v0/params.go b/rpc/v0/params.go
index 98778554dec9a3a2329d0d591b8cd5b05f21e12f..e6f565557ea65247391e8532b282e3fbe80383d8 100644
--- a/rpc/v0/params.go
+++ b/rpc/v0/params.go
@@ -1,3 +1,17 @@
+// 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_v0
 
 import (
diff --git a/rpc/v0/restServer.go b/rpc/v0/restServer.go
index 2af84e19e666efc6eb312a40271bced1cf44d5b1..18fb507ec3569df4699af3172eccf7c9d6910471 100644
--- a/rpc/v0/restServer.go
+++ b/rpc/v0/restServer.go
@@ -1,3 +1,17 @@
+// 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_v0
 
 import (
diff --git a/test/testdata/testdata/testdata.go b/rpc/v0/restServer_data_test.go
similarity index 92%
rename from test/testdata/testdata/testdata.go
rename to rpc/v0/restServer_data_test.go
index 5fd2be000a2773de50fb7e469ed2a08bc820f2a5..31fbaeb3b169dc78bbb76fe6700c4698843b2a4a 100644
--- a/test/testdata/testdata/testdata.go
+++ b/rpc/v0/restServer_data_test.go
@@ -1,12 +1,25 @@
-package testdata
+// 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_v0
 
 import (
 	account "github.com/eris-ltd/eris-db/account"
 	consensus_types "github.com/eris-ltd/eris-db/consensus/types"
 	core_types "github.com/eris-ltd/eris-db/core/types"
 	event "github.com/eris-ltd/eris-db/event"
-	stypes "github.com/eris-ltd/eris-db/manager/eris-mint/state/types"
-	rpc_v0 "github.com/eris-ltd/eris-db/rpc/v0"
+	genesis "github.com/eris-ltd/eris-db/genesis"
 	"github.com/eris-ltd/eris-db/rpc/v0/shared"
 	transaction "github.com/eris-ltd/eris-db/txs"
 	mintTypes "github.com/tendermint/tendermint/types"
@@ -540,26 +553,26 @@ var serverDuration uint = 100
 type (
 	ChainData struct {
 		PrivValidator *mintTypes.PrivValidator `json:"priv_validator"`
-		Genesis       *stypes.GenesisDoc       `json:"genesis"`
+		Genesis       *genesis.GenesisDoc      `json:"genesis"`
 	}
 
 	GetAccountData struct {
-		Input  *rpc_v0.AddressParam `json:"input"`
-		Output *account.Account     `json:"output"`
+		Input  *AddressParam    `json:"input"`
+		Output *account.Account `json:"output"`
 	}
 
 	GetAccountsData struct {
-		Input  *rpc_v0.AccountsParam   `json:"input"`
+		Input  *AccountsParam          `json:"input"`
 		Output *core_types.AccountList `json:"output"`
 	}
 
 	GetStorageData struct {
-		Input  *rpc_v0.AddressParam `json:"input"`
-		Output *core_types.Storage  `json:"output"`
+		Input  *AddressParam       `json:"input"`
+		Output *core_types.Storage `json:"output"`
 	}
 
 	GetStorageAtData struct {
-		Input  *rpc_v0.StorageAtParam  `json:"input"`
+		Input  *StorageAtParam         `json:"input"`
 		Output *core_types.StorageItem `json:"output"`
 	}
 
@@ -588,13 +601,13 @@ type (
 	}
 
 	GetBlockData struct {
-		Input  *rpc_v0.HeightParam `json:"input"`
-		Output *mintTypes.Block    `json:"output"`
+		Input  *HeightParam     `json:"input"`
+		Output *mintTypes.Block `json:"output"`
 	}
 
 	GetBlocksData struct {
-		Input  *rpc_v0.BlocksParam `json:"input"`
-		Output *core_types.Blocks  `json:"output"`
+		Input  *BlocksParam       `json:"input"`
+		Output *core_types.Blocks `json:"output"`
 	}
 
 	GetConsensusStateData struct {
@@ -630,18 +643,18 @@ type (
 	}
 
 	GetPeerData struct {
-		Input  *rpc_v0.PeerParam     `json:"input"`
+		Input  *PeerParam            `json:"input"`
 		Output *consensus_types.Peer `json:"output"`
 	}
 
 	TransactData struct {
-		Input  *rpc_v0.TransactParam `json:"input"`
-		Output *transaction.Receipt  `json:"output"`
+		Input  *TransactParam       `json:"input"`
+		Output *transaction.Receipt `json:"output"`
 	}
 
 	TransactCreateData struct {
-		Input  *rpc_v0.TransactParam `json:"input"`
-		Output *transaction.Receipt  `json:"output"`
+		Input  *TransactParam       `json:"input"`
+		Output *transaction.Receipt `json:"output"`
 	}
 
 	GetUnconfirmedTxsData struct {
@@ -649,43 +662,43 @@ type (
 	}
 
 	CallCodeData struct {
-		Input  *rpc_v0.CallCodeParam `json:"input"`
-		Output *core_types.Call      `json:"output"`
+		Input  *CallCodeParam   `json:"input"`
+		Output *core_types.Call `json:"output"`
 	}
 
 	CallData struct {
-		Input  *rpc_v0.CallParam `json:"input"`
-		Output *core_types.Call  `json:"output"`
+		Input  *CallParam       `json:"input"`
+		Output *core_types.Call `json:"output"`
 	}
 
 	EventSubscribeData struct {
-		Input  *rpc_v0.EventIdParam `json:"input"`
-		Output *event.EventSub      `json:"output"`
+		Input  *EventIdParam   `json:"input"`
+		Output *event.EventSub `json:"output"`
 	}
 
 	EventUnsubscribeData struct {
-		Input  *rpc_v0.SubIdParam `json:"input"`
-		Output *event.EventUnsub  `json:"output"`
+		Input  *SubIdParam       `json:"input"`
+		Output *event.EventUnsub `json:"output"`
 	}
 
 	TransactNameRegData struct {
-		Input  *rpc_v0.TransactNameRegParam `json:"input"`
-		Output *transaction.Receipt         `json:"output"`
+		Input  *TransactNameRegParam `json:"input"`
+		Output *transaction.Receipt  `json:"output"`
 	}
 
 	GetNameRegEntryData struct {
-		Input  *rpc_v0.NameRegEntryParam `json:"input"`
-		Output *core_types.NameRegEntry  `json:"output"`
+		Input  *NameRegEntryParam       `json:"input"`
+		Output *core_types.NameRegEntry `json:"output"`
 	}
 
 	GetNameRegEntriesData struct {
-		Input  *rpc_v0.FilterListParam     `json:"input"`
+		Input  *FilterListParam            `json:"input"`
 		Output *core_types.ResultListNames `json:"output"`
 	}
 
 	/*
 		EventPollData struct {
-			Input  *rpc_v0.SubIdParam  `json:"input"`
+			Input  *SubIdParam  `json:"input"`
 			Output *event.PollResponse `json:"output"`
 		}
 	*/
@@ -728,7 +741,7 @@ type (
 )
 
 func LoadTestData() *TestData {
-	codec := rpc_v0.NewTCodec()
+	codec := NewTCodec()
 	testData := &TestData{}
 	if err := codec.DecodeBytes(testData, []byte(testDataJson)); err != nil {
 		panic(err)
diff --git a/test/mock/pipe.go b/rpc/v0/restServer_pipe_test.go
similarity index 80%
rename from test/mock/pipe.go
rename to rpc/v0/restServer_pipe_test.go
index e279ad18253e2fc755f9948d8ec5108d89588a41..6b084b9edb23b07c8976b912cbc25a426559caf6 100644
--- a/test/mock/pipe.go
+++ b/rpc/v0/restServer_pipe_test.go
@@ -1,4 +1,18 @@
-package mock
+// 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_v0
 
 import (
 	"fmt"
@@ -11,48 +25,44 @@ import (
 	blockchain_types "github.com/eris-ltd/eris-db/blockchain/types"
 	consensus_types "github.com/eris-ltd/eris-db/consensus/types"
 	manager_types "github.com/eris-ltd/eris-db/manager/types"
-	td "github.com/eris-ltd/eris-db/test/testdata/testdata"
 	"github.com/eris-ltd/eris-db/txs"
 
+	"github.com/eris-ltd/eris-db/logging/loggers"
+	abci_types "github.com/tendermint/abci/types"
 	"github.com/tendermint/go-crypto"
 	"github.com/tendermint/go-p2p"
 	mintTypes "github.com/tendermint/tendermint/types"
-	tmsp_types "github.com/tendermint/tmsp/types"
 )
 
 // Base struct.
 type MockPipe struct {
-	testData        *td.TestData
+	testData        *TestData
 	accounts        definitions.Accounts
 	blockchain      blockchain_types.Blockchain
 	consensusEngine consensus_types.ConsensusEngine
 	events          event.EventEmitter
 	namereg         definitions.NameReg
 	transactor      definitions.Transactor
+	logger          loggers.InfoTraceLogger
 }
 
 // Create a new mock tendermint pipe.
-func NewMockPipe(td *td.TestData) definitions.Pipe {
-	accounts := &accounts{td}
-	blockchain := &blockchain{td}
-	consensusEngine := &consensusEngine{td}
-	eventer := &eventer{td}
-	namereg := &namereg{td}
-	transactor := &transactor{td}
+func NewMockPipe(td *TestData) definitions.Pipe {
 	return &MockPipe{
-		td,
-		accounts,
-		blockchain,
-		consensusEngine,
-		eventer,
-		namereg,
-		transactor,
+		testData:        td,
+		accounts:        &accounts{td},
+		blockchain:      &mockBlockchain{td},
+		consensusEngine: &consensusEngine{td},
+		events:          &eventer{td},
+		namereg:         &namereg{td},
+		transactor:      &transactor{td},
+		logger:          loggers.NewNoopInfoTraceLogger(),
 	}
 }
 
 // Create a mock pipe with default mock data.
 func NewDefaultMockPipe() definitions.Pipe {
-	return NewMockPipe(td.LoadTestData())
+	return NewMockPipe(LoadTestData())
 }
 
 func (pipe *MockPipe) Accounts() definitions.Accounts {
@@ -75,6 +85,10 @@ func (pipe *MockPipe) Transactor() definitions.Transactor {
 	return pipe.transactor
 }
 
+func (pipe *MockPipe) Logger() loggers.InfoTraceLogger {
+	return pipe.logger
+}
+
 func (pipe *MockPipe) GetApplication() manager_types.Application {
 	// TODO: [ben] mock application
 	return nil
@@ -110,7 +124,7 @@ func (pipe *MockPipe) GenesisHash() []byte {
 
 // Accounts
 type accounts struct {
-	testData *td.TestData
+	testData *TestData
 }
 
 func (acc *accounts) GenPrivAccount() (*account.PrivAccount, error) {
@@ -138,33 +152,33 @@ func (acc *accounts) StorageAt(address, key []byte) (*core_types.StorageItem, er
 }
 
 // Blockchain
-type blockchain struct {
-	testData *td.TestData
+type mockBlockchain struct {
+	testData *TestData
 }
 
-func (this *blockchain) ChainId() string {
+func (this *mockBlockchain) ChainId() string {
 	return this.testData.GetChainId.Output.ChainId
 }
 
-func (this *blockchain) Height() int {
+func (this *mockBlockchain) Height() int {
 	return this.testData.GetLatestBlockHeight.Output.Height
 }
 
-func (this *blockchain) Block(height int) *mintTypes.Block {
+func (this *mockBlockchain) Block(height int) *mintTypes.Block {
 	return this.testData.GetBlock.Output
 }
 
-func (this *blockchain) BlockMeta(height int) *mintTypes.BlockMeta {
+func (this *mockBlockchain) BlockMeta(height int) *mintTypes.BlockMeta {
 	return &mintTypes.BlockMeta{}
 }
 
 // Consensus
 type consensusEngine struct {
-	testData *td.TestData
+	testData *TestData
 }
 
 func (cons *consensusEngine) BroadcastTransaction(transaction []byte,
-	callback func(*tmsp_types.Response)) error {
+	callback func(*abci_types.Response)) error {
 	return nil
 }
 
@@ -224,7 +238,7 @@ func (cons *consensusEngine) PeerConsensusStates() map[string]string {
 
 // Events
 type eventer struct {
-	testData *td.TestData
+	testData *TestData
 }
 
 func (evntr *eventer) Subscribe(subId, event string, callback func(txs.EventData)) error {
@@ -237,7 +251,7 @@ func (evntr *eventer) Unsubscribe(subId string) error {
 
 // NameReg
 type namereg struct {
-	testData *td.TestData
+	testData *TestData
 }
 
 func (nmreg *namereg) Entry(key string) (*core_types.NameRegEntry, error) {
@@ -250,7 +264,7 @@ func (nmreg *namereg) Entries(filters []*event.FilterData) (*core_types.ResultLi
 
 // Txs
 type transactor struct {
-	testData *td.TestData
+	testData *TestData
 }
 
 func (trans *transactor) Call(fromAddress, toAddress, data []byte) (*core_types.Call, error) {
diff --git a/test/mock/mock_web_api_test.go b/rpc/v0/restServer_test.go
similarity index 93%
rename from test/mock/mock_web_api_test.go
rename to rpc/v0/restServer_test.go
index fc0603e0114ae86d83368a0c6ebfd6cc350b10dc..7cdf28039bd5fd11bd5d76201961710eb7867963 100644
--- a/test/mock/mock_web_api_test.go
+++ b/rpc/v0/restServer_test.go
@@ -1,4 +1,18 @@
-package mock
+// 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_v0
 
 // Basic imports
 import (
@@ -15,9 +29,7 @@ import (
 	core_types "github.com/eris-ltd/eris-db/core/types"
 	event "github.com/eris-ltd/eris-db/event"
 	rpc "github.com/eris-ltd/eris-db/rpc"
-	rpc_v0 "github.com/eris-ltd/eris-db/rpc/v0"
 	server "github.com/eris-ltd/eris-db/server"
-	td "github.com/eris-ltd/eris-db/test/testdata/testdata"
 	"github.com/eris-ltd/eris-db/txs"
 
 	"github.com/eris-ltd/eris-db/rpc/v0/shared"
@@ -41,18 +53,18 @@ type MockSuite struct {
 	serveProcess *server.ServeProcess
 	codec        rpc.Codec
 	sUrl         string
-	testData     *td.TestData
+	testData     *TestData
 }
 
 func (mockSuite *MockSuite) SetupSuite() {
 	gin.SetMode(gin.ReleaseMode)
 	// Load the supporting objects.
-	testData := td.LoadTestData()
+	testData := LoadTestData()
 	pipe := NewMockPipe(testData)
-	codec := &rpc_v0.TCodec{}
+	codec := &TCodec{}
 	evtSubs := event.NewEventSubscriptions(pipe.Events())
 	// The server
-	restServer := rpc_v0.NewRestServer(codec, pipe, evtSubs)
+	restServer := NewRestServer(codec, pipe, evtSubs)
 	sConf := server.DefaultServerConfig()
 	sConf.Bind.Port = 31402
 	// Create a server process.
@@ -62,7 +74,7 @@ func (mockSuite *MockSuite) SetupSuite() {
 		panic(err)
 	}
 	mockSuite.serveProcess = proc
-	mockSuite.codec = rpc_v0.NewTCodec()
+	mockSuite.codec = NewTCodec()
 	mockSuite.testData = testData
 	mockSuite.sUrl = "http://localhost:31402"
 }
diff --git a/rpc/v0/shared/net.go b/rpc/v0/shared/net.go
index 778b53595bc34896d54c61fc7cbe95029c4eb0ba..5d1bc85dca44f2a16b709592430d728735bf754b 100644
--- a/rpc/v0/shared/net.go
+++ b/rpc/v0/shared/net.go
@@ -1,21 +1,17 @@
-// Copyright 2015, 2016 Eris Industries (UK) Ltd.
-// This file is part of Eris-RT
+// 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.
 
-// Eris-RT is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-
-// Eris-RT is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License
-// along with Eris-RT.  If not, see <http://www.gnu.org/licenses/>.
-
-// Net is part of the pipe for ErisMint and provides the implementation
-// for the pipe to call into the ErisMint application
 package shared
 
 import (
@@ -23,6 +19,9 @@ import (
 	"github.com/eris-ltd/eris-db/definitions"
 )
 
+// Net is part of the pipe for ErisMint and provides the implementation
+// for the pipe to call into the ErisMint application
+
 //-----------------------------------------------------------------------------
 
 // Get the complete pipe info.
diff --git a/rpc/v0/shared/pipes.go b/rpc/v0/shared/pipes.go
index fb71aad9abe1006a233e60cb1f12bf048ad2d6a9..55a27b3fb493c2a3aad54bad996dc842c1073f7a 100644
--- a/rpc/v0/shared/pipes.go
+++ b/rpc/v0/shared/pipes.go
@@ -1,3 +1,17 @@
+// 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 shared
 
 // Shared extension methods for Pipe and its derivatives
diff --git a/rpc/v0/wsService.go b/rpc/v0/wsService.go
index 35705ed39c179ded02944c931580f04e57d51d96..daea0d01b75844cf3d19aaba958ed8bff9cf6308 100644
--- a/rpc/v0/wsService.go
+++ b/rpc/v0/wsService.go
@@ -1,11 +1,23 @@
+// 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_v0
 
 import (
 	"encoding/json"
 	"fmt"
 
-	log "github.com/eris-ltd/eris-logger"
-
 	definitions "github.com/eris-ltd/eris-db/definitions"
 	"github.com/eris-ltd/eris-db/event"
 	rpc "github.com/eris-ltd/eris-db/rpc"
@@ -36,7 +48,6 @@ func NewErisDbWsService(codec rpc.Codec,
 
 // Process a request.
 func (this *ErisDbWsService) Process(msg []byte, session *server.WSSession) {
-	log.Debug("REQUEST: %s\n", string(msg))
 	// Create new request object and unmarshal.
 	req := &rpc.RPCRequest{}
 	errU := json.Unmarshal(msg, req)
@@ -84,7 +95,6 @@ func (this *ErisDbWsService) writeResponse(id string, result interface{},
 	session *server.WSSession) error {
 	response := rpc.NewRPCResponse(id, result)
 	bts, err := this.codec.EncodeBytes(response)
-	log.Debug("RESPONSE: %v\n", response)
 	if err != nil {
 		this.writeError("Internal error: "+err.Error(), id, rpc.INTERNAL_ERROR, session)
 		return err
diff --git a/server/config.go b/server/config.go
index 13078f985532f58ffa073c3fd9829f93a057ef9c..4dcce19dd18199cfbbd19ae0f54bed9554b8db53 100644
--- a/server/config.go
+++ b/server/config.go
@@ -1,18 +1,16 @@
-// Copyright 2015, 2016 Eris Industries (UK) Ltd.
-// This file is part of Eris-RT
-
-// Eris-RT is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-
-// Eris-RT is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License
-// along with Eris-RT.  If not, see <http://www.gnu.org/licenses/>.
+// 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
 
diff --git a/server/idpool.go b/server/idpool.go
index d713c7014f1abb0da48f9a9e49d9faccc55ac899..44a72cba4d1b3266430b4ff95841a90db4316de8 100644
--- a/server/idpool.go
+++ b/server/idpool.go
@@ -1,3 +1,17 @@
+// 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 (
diff --git a/server/log.go b/server/log.go
index aacad33d92109b6353e54b91b438b3f2f7e746f3..e2bcb50b4cbf34e4807fd3bed9c484c1211a23d6 100644
--- a/server/log.go
+++ b/server/log.go
@@ -1,3 +1,17 @@
+// 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 (
diff --git a/server/logging.go b/server/logging.go
index 173fecaf34371dea336d152b0d911efac4f7309d..4a38e0f82d039b18400ec07d1767812e1210c574 100644
--- a/server/logging.go
+++ b/server/logging.go
@@ -1,3 +1,17 @@
+// 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 (
diff --git a/server/server.go b/server/server.go
index f1d38c3dea5fdd2c1c9fb4ed949c52df44f78998..8e4c85122e663417e9355b099c9153442f70f9ae 100644
--- a/server/server.go
+++ b/server/server.go
@@ -1,3 +1,17 @@
+// 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 (
diff --git a/server/server_test.go b/server/server_test.go
index 61569515529d3d9d650f018f2757cc0fc371cbe4..5efdad26819e4d2f12ed568c71954eb27ce1405c 100644
--- a/server/server_test.go
+++ b/server/server_test.go
@@ -1,3 +1,17 @@
+// 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 (
diff --git a/server/websocket.go b/server/websocket.go
index a5767141c8710a3b854f6d3efc35daf2791eb4e5..aff2f94c307aa13c3383292ad9dd44f4b054b8e2 100644
--- a/server/websocket.go
+++ b/server/websocket.go
@@ -1,3 +1,17 @@
+// 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 (
diff --git a/test/filters/filter_test.go b/test/filters/filter_test.go
index ff57650149d36642806ae17c447c1fb0b594d572..c27a1eb02c3fb267243bbcd3533057b78b379f82 100644
--- a/test/filters/filter_test.go
+++ b/test/filters/filter_test.go
@@ -1,3 +1,17 @@
+// 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 (
diff --git a/test/fixtures/file_fixtures.go b/test/fixtures/file_fixtures.go
index da751d108d7a068eef522eabbff92788004096f1..d6926c0972911d33b3f4d3272645388e36bec8bd 100644
--- a/test/fixtures/file_fixtures.go
+++ b/test/fixtures/file_fixtures.go
@@ -1,3 +1,17 @@
+// 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 fixtures
 
 import (
diff --git a/test/server/http_burst_test.go b/test/server/http_burst_test.go
index bb49275b7d82c5ee10a35fb162a79852e95833eb..b9e404e2801abb98046186e53ca0e9342eec7016 100644
--- a/test/server/http_burst_test.go
+++ b/test/server/http_burst_test.go
@@ -1,3 +1,17 @@
+// 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 (
diff --git a/test/server/scumbag.go b/test/server/scumbag.go
index 71eaddc61d10affad17ad6f9548d42b461b7f172..67751442e23b3b5ad948fb0b88ce33a8758ab9f3 100644
--- a/test/server/scumbag.go
+++ b/test/server/scumbag.go
@@ -1,3 +1,17 @@
+// 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 (
diff --git a/test/server/ws_burst_test.go b/test/server/ws_burst_test.go
index cb9e7af4f2037fdc52f4893f464c3436b406cff9..55dd8e93975f923fbefc79d5e2a2eded08be37fd 100644
--- a/test/server/ws_burst_test.go
+++ b/test/server/ws_burst_test.go
@@ -1,3 +1,17 @@
+// 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 (
diff --git a/test/testdata/helpers.go b/test/testdata/helpers.go
index 127440f7eb185dcd360d13b9dc183c8983dc72ad..2dbbaed7bbd0c3a31c042b3928ede8c39df16bbb 100644
--- a/test/testdata/helpers.go
+++ b/test/testdata/helpers.go
@@ -1,3 +1,17 @@
+// 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 testdata
 
 import (
diff --git a/tests/build_tool.sh b/tests/build_tool.sh
index 31dcac0cd50ae7c5fab7a1c42a49478e31c622b9..325542e9a71ca09d8ff0ebac7ca8b1af9dee762d 100755
--- a/tests/build_tool.sh
+++ b/tests/build_tool.sh
@@ -35,9 +35,10 @@ release_min=$(cat $REPO/version/version.go | tail -n 1 | cut -d \  -f 4 | tr -d
 release_maj=$(echo $release_min | cut -d . -f 1-2)
 
 # Build
+mkdir -p $REPO/target/docker
 docker build -t $IMAGE:build $REPO
-docker run --rm --entrypoint cat $IMAGE:build /usr/local/bin/$TARGET > $REPO/"$TARGET"_build_artifact
-docker run --rm --entrypoint cat $IMAGE:build /usr/local/bin/eris-client > $REPO/eris-client
+docker run --rm --entrypoint cat $IMAGE:build /usr/local/bin/$TARGET > $REPO/target/docker/eris-db.dockerartefact
+docker run --rm --entrypoint cat $IMAGE:build /usr/local/bin/eris-client > $REPO/target/docker/eris-client.dockerartefact
 docker build -t $IMAGE:$release_min -f Dockerfile.deploy $REPO
 
 # If provided, tag the image with the label provided
@@ -48,6 +49,6 @@ then
 fi
 
 # Cleanup
-rm $REPO/"$TARGET"_build_artifact
-rm $REPO/eris-client
+rm $REPO/target/docker/eris-db.dockerartefact
+rm $REPO/target/docker/eris-client.dockerartefact
 docker rmi -f $IMAGE:build
diff --git a/txs/events.go b/txs/events.go
index 4cb7e656c6535bebd71088693f4e5b7486cb1f9b..9e15cd3c54b2a3a8c6c5b88dd701f0448da3a9d1 100644
--- a/txs/events.go
+++ b/txs/events.go
@@ -1,12 +1,26 @@
+// 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 txs
 
 import (
 	"fmt"
 	"time"
 
-	. "github.com/tendermint/go-common"
-	"github.com/tendermint/go-wire"
+	. "github.com/eris-ltd/eris-db/word256"
 
+	"github.com/tendermint/go-wire"
 	tm_types "github.com/tendermint/tendermint/types" // Block
 )
 
diff --git a/txs/log.go b/txs/log.go
deleted file mode 100644
index b967a58d0ef7d4701fc15f5ab3dfee1f046b15f5..0000000000000000000000000000000000000000
--- a/txs/log.go
+++ /dev/null
@@ -1,7 +0,0 @@
-package txs
-
-import (
-	"github.com/tendermint/go-logger"
-)
-
-var log = logger.New("module", "types")
diff --git a/txs/names.go b/txs/names.go
index 1cc00e168c4b3dfce9cb1685969e645caf412d41..41b80b085af1c280cc92eaeed2186508b217be69 100644
--- a/txs/names.go
+++ b/txs/names.go
@@ -1,3 +1,17 @@
+// 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 txs
 
 import (
diff --git a/txs/tx.go b/txs/tx.go
index a216332031d24951fdc63d1f12a57b9f8f932fc7..0a7430dc193b755eb43745d1484043e5c249bce7 100644
--- a/txs/tx.go
+++ b/txs/tx.go
@@ -1,3 +1,17 @@
+// 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 txs
 
 import (
diff --git a/txs/tx_test.go b/txs/tx_test.go
index e3f092da5679bd78f2b0ff1e1a4423f8eb960565..e4b0653dc9472d329b8bbf61646ba3e0eb260e03 100644
--- a/txs/tx_test.go
+++ b/txs/tx_test.go
@@ -1,3 +1,17 @@
+// 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 txs
 
 import (
diff --git a/txs/tx_utils.go b/txs/tx_utils.go
index cdc4be247762db25b3abccda6919b7f72f594751..0c6466486c03339ff0b2afd94aed2da3cb5a1d56 100644
--- a/txs/tx_utils.go
+++ b/txs/tx_utils.go
@@ -1,3 +1,17 @@
+// 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 txs
 
 import (
diff --git a/util/architecture/constants.go b/util/architecture/constants.go
index fb03311c6b6f1c10f6fa6b2284abb4974183d39f..695a5fe16a76b57f7eb4dafcbda7b3a4194a1bc2 100644
--- a/util/architecture/constants.go
+++ b/util/architecture/constants.go
@@ -1,5 +1,19 @@
 // +build !arm
 
+// 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 architecture
 
 import "math"
diff --git a/util/architecture/constants_arm.go b/util/architecture/constants_arm.go
index 5f8c9cc82ea360956a4206da74f69391e1bb4045..c677498cba7c32836976414bca39d10614319ab2 100644
--- a/util/architecture/constants_arm.go
+++ b/util/architecture/constants_arm.go
@@ -1,3 +1,17 @@
+// 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 architecture
 
 import "math"
diff --git a/util/fs.go b/util/fs.go
index 7d41c1ddd51d28de1859daf291062d2afd5d4290..41ec3fce08a181acb8fd806cb99a74fcfb260684 100644
--- a/util/fs.go
+++ b/util/fs.go
@@ -1,18 +1,16 @@
-// Copyright 2015, 2016 Eris Industries (UK) Ltd.
-// This file is part of Eris-RT
-
-// Eris-RT is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-
-// Eris-RT is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License
-// along with Eris-RT.  If not, see <http://www.gnu.org/licenses/>.
+// 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 util
 
diff --git a/util/hell/README.md b/util/hell/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..715cb5522ca5a98143a45edf7e9ec49517b6778d
--- /dev/null
+++ b/util/hell/README.md
@@ -0,0 +1,11 @@
+> Hell is other people's packages
+
+While we wait for working package management in go we need a way to make
+maintaining the glide.lock by hand less painful.
+
+To interactively add a package run from the root:
+
+```bash
+go run ./util/hell/cmd/hell/main.go get --interactive github.com/tendermint/tendermint
+```
+
diff --git a/util/hell/cmd/hell/main.go b/util/hell/cmd/hell/main.go
new file mode 100644
index 0000000000000000000000000000000000000000..427105ba9a77e14ed02efe81e38d2b3f5d3b2739
--- /dev/null
+++ b/util/hell/cmd/hell/main.go
@@ -0,0 +1,145 @@
+// 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 (
+	"fmt"
+	"os"
+	"path/filepath"
+
+	"github.com/eris-ltd/eris-db/util/hell"
+
+	"github.com/Masterminds/glide/action"
+	"github.com/Masterminds/glide/cache"
+	"github.com/Masterminds/glide/cfg"
+	"github.com/Masterminds/glide/msg"
+	"github.com/Masterminds/glide/path"
+	"github.com/Masterminds/glide/repo"
+	"github.com/Masterminds/glide/util"
+	"github.com/spf13/cobra"
+)
+
+func main() {
+	hellCmd := &cobra.Command{
+		Use:   "hell",
+		Short: "Hell makes the most of it being warm",
+		Long:  "",
+		Run:   func(cmd *cobra.Command, args []string) { cmd.Help() },
+	}
+
+	// Lock merge command
+	var baseGlideLockFile, depGlideLockFile string
+	lockMergeCmd := &cobra.Command{
+		Use:   "lock-merge",
+		Short: "Merge glide.lock files together",
+		Long: "This command merges two glide.lock files into a single one by copying all dependencies " +
+			"from a base glide.lock and an override glide.lock to an output glide.lock with dependencies " +
+			"from override taking precedence over those from base.",
+		Run: func(cmd *cobra.Command, args []string) {
+			baseLockFile, err := cfg.ReadLockFile(baseGlideLockFile)
+			if err != nil {
+				fmt.Printf("Could not read file: %s\n", err)
+				os.Exit(1)
+			}
+			overrideLockFile, err := cfg.ReadLockFile(depGlideLockFile)
+			if err != nil {
+				fmt.Printf("Could not read file: %s\n", err)
+				os.Exit(1)
+			}
+			mergedLockFile, err := hell.MergeGlideLockFiles(baseLockFile, overrideLockFile)
+			if err != nil {
+				fmt.Printf("Could not merge lock files: %s\n", err)
+				os.Exit(1)
+			}
+			mergedBytes, err := mergedLockFile.Marshal()
+			if err != nil {
+				fmt.Printf("Could not marshal lock file: %s\n", err)
+				os.Exit(1)
+			}
+			os.Stdout.Write(mergedBytes)
+		},
+	}
+	lockMergeCmd.PersistentFlags().StringVarP(&baseGlideLockFile, "base", "b", "", "base lock file")
+	lockMergeCmd.PersistentFlags().StringVarP(&depGlideLockFile, "override", "o", "", "override lock file")
+
+	// Lock update
+	interactive := false
+	getTransitiveCmd := &cobra.Command{
+		Use:   "get",
+		Short: "gets a remote dependency to this project along with its transtive dependencies.",
+		Long: "Gets a remote dependency and its transitive dependencies by adding the remote " +
+			"depednency to this project's glide.yaml and merging the remote dependency's " +
+			"glide.lock into this project's glide.lock",
+		Run: func(cmd *cobra.Command, args []string) {
+			if len(args) != 1 {
+				msg.Die("%s requires a single argument of the remote dependency\n", cmd.Name())
+			}
+			rootPackage, _ := util.NormalizeName(args[0])
+			// Add dependency to glide
+			installer := repo.NewInstaller()
+			action.Get(args, installer, false, true, false, !interactive, false)
+			// Now hunt down the repo cache
+			dep := action.EnsureConfig().Imports.Get(rootPackage)
+
+			key, err := cache.Key(dep.Remote())
+			if err != nil {
+				msg.Die("%s requires a single argument of the remote dependency\n", cmd.Name())
+			}
+			cacheDir := filepath.Join(cache.Location(), "src", key)
+			repos, err := dep.GetRepo(cacheDir)
+			if err != nil {
+				msg.Die("Could not get repo: %s", err)
+			}
+			version, err := repos.Version()
+			if err != nil {
+				msg.Die("Could not get version: %s", err)
+			}
+			dep.Pin = version
+			lockPath := filepath.Join(".", path.LockFile)
+			baseLockFile, err := cfg.ReadLockFile(lockPath)
+			if err != nil {
+				msg.Die("Could not read base lock file: %s", err)
+			}
+			overrideLockFile := &cfg.Lockfile{}
+			if path.HasLock(cacheDir) {
+				msg.Info("Found dependency lock file so merging into project lock file")
+				overrideLockFile, err = cfg.ReadLockFile(filepath.Join(cacheDir, path.LockFile))
+				if err != nil {
+					msg.Die("Could not read dependency lock file: %s", err)
+				}
+			}
+			// Add the package to glide lock too!
+			overrideLockFile.Imports = append(overrideLockFile.Imports, cfg.LockFromDependency(dep))
+
+			mergedLockFile, err := hell.MergeGlideLockFiles(baseLockFile, overrideLockFile)
+			if err != nil {
+				msg.Die("Could not merge lock files: %s\n", err)
+			}
+			err = mergedLockFile.WriteFile(lockPath)
+			if err != nil {
+				msg.Die("Could not write merged lock file: %s", err)
+			}
+
+			action.Install(installer, false)
+		},
+	}
+
+	getTransitiveCmd.PersistentFlags().BoolVarP(&interactive, "interactive", "i", false,
+		"set dependency verion interactively")
+
+	hellCmd.AddCommand(lockMergeCmd)
+	hellCmd.AddCommand(getTransitiveCmd)
+	lockMergeCmd.Execute()
+}
diff --git a/util/hell/merge.go b/util/hell/merge.go
new file mode 100644
index 0000000000000000000000000000000000000000..130a80065b9ba82b70a0cbe24ebac439dd79b974
--- /dev/null
+++ b/util/hell/merge.go
@@ -0,0 +1,101 @@
+// 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 hell
+
+import (
+	"crypto/sha256"
+	"fmt"
+	"sort"
+
+	"github.com/Masterminds/glide/cfg"
+)
+
+// Merges two glide lock files together, letting dependencies from 'base' be overwritten
+// by those from 'override'. Returns the resultant glide lock file bytes
+func MergeGlideLockFiles(baseLockFile, overrideLockFile *cfg.Lockfile) (*cfg.Lockfile, error) {
+	imports := make(map[string]*cfg.Lock, len(baseLockFile.Imports))
+	devImports := make(map[string]*cfg.Lock, len(baseLockFile.DevImports))
+	// Copy the base dependencies into a map
+	for _, lock := range baseLockFile.Imports {
+		imports[lock.Name] = lock
+	}
+	for _, lock := range baseLockFile.DevImports {
+		devImports[lock.Name] = lock
+	}
+	// Override base dependencies and add any extra ones
+	for _, lock := range overrideLockFile.Imports {
+		imports[lock.Name] = mergeLocks(imports[lock.Name], lock)
+	}
+	for _, lock := range overrideLockFile.DevImports {
+		devImports[lock.Name] = mergeLocks(imports[lock.Name], lock)
+	}
+
+	deps := make([]*cfg.Dependency, 0, len(imports))
+	devDeps := make([]*cfg.Dependency, 0, len(devImports))
+
+	// Flatten to Dependencies
+	for _, lock := range imports {
+		deps = append(deps, pinnedDependencyFromLock(lock))
+	}
+
+	for _, lock := range devImports {
+		devDeps = append(devDeps, pinnedDependencyFromLock(lock))
+	}
+
+	hasher := sha256.New()
+	hasher.Write(([]byte)(baseLockFile.Hash))
+	hasher.Write(([]byte)(overrideLockFile.Hash))
+
+	return cfg.NewLockfile(deps, devDeps, fmt.Sprintf("%x", hasher.Sum(nil)))
+}
+
+func mergeLocks(baseLock, overrideLock *cfg.Lock) *cfg.Lock {
+	lock := overrideLock.Clone()
+	if baseLock == nil {
+		return lock
+	}
+
+	// Merge and dedupe subpackages
+	subpackages := make([]string, 0, len(lock.Subpackages)+len(baseLock.Subpackages))
+	for _, sp := range lock.Subpackages {
+		subpackages = append(subpackages, sp)
+	}
+	for _, sp := range baseLock.Subpackages {
+		subpackages = append(subpackages, sp)
+	}
+
+	sort.Stable(sort.StringSlice(subpackages))
+
+	dedupeSubpackages := make([]string, 0, len(subpackages))
+
+	lastSp := ""
+	elided := 0
+	for _, sp := range subpackages {
+		if lastSp == sp {
+			elided++
+		} else {
+			dedupeSubpackages = append(dedupeSubpackages, sp)
+			lastSp = sp
+		}
+	}
+	lock.Subpackages = dedupeSubpackages[:len(dedupeSubpackages)-elided]
+	return lock
+}
+
+func pinnedDependencyFromLock(lock *cfg.Lock) *cfg.Dependency {
+	dep := cfg.DependencyFromLock(lock)
+	dep.Pin = lock.Version
+	return dep
+}
diff --git a/util/hell/merge_test.go b/util/hell/merge_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..5fffedb9c93d01cc24782a657a09282d408933a9
--- /dev/null
+++ b/util/hell/merge_test.go
@@ -0,0 +1,85 @@
+// 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 hell
+
+import (
+	"strings"
+	"testing"
+
+	"github.com/Masterminds/glide/cfg"
+	"github.com/stretchr/testify/assert"
+)
+
+const baseLockYml = `imports:
+- name: github.com/gogo/protobuf
+  version: 82d16f734d6d871204a3feb1a73cb220cc92574c
+- name: github.com/tendermint/tendermint
+  version: aaea0c5d2e3ecfbf29f2608f9d43649ec7f07f50
+  subpackages:
+  - node
+  - proxy
+  - types
+  - version
+  - consensus
+  - rpc/core/types
+  - blockchain
+  - mempool
+  - rpc/core
+  - state
+`
+const overrideLockYml = `imports:
+- name: github.com/tendermint/tendermint
+  version: 764091dfbb035f1b28da4b067526e04c6a849966
+  subpackages:
+  - benchmarks
+  - proxy
+  - types
+  - version
+`
+const expectedLockYml = `imports:
+- name: github.com/gogo/protobuf
+  version: 82d16f734d6d871204a3feb1a73cb220cc92574c
+- name: github.com/tendermint/tendermint
+  version: 764091dfbb035f1b28da4b067526e04c6a849966
+  subpackages:
+  - benchmarks
+  - blockchain
+  - consensus
+  - mempool
+  - node
+  - proxy
+  - rpc/core
+  - rpc/core/types
+testImports: []
+`
+
+func TestMergeGlideLockFiles(t *testing.T) {
+	baseLockFile, err := cfg.LockfileFromYaml(([]byte)(baseLockYml))
+	assert.NoError(t, err, "Lockfile should parse")
+
+	overrideLockFile, err := cfg.LockfileFromYaml(([]byte)(overrideLockYml))
+	assert.NoError(t, err, "Lockfile should parse")
+
+	mergedLockFile, err := MergeGlideLockFiles(baseLockFile, overrideLockFile)
+	assert.NoError(t, err, "Lockfiles should merge")
+
+	mergedYmlBytes, err := mergedLockFile.Marshal()
+	assert.NoError(t, err, "Lockfile should marshal")
+
+	ymlLines := strings.Split(string(mergedYmlBytes), "\n")
+	// Drop the updated and hash lines
+	actualYml := strings.Join(ymlLines[2:], "\n")
+	assert.Equal(t, expectedLockYml, actualYml)
+}
diff --git a/util/os.go b/util/os.go
new file mode 100644
index 0000000000000000000000000000000000000000..a205c1c0931ab03a6f2577cc2aef979441660730
--- /dev/null
+++ b/util/os.go
@@ -0,0 +1,26 @@
+// 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 util
+
+import (
+	"fmt"
+	"os"
+)
+
+// Prints an error message to stderr and exits with status code 1
+func Fatalf(format string, args ...interface{}) {
+	fmt.Fprintf(os.Stderr, format, args...)
+	os.Exit(1)
+}
diff --git a/util/slice/slice.go b/util/slice/slice.go
new file mode 100644
index 0000000000000000000000000000000000000000..8c2b7f8914b86539c04051f7077830c82ec4b835
--- /dev/null
+++ b/util/slice/slice.go
@@ -0,0 +1,105 @@
+// 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 slice
+
+func Slice(elements ...interface{}) []interface{} {
+	return elements
+}
+
+func EmptySlice() []interface{} {
+	return []interface{}{}
+}
+
+// Like append but on the interface{} type and always to a fresh backing array
+// so can be used safely with slices over arrays you did not create.
+func CopyAppend(slice []interface{}, elements ...interface{}) []interface{} {
+	sliceLength := len(slice)
+	newSlice := make([]interface{}, sliceLength+len(elements))
+	for i, e := range slice {
+		newSlice[i] = e
+	}
+	for i, e := range elements {
+		newSlice[sliceLength+i] = e
+	}
+	return newSlice
+}
+
+// Prepend elements to slice in the order they appear
+func CopyPrepend(slice []interface{}, elements ...interface{}) []interface{} {
+	elementsLength := len(elements)
+	newSlice := make([]interface{}, len(slice)+elementsLength)
+	for i, e := range elements {
+		newSlice[i] = e
+	}
+	for i, e := range slice {
+		newSlice[elementsLength+i] = e
+	}
+	return newSlice
+}
+
+// Concatenate slices into a single slice
+func Concat(slices ...[]interface{}) []interface{} {
+	offset := 0
+	for _, slice := range slices {
+		offset += len(slice)
+	}
+	concat := make([]interface{}, offset)
+	offset = 0
+	for _, slice := range slices {
+		for i, e := range slice {
+			concat[offset+i] = e
+		}
+		offset += len(slice)
+	}
+	return concat
+}
+
+// Deletes n elements starting with the ith from a slice by splicing.
+// Beware uses append so the underlying backing array will be modified!
+func Delete(slice []interface{}, i int, n int) []interface{} {
+	return append(slice[:i], slice[i+n:]...)
+}
+
+// Delete an element at a specific index and return the contracted list
+func DeleteAt(slice []interface{}, i int) []interface{} {
+	return Delete(slice, i, 1)
+}
+
+// Flatten a slice by a list by splicing any elements of the list that are
+// themselves lists into the slice elements to the list in place of slice itself
+func Flatten(slice []interface{}) []interface{} {
+	return DeepFlatten(slice, 1)
+}
+
+// Recursively flattens a list by splicing any sub-lists into their parent until
+// depth is reached. If a negative number is passed for depth then it continues
+// until no elements of the returned list are lists
+func DeepFlatten(slice []interface{}, depth int) []interface{} {
+	if depth == 0 {
+		return slice
+	}
+	returnSlice := []interface{}{}
+
+	for _, element := range slice {
+		if s, ok := element.([]interface{}); ok {
+			returnSlice = append(returnSlice, DeepFlatten(s, depth-1)...)
+		} else {
+			returnSlice = append(returnSlice, element)
+		}
+
+	}
+
+	return returnSlice
+}
diff --git a/util/slice/slice_test.go b/util/slice/slice_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..8ab47c99aa03c78a5efcf539807ce68fe3deaa5c
--- /dev/null
+++ b/util/slice/slice_test.go
@@ -0,0 +1,57 @@
+// 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 slice
+
+import (
+	"testing"
+
+	"github.com/stretchr/testify/assert"
+)
+
+func TestCopyAppend(t *testing.T) {
+	assert.Equal(t, Slice(1, "two", "three", 4),
+		CopyAppend(Slice(1, "two"), "three", 4))
+	assert.Equal(t, EmptySlice(), CopyAppend(nil))
+	assert.Equal(t, Slice(1), CopyAppend(nil, 1))
+	assert.Equal(t, Slice(1), CopyAppend(Slice(1)))
+}
+
+func TestCopyPrepend(t *testing.T) {
+	assert.Equal(t, Slice("three", 4, 1, "two"),
+		CopyPrepend(Slice(1, "two"), "three", 4))
+	assert.Equal(t, EmptySlice(), CopyPrepend(nil))
+	assert.Equal(t, Slice(1), CopyPrepend(nil, 1))
+	assert.Equal(t, Slice(1), CopyPrepend(Slice(1)))
+}
+
+func TestConcat(t *testing.T) {
+	assert.Equal(t, Slice(1, 2, 3, 4, 5), Concat(Slice(1, 2, 3, 4, 5)))
+	assert.Equal(t, Slice(1, 2, 3, 4, 5), Concat(Slice(1, 2, 3), Slice(4, 5)))
+	assert.Equal(t, Slice(1, 2, 3, 4, 5), Concat(Slice(1), Slice(2, 3), Slice(4, 5)))
+	assert.Equal(t, EmptySlice(), Concat(nil))
+	assert.Equal(t, Slice(1), Concat(nil, Slice(), Slice(1)))
+	assert.Equal(t, Slice(1), Concat(Slice(1), Slice(), nil))
+}
+
+func TestDelete(t *testing.T) {
+	assert.Equal(t, Slice(1, 2, 4, 5), Delete(Slice(1, 2, 3, 4, 5), 2, 1))
+}
+
+func TestDeepFlatten(t *testing.T) {
+	assert.Equal(t, Flatten(Slice(Slice(1, 2), 3, 4)), Slice(1, 2, 3, 4))
+	nestedSlice := Slice(Slice(1, Slice(Slice(2))), Slice(3, 4))
+	assert.Equal(t, DeepFlatten(nestedSlice, -1), Slice(1, 2, 3, 4))
+	assert.Equal(t, DeepFlatten(nestedSlice, 2), Slice(1, Slice(2), 3, 4))
+}
diff --git a/util/snatives/cmd/main.go b/util/snatives/cmd/main.go
new file mode 100644
index 0000000000000000000000000000000000000000..0b12ba3330329ec4b3c130d5d66b094f971893f8
--- /dev/null
+++ b/util/snatives/cmd/main.go
@@ -0,0 +1,44 @@
+// 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 (
+	"fmt"
+
+	"github.com/eris-ltd/eris-db/manager/eris-mint/evm"
+	"github.com/eris-ltd/eris-db/util/snatives/templates"
+)
+
+// Dump SNative contracts
+func main() {
+	contracts := vm.SNativeContracts()
+	// Index of next contract
+	i := 1
+	fmt.Print("pragma solidity >=0.0.0;\n\n")
+	for _, contract := range contracts {
+		solidity, err := templates.NewSolidityContract(contract).Solidity()
+		if err != nil {
+			fmt.Printf("Error generating solidity for contract %s: %s\n",
+				contract.Name, err)
+		}
+		fmt.Println(solidity)
+		if i < len(contracts) {
+			// Two new lines between contracts as per Solidity style guide
+			// (the template gives us 1 trailing new line)
+			fmt.Println()
+		}
+		i++
+	}
+}
diff --git a/util/snatives/templates/indent_writer.go b/util/snatives/templates/indent_writer.go
new file mode 100644
index 0000000000000000000000000000000000000000..c395f5a9f16da3fae0ce17c4878e3ef38a55eeee
--- /dev/null
+++ b/util/snatives/templates/indent_writer.go
@@ -0,0 +1,61 @@
+// 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 templates
+
+import "io"
+
+const newLine = byte('\n')
+
+type indentWriter struct {
+	writer      io.Writer
+	indentLevel uint
+	indentBytes []byte
+	indent      bool
+}
+
+var _ io.Writer = (*indentWriter)(nil)
+
+// indentWriter indents all lines written to it with a specified indent string
+// indented the specified number of indents
+func NewIndentWriter(indentLevel uint, indentString string,
+	writer io.Writer) *indentWriter {
+	return &indentWriter{
+		writer:      writer,
+		indentLevel: indentLevel,
+		indentBytes: []byte(indentString),
+		indent:      true,
+	}
+}
+
+func (iw *indentWriter) Write(p []byte) (int, error) {
+	bs := make([]byte, 0, len(p))
+	for _, b := range p {
+		if iw.indent {
+			for i := uint(0); i < iw.indentLevel; i++ {
+				bs = append(bs, iw.indentBytes...)
+			}
+			iw.indent = false
+		}
+		if b == newLine {
+			iw.indent = true
+		}
+		bs = append(bs, b)
+	}
+	return iw.writer.Write(bs)
+}
+
+func (iw *indentWriter) SetIndent(level uint) {
+	iw.indentLevel = level
+}
diff --git a/util/snatives/templates/solidity_templates.go b/util/snatives/templates/solidity_templates.go
new file mode 100644
index 0000000000000000000000000000000000000000..eda2c55588632d71677aeadd5c9017bcf05c0bde
--- /dev/null
+++ b/util/snatives/templates/solidity_templates.go
@@ -0,0 +1,173 @@
+// 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 templates
+
+import (
+	"bytes"
+	"fmt"
+	"strings"
+	"text/template"
+
+	"github.com/eris-ltd/eris-db/manager/eris-mint/evm"
+)
+
+const contractTemplateText = `/**
+[[.Comment]]
+* @dev These functions can be accessed as if this contract were deployed at a special address ([[.Address]]).
+* @dev This special address is defined as the last 20 bytes of the sha3 hash of the the contract name.
+* @dev To instantiate the contract use:
+* @dev [[.Name]] [[.InstanceName]] = [[.Name]](address(sha3("[[.Name]]")));
+*/
+contract [[.Name]] {[[range .Functions]]
+[[.SolidityIndent 1]]
+[[end]]}
+`
+const functionTemplateText = `/**
+[[.Comment]]
+*/
+function [[.Name]]([[.ArgList]]) constant returns ([[.Return.TypeName]] [[.Return.Name]]);`
+
+// Solidity style guide recommends 4 spaces per indentation level
+// (see: http://solidity.readthedocs.io/en/develop/style-guide.html)
+const indentString = "    "
+
+var contractTemplate *template.Template
+var functionTemplate *template.Template
+
+func init() {
+	var err error
+	functionTemplate, err = template.New("SolidityFunctionTemplate").
+		Delims("[[", "]]").
+		Parse(functionTemplateText)
+	if err != nil {
+		panic(fmt.Errorf("Couldn't parse SNative function template: %s", err))
+	}
+	contractTemplate, err = template.New("SolidityContractTemplate").
+		Delims("[[", "]]").
+		Parse(contractTemplateText)
+	if err != nil {
+		panic(fmt.Errorf("Couldn't parse SNative contract template: %s", err))
+	}
+}
+
+type solidityContract struct {
+	*vm.SNativeContractDescription
+}
+
+type solidityFunction struct {
+	*vm.SNativeFunctionDescription
+}
+
+//
+// Contract
+//
+
+// Create a templated solidityContract from an SNative contract description
+func NewSolidityContract(contract *vm.SNativeContractDescription) *solidityContract {
+	return &solidityContract{contract}
+}
+
+func (contract *solidityContract) Comment() string {
+	return comment(contract.SNativeContractDescription.Comment)
+}
+
+// Get a version of the contract name to be used for an instance of the contract
+func (contract *solidityContract) InstanceName() string {
+	// Hopefully the contract name is UpperCamelCase. If it's not, oh well, this
+	// is meant to be illustrative rather than cast iron compilable
+	instanceName := strings.ToLower(contract.Name[:1]) + contract.Name[1:]
+	if instanceName == contract.Name {
+		return "contractInstance"
+	}
+	return instanceName
+}
+
+func (contract *solidityContract) Address() string {
+	return fmt.Sprintf("0x%x",
+		contract.SNativeContractDescription.Address())
+}
+
+// Generate Solidity code for this SNative contract
+func (contract *solidityContract) Solidity() (string, error) {
+	buf := new(bytes.Buffer)
+	err := contractTemplate.Execute(buf, contract)
+	if err != nil {
+		return "", err
+	}
+	return buf.String(), nil
+}
+
+func (contract *solidityContract) Functions() []*solidityFunction {
+	functions := contract.SNativeContractDescription.Functions()
+	solidityFunctions := make([]*solidityFunction, len(functions))
+	for i, function := range functions {
+		solidityFunctions[i] = NewSolidityFunction(function)
+	}
+	return solidityFunctions
+}
+
+//
+// Function
+//
+
+// Create a templated solidityFunction from an SNative function description
+func NewSolidityFunction(function *vm.SNativeFunctionDescription) *solidityFunction {
+	return &solidityFunction{function}
+}
+
+func (function *solidityFunction) ArgList() string {
+	argList := make([]string, len(function.Args))
+	for i, arg := range function.Args {
+		argList[i] = fmt.Sprintf("%s %s", arg.TypeName, arg.Name)
+	}
+	return strings.Join(argList, ", ")
+}
+
+func (function *solidityFunction) Comment() string {
+	return comment(function.SNativeFunctionDescription.Comment)
+}
+
+func (function *solidityFunction) SolidityIndent(indentLevel uint) (string, error) {
+	return function.solidity(indentLevel)
+}
+
+func (function *solidityFunction) Solidity() (string, error) {
+	return function.solidity(0)
+}
+
+func (function *solidityFunction) solidity(indentLevel uint) (string, error) {
+	buf := new(bytes.Buffer)
+	iw := NewIndentWriter(indentLevel, indentString, buf)
+	err := functionTemplate.Execute(iw, function)
+	if err != nil {
+		return "", err
+	}
+	return buf.String(), nil
+}
+
+//
+// Utility
+//
+
+func comment(comment string) string {
+	commentLines := make([]string, 0, 5)
+	for _, line := range strings.Split(comment, "\n") {
+		trimLine := strings.TrimLeft(line, " \t\n")
+		if trimLine != "" {
+			commentLines = append(commentLines, trimLine)
+		}
+	}
+	return strings.Join(commentLines, "\n")
+}
diff --git a/util/snatives/templates/solidity_templates_test.go b/util/snatives/templates/solidity_templates_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..c839230ea3bceb141a2e23de0de865b03dd77bae
--- /dev/null
+++ b/util/snatives/templates/solidity_templates_test.go
@@ -0,0 +1,44 @@
+// 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 templates
+
+import (
+	"fmt"
+	"github.com/eris-ltd/eris-db/manager/eris-mint/evm"
+	"github.com/stretchr/testify/assert"
+	"testing"
+)
+
+func TestSNativeFuncTemplate(t *testing.T) {
+	contract := vm.SNativeContracts()["Permissions"]
+	function, err := contract.FunctionByName("removeRole")
+	if err != nil {
+		t.Fatal("Couldn't get function")
+	}
+	solidityFunction := NewSolidityFunction(function)
+	solidity, err := solidityFunction.Solidity()
+	assert.NoError(t, err)
+	fmt.Println(solidity)
+}
+
+// This test checks that we can generate the SNative contract interface and
+// prints it to stdout
+func TestSNativeContractTemplate(t *testing.T) {
+	contract := vm.SNativeContracts()["Permissions"]
+	solidityContract := NewSolidityContract(contract)
+	solidity, err := solidityContract.Solidity()
+	assert.NoError(t, err)
+	fmt.Println(solidity)
+}
diff --git a/util/util.go b/util/util.go
index c0acaefc64d4b75b74c66a4a3802e9edc0d0385f..d170c681553b6d38206ca86d883c30dba72598a5 100644
--- a/util/util.go
+++ b/util/util.go
@@ -1,3 +1,17 @@
+// 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 util
 
 import (
diff --git a/version/version.go b/version/version.go
index 36e4f305ab6f03fc4c49b20d7dfb4f8d9e95254c..103c787d173a6f9b82a8aad73fd90a1266e7ad56 100644
--- a/version/version.go
+++ b/version/version.go
@@ -1,24 +1,22 @@
-// Copyright 2015, 2016 Eris Industries (UK) Ltd.
-// This file is part of Eris-RT
+// 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.
 
-// Eris-RT is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-
-// Eris-RT is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License
-// along with Eris-RT.  If not, see <http://www.gnu.org/licenses/>.
+package version
 
 // version provides the current Eris-DB version and a VersionIdentifier
 // for the modules to identify their version with.
 
-package version
-
 import (
 	"fmt"
 )
@@ -32,9 +30,9 @@ const (
 	// Major version component of the current release
 	erisVersionMajor = 0
 	// Minor version component of the current release
-	erisVersionMinor = 12
+	erisVersionMinor = 16
 	// Patch version component of the current release
-	erisVersionPatch = 1
+	erisVersionPatch = 0
 )
 
 var erisVersion *VersionIdentifier
@@ -129,4 +127,4 @@ func (version *VersionIdentifier) MatchesMinorVersion(
 
 // IMPORTANT: Eris-DB version must be on the last line of this file for
 // the deployment script tests/build_tool.sh to pick up the right label.
-const VERSION = "0.12.1"
+const VERSION = "0.16.0"
diff --git a/word256/byteslice.go b/word256/byteslice.go
new file mode 100644
index 0000000000000000000000000000000000000000..88dbaf7c8625cbffd3cc2a4936697ae10294a6b8
--- /dev/null
+++ b/word256/byteslice.go
@@ -0,0 +1,61 @@
+// 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 word256
+
+// TODO: [ben] byteslice is not specific for word256, but it is used exclusively
+// for word256 (and for word160* 20byte addresses) so consider stronger typing.
+
+import (
+	"bytes"
+)
+
+func Fingerprint(slice []byte) []byte {
+	fingerprint := make([]byte, 6)
+	copy(fingerprint, slice)
+	return fingerprint
+}
+
+func IsZeros(slice []byte) bool {
+	for _, byt := range slice {
+		if byt != byte(0) {
+			return false
+		}
+	}
+	return true
+}
+
+func RightPadBytes(slice []byte, l int) []byte {
+	if l < len(slice) {
+		return slice
+	}
+	padded := make([]byte, l)
+	copy(padded[0:len(slice)], slice)
+	return padded
+}
+
+func LeftPadBytes(slice []byte, l int) []byte {
+	if l < len(slice) {
+		return slice
+	}
+	padded := make([]byte, l)
+	copy(padded[l-len(slice):], slice)
+	return padded
+}
+
+func TrimmedString(b []byte) string {
+	trimSet := string([]byte{0})
+	return string(bytes.TrimLeft(b, trimSet))
+
+}
diff --git a/word256/int.go b/word256/int.go
new file mode 100644
index 0000000000000000000000000000000000000000..7e91add1526de3a818602284ff16062d1fde91fe
--- /dev/null
+++ b/word256/int.go
@@ -0,0 +1,74 @@
+// 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 word256
+
+// NOTE: [ben] this used to be in tendermint/go-common but should be
+// isolated and cleaned up and tested.  Should be used in permissions
+// and manager/eris-mint
+// TODO: [ben] cleanup, but also write unit-tests
+
+import (
+	"encoding/binary"
+	"sort"
+)
+
+// 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) {
+	binary.LittleEndian.PutUint64(dest, i)
+}
+
+func GetUint64LE(src []byte) uint64 {
+	return binary.LittleEndian.Uint64(src)
+}
+
+func PutUint64BE(dest []byte, i uint64) {
+	binary.BigEndian.PutUint64(dest, i)
+}
+
+func GetUint64BE(src []byte) uint64 {
+	return binary.BigEndian.Uint64(src)
+}
+
+func PutInt64LE(dest []byte, i int64) {
+	binary.LittleEndian.PutUint64(dest, uint64(i))
+}
+
+func GetInt64LE(src []byte) int64 {
+	return int64(binary.LittleEndian.Uint64(src))
+}
+
+func PutInt64BE(dest []byte, i int64) {
+	binary.BigEndian.PutUint64(dest, uint64(i))
+}
+
+func GetInt64BE(src []byte) int64 {
+	return int64(binary.BigEndian.Uint64(src))
+}
diff --git a/word256/word.go b/word256/word.go
new file mode 100644
index 0000000000000000000000000000000000000000..e5ce7cb7cdd8ad64757700ee80e125a88124f8dd
--- /dev/null
+++ b/word256/word.go
@@ -0,0 +1,112 @@
+// 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 word256
+
+// NOTE: [ben] this used to be in tendermint/go-common but should be
+// isolated and cleaned up and tested.  Should be used in permissions
+// and manager/eris-mint
+// TODO: [ben] cleanup, but also write unit-tests
+
+import (
+	"bytes"
+	"sort"
+)
+
+var (
+	Zero256 = Word256{0}
+	One256  = Word256{1}
+)
+
+const Word256Length = 32
+
+type Word256 [Word256Length]byte
+
+func (w Word256) String() string        { return string(w[:]) }
+func (w Word256) TrimmedString() string { return TrimmedString(w.Bytes()) }
+func (w Word256) Copy() Word256         { return w }
+func (w Word256) Bytes() []byte         { return w[:] } // copied.
+func (w Word256) Prefix(n int) []byte   { return w[:n] }
+func (w Word256) Postfix(n int) []byte  { return w[32-n:] }
+func (w Word256) IsZero() bool {
+	accum := byte(0)
+	for _, byt := range w {
+		accum |= byt
+	}
+	return accum == 0
+}
+func (w Word256) Compare(other Word256) int {
+	return bytes.Compare(w[:], other[:])
+}
+
+func Uint64ToWord256(i uint64) Word256 {
+	buf := [8]byte{}
+	PutUint64BE(buf[:], i)
+	return LeftPadWord256(buf[:])
+}
+
+func Int64ToWord256(i int64) Word256 {
+	buf := [8]byte{}
+	PutInt64BE(buf[:], i)
+	return LeftPadWord256(buf[:])
+}
+
+func RightPadWord256(bz []byte) (word Word256) {
+	copy(word[:], bz)
+	return
+}
+
+func LeftPadWord256(bz []byte) (word Word256) {
+	copy(word[32-len(bz):], bz)
+	return
+}
+
+func Uint64FromWord256(word Word256) uint64 {
+	buf := word.Postfix(8)
+	return GetUint64BE(buf)
+}
+
+func Int64FromWord256(word Word256) int64 {
+	buf := word.Postfix(8)
+	return GetInt64BE(buf)
+}
+
+//-------------------------------------
+
+type Tuple256 struct {
+	First  Word256
+	Second Word256
+}
+
+func (tuple Tuple256) Compare(other Tuple256) int {
+	firstCompare := tuple.First.Compare(other.First)
+	if firstCompare == 0 {
+		return tuple.Second.Compare(other.Second)
+	} else {
+		return firstCompare
+	}
+}
+
+func Tuple256Split(t Tuple256) (Word256, Word256) {
+	return t.First, t.Second
+}
+
+type Tuple256Slice []Tuple256
+
+func (p Tuple256Slice) Len() int { return len(p) }
+func (p Tuple256Slice) Less(i, j int) bool {
+	return p[i].Compare(p[j]) < 0
+}
+func (p Tuple256Slice) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
+func (p Tuple256Slice) Sort()         { sort.Sort(p) }