diff --git a/account/account.go b/account/account.go
index 4cb846ace1b0f74c2c95f08ac8c5d8e86793f25b..54f862feaa6ac6501edc3f07c3c3401e96560c5c 100644
--- a/account/account.go
+++ b/account/account.go
@@ -73,9 +73,9 @@ type MutableAccount interface {
 	// Set public key (needed for lazy initialisation), should also set the dependent address
 	SetPublicKey(pubKey PublicKey) MutableAccount
 	// Subtract amount from account balance (will panic if amount is greater than balance)
-	SubtractFromBalance(amount uint64) MutableAccount
+	SubtractFromBalance(amount uint64) (MutableAccount, error)
 	// Add amount to balance (will panic if amount plus balance is a uint64 overflow)
-	AddToBalance(amount uint64) MutableAccount
+	AddToBalance(amount uint64) (MutableAccount, error)
 	// Set EVM byte code associated with account
 	SetCode(code []byte) MutableAccount
 	// Increment Sequence number by 1 (capturing the current Sequence number as the index for any pending mutations)
@@ -162,6 +162,7 @@ func AsConcreteAccount(account Account) *ConcreteAccount {
 	if account == nil {
 		return nil
 	}
+	// Avoid a copy
 	if ca, ok := account.(concreteAccountWrapper); ok {
 		return ca.ConcreteAccount
 	}
@@ -211,13 +212,6 @@ func GetMutableAccount(getter Getter, address Address) (MutableAccount, error) {
 	if err != nil {
 		return nil, err
 	}
-	// If we get get our own concreteAccountWrapper back we can save an unnecessary copy and just
-	// return since ConcreteAccount.Account() will have been used to produce it which will already
-	// have copied
-	caw, ok := acc.(concreteAccountWrapper)
-	if ok {
-		return caw, nil
-	}
 	return AsMutableAccount(acc), nil
 }
 
@@ -284,22 +278,22 @@ func (caw concreteAccountWrapper) SetPublicKey(pubKey PublicKey) MutableAccount
 	return caw
 }
 
-func (caw concreteAccountWrapper) SubtractFromBalance(amount uint64) MutableAccount {
+func (caw concreteAccountWrapper) SubtractFromBalance(amount uint64) (MutableAccount, error) {
 	if amount > caw.Balance() {
-		panic(fmt.Errorf("insufficient funds: attempt to subtract %v from the balance of %s",
-			amount, caw.ConcreteAccount))
+		return nil, fmt.Errorf("insufficient funds: attempt to subtract %v from the balance of %s",
+			amount, caw.ConcreteAccount)
 	}
 	caw.ConcreteAccount.Balance -= amount
-	return caw
+	return caw, nil
 }
 
-func (caw concreteAccountWrapper) AddToBalance(amount uint64) MutableAccount {
+func (caw concreteAccountWrapper) AddToBalance(amount uint64) (MutableAccount, error) {
 	if binary.IsUint64SumOverflow(caw.Balance(), amount) {
-		panic(fmt.Errorf("uint64 overflow: attempt to add %v to the balance of %s",
-			amount, caw.ConcreteAccount))
+		return nil, fmt.Errorf("uint64 overflow: attempt to add %v to the balance of %s",
+			amount, caw.ConcreteAccount)
 	}
 	caw.ConcreteAccount.Balance += amount
-	return caw
+	return caw, nil
 }
 
 func (caw concreteAccountWrapper) SetCode(code []byte) MutableAccount {
diff --git a/client/cmd/burrow-client.go b/client/cmd/burrow-client.go
index 23e10c4482490241ea70b4ce21f5b5c4bd1ae072..b06833f4baa932bf0e7824d83832d82cc28db83a 100644
--- a/client/cmd/burrow-client.go
+++ b/client/cmd/burrow-client.go
@@ -58,10 +58,6 @@ func AddGlobalFlags() {
 func AddClientCommands() {
 	BurrowClientCmd.AddCommand(buildTransactionCommand())
 	BurrowClientCmd.AddCommand(buildStatusCommand())
-
-	buildGenesisGenCommand()
-	BurrowClientCmd.AddCommand(GenesisGenCmd)
-
 }
 
 //------------------------------------------------------------------------------
diff --git a/client/cmd/genesis.go b/client/cmd/genesis.go
deleted file mode 100644
index cb2d4fb19c32840851f8b770692e1213097bf672..0000000000000000000000000000000000000000
--- a/client/cmd/genesis.go
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright 2017 Monax Industries Limited
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//    http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package commands
-
-import (
-	"fmt"
-
-	"github.com/hyperledger/burrow/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: "burrow-client make-genesis creates a genesis.json with known inputs",
-	Long:  "burrow-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 {
-			panic(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/cmd/burrow/main.go b/cmd/burrow/main.go
index 2133020523639f18a0e788ab975cfbaf4fddd05d..a7bb0629950951287f331364617e2c006ab459ab 100644
--- a/cmd/burrow/main.go
+++ b/cmd/burrow/main.go
@@ -59,20 +59,31 @@ func main() {
 			tomlOpt := cmd.BoolOpt("t toml", false, "Emit GenesisSpec as TOML rather than the "+
 				"default JSON")
 
-			participantsOpt := cmd.IntOpt("p participant-accounts", 1, "Number of preset Participant type accounts")
-
 			fullOpt := cmd.IntOpt("f full-accounts", 1, "Number of preset Full type accounts")
+			validatorOpt := cmd.IntOpt("v validator-accounts", 0, "Number of preset Validator type accounts")
+			rootOpt := cmd.IntOpt("r root-accounts", 0, "Number of preset Root type accounts")
+			developerOpt := cmd.IntOpt("d developer-accounts", 0, "Number of preset Developer type accounts")
+			participantsOpt := cmd.IntOpt("p participant-accounts", 1, "Number of preset Participant type accounts")
 
-			cmd.Spec = "[--participant-accounts] [--full-accounts] [--toml]"
+			cmd.Spec = "[--full-accounts] [--validator-accounts] [--root-accounts] [--developer-accounts] [--participant-accounts] [--toml]"
 
 			cmd.Action = func() {
 				specs := make([]spec.GenesisSpec, 0, *participantsOpt+*fullOpt)
-				for i := 0; i < *participantsOpt; i++ {
-					specs = append(specs, spec.ParticipantAccount(i))
-				}
 				for i := 0; i < *fullOpt; i++ {
 					specs = append(specs, spec.FullAccount(i))
 				}
+				for i := 0; i < *validatorOpt; i++ {
+					specs = append(specs, spec.ValidatorAccount(i))
+				}
+				for i := 0; i < *rootOpt; i++ {
+					specs = append(specs, spec.RootAccount(i))
+				}
+				for i := 0; i < *developerOpt; i++ {
+					specs = append(specs, spec.DeveloperAccount(i))
+				}
+				for i := 0; i < *participantsOpt; i++ {
+					specs = append(specs, spec.ParticipantAccount(i))
+				}
 				genesisSpec := spec.MergeGenesisSpecs(specs...)
 				if *tomlOpt {
 					os.Stdout.WriteString(source.TOMLString(genesisSpec))
@@ -177,7 +188,7 @@ func main() {
 					ops := strings.Split(*loggingOpt, ",")
 					sinkConfig, err := presets.BuildSinkConfig(ops...)
 					if err != nil {
-						fatalf("could not build logging configuration: %v\n\nTo see possible logging " +
+						fatalf("could not build logging configuration: %v\n\nTo see possible logging "+
 							"instructions run:\n  burrow configure --describe-logging", err)
 					}
 					conf.Logging = &logging_config.LoggingConfig{
diff --git a/execution/evm/vm.go b/execution/evm/vm.go
index 2813a5e5254a2261fc24d5f80a48a2ddf8ff7a68..780d30321ea0558e8822be6de0e372839e6c9dca 100644
--- a/execution/evm/vm.go
+++ b/execution/evm/vm.go
@@ -953,7 +953,10 @@ func (vm *VM) call(caller, callee acm.MutableAccount, code, input []byte, value
 				return nil, firstErr(err, ErrUnknownAddress)
 			}
 
-			receiver.AddToBalance(callee.Balance())
+			receiver, errAdd := receiver.AddToBalance(callee.Balance())
+			if errAdd != nil {
+				return nil, firstErr(err, errAdd)
+			}
 			vm.state.UpdateAccount(receiver)
 			vm.state.RemoveAccount(callee.Address())
 			vm.Debugf(" => (%X) %v\n", addr[:4], callee.Balance())
@@ -1026,7 +1029,10 @@ func transfer(from, to acm.MutableAccount, amount uint64) error {
 		return ErrInsufficientBalance
 	} else {
 		from.SubtractFromBalance(amount)
-		to.AddToBalance(amount)
-		return nil
+		_, err := to.AddToBalance(amount)
+		if err != nil {
+			return err
+		}
 	}
+	return nil
 }
diff --git a/execution/evm/vm_test.go b/execution/evm/vm_test.go
index 523ed41d789e287b7119eb075feefd4273343dd6..4e8beb6884ccd45a1ceef7a6cce688ebd655c7e4 100644
--- a/execution/evm/vm_test.go
+++ b/execution/evm/vm_test.go
@@ -35,6 +35,7 @@ import (
 	"github.com/hyperledger/burrow/logging/loggers"
 	"github.com/hyperledger/burrow/permission"
 	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/require"
 )
 
 var logger, _ = lifecycle.NewStdErrLogger()
@@ -164,13 +165,15 @@ func TestSendCall(t *testing.T) {
 
 	//----------------------------------------------
 	// give account2 sufficient balance, should pass
-	account2 = newAccount(2).AddToBalance(100000)
+	account2, err = newAccount(2).AddToBalance(100000)
+	require.NoError(t, err)
 	_, err = runVMWaitError(ourVm, account1, account2, addr, contractCode, 1000)
 	assert.NoError(t, err, "Should have sufficient balance")
 
 	//----------------------------------------------
 	// insufficient gas, should fail
-	account2 = newAccount(2).AddToBalance(100000)
+	account2, err = newAccount(2).AddToBalance(100000)
+	require.NoError(t, err)
 	_, err = runVMWaitError(ourVm, account1, account2, addr, contractCode, 100)
 	assert.Error(t, err, "Expected insufficient gas error")
 }
diff --git a/execution/execution.go b/execution/execution.go
index 103a8607fda0dd9e645e67c650426eb1b95076f4..baee18176510a1ad4eca87a46126f5a7b904dfb6 100644
--- a/execution/execution.go
+++ b/execution/execution.go
@@ -191,8 +191,16 @@ func (exe *executor) Execute(tx txs.Tx) error {
 		fees += fee
 
 		// Good! Adjust accounts
-		adjustByInputs(accounts, tx.Inputs)
-		adjustByOutputs(accounts, tx.Outputs)
+		err = adjustByInputs(accounts, tx.Inputs)
+		if err != nil {
+			return err
+		}
+
+		err = adjustByOutputs(accounts, tx.Outputs)
+		if err != nil {
+			return err
+		}
+
 		for _, acc := range accounts {
 			exe.blockCache.UpdateAccount(acc)
 		}
@@ -282,7 +290,11 @@ func (exe *executor) Execute(tx txs.Tx) error {
 			"account", inAcc.Address(),
 			"old_sequence", inAcc.Sequence(),
 			"new_sequence", inAcc.Sequence()+1)
-		inAcc.IncSequence().SubtractFromBalance(tx.Fee)
+
+		inAcc, err = inAcc.IncSequence().SubtractFromBalance(tx.Fee)
+		if err != nil {
+			return err
+		}
 
 		exe.blockCache.UpdateAccount(inAcc)
 
@@ -396,7 +408,10 @@ func (exe *executor) Execute(tx txs.Tx) error {
 			// the proposer determines the order of txs.
 			// So mempool will skip the actual .Call(),
 			// and only deduct from the caller's balance.
-			inAcc.SubtractFromBalance(value)
+			inAcc, err = inAcc.SubtractFromBalance(value)
+			if err != nil {
+				return err
+			}
 			if createContract {
 				// This is done by DeriveNewAccount when runCall == true
 
@@ -541,7 +556,10 @@ func (exe *executor) Execute(tx txs.Tx) error {
 
 		// Good!
 		inAcc.IncSequence()
-		inAcc.SubtractFromBalance(value)
+		inAcc, err = inAcc.SubtractFromBalance(value)
+		if err != nil {
+			return err
+		}
 		exe.blockCache.UpdateAccount(inAcc)
 
 		// TODO: maybe we want to take funds on error and allow txs in that don't do anythingi?
@@ -771,7 +789,7 @@ func (exe *executor) Execute(tx txs.Tx) error {
 					return nil
 				})
 		default:
-			panic(fmt.Sprintf("invalid permission function: %s", permission.PermFlagToString(permFlag)))
+			return fmt.Errorf("invalid permission function: %s", permission.PermFlagToString(permFlag))
 		}
 
 		// TODO: maybe we want to take funds on error and allow txs in that don't do anythingi?
@@ -781,7 +799,10 @@ func (exe *executor) Execute(tx txs.Tx) error {
 
 		// Good!
 		inAcc.IncSequence()
-		inAcc.SubtractFromBalance(value)
+		inAcc, err = inAcc.SubtractFromBalance(value)
+		if err != nil {
+			return err
+		}
 		exe.blockCache.UpdateAccount(inAcc)
 		if permAcc != nil {
 			exe.blockCache.UpdateAccount(permAcc)
@@ -798,8 +819,7 @@ func (exe *executor) Execute(tx txs.Tx) error {
 
 	default:
 		// binary decoding should not let this happen
-		panic("Unknown Tx type")
-		return nil
+		return fmt.Errorf("unknown Tx type: %#v", tx)
 	}
 }
 
@@ -1036,15 +1056,16 @@ func checkInputPubKey(acc acm.MutableAccount, in *txs.TxInput) error {
 	return nil
 }
 
-func validateInputs(accs map[acm.Address]acm.MutableAccount, signBytes []byte, ins []*txs.TxInput) (total uint64, err error) {
+func validateInputs(accs map[acm.Address]acm.MutableAccount, signBytes []byte, ins []*txs.TxInput) (uint64, error) {
+	total := uint64(0)
 	for _, in := range ins {
 		acc := accs[in.Address]
 		if acc == nil {
-			panic("validateInputs() expects account in accounts")
+			return 0, fmt.Errorf("validateInputs() expects account in accounts, but account %s not found", in.Address)
 		}
-		err = validateInput(acc, signBytes, in)
+		err := validateInput(acc, signBytes, in)
 		if err != nil {
-			return
+			return 0, err
 		}
 		// Good. Add amount to total
 		total += in.Amount
@@ -1052,7 +1073,7 @@ func validateInputs(accs map[acm.Address]acm.MutableAccount, signBytes []byte, i
 	return total, nil
 }
 
-func validateInput(acc acm.MutableAccount, signBytes []byte, in *txs.TxInput) (err error) {
+func validateInput(acc acm.MutableAccount, signBytes []byte, in *txs.TxInput) error {
 	// Check TxInput basic
 	if err := in.ValidateBasic(); err != nil {
 		return err
@@ -1075,7 +1096,8 @@ func validateInput(acc acm.MutableAccount, signBytes []byte, in *txs.TxInput) (e
 	return nil
 }
 
-func validateOutputs(outs []*txs.TxOutput) (total uint64, err error) {
+func validateOutputs(outs []*txs.TxOutput) (uint64, error) {
+	total := uint64(0)
 	for _, out := range outs {
 		// Check TxOutput basic
 		if err := out.ValidateBasic(); err != nil {
@@ -1087,36 +1109,45 @@ func validateOutputs(outs []*txs.TxOutput) (total uint64, err error) {
 	return total, nil
 }
 
-func adjustByInputs(accs map[acm.Address]acm.MutableAccount, ins []*txs.TxInput) {
+func adjustByInputs(accs map[acm.Address]acm.MutableAccount, ins []*txs.TxInput) error {
 	for _, in := range ins {
 		acc := accs[in.Address]
 		if acc == nil {
-			panic("adjustByInputs() expects account in accounts")
+			return fmt.Errorf("adjustByInputs() expects account in accounts, but account %s not found", in.Address)
 		}
 		if acc.Balance() < in.Amount {
 			panic("adjustByInputs() expects sufficient funds")
+			return fmt.Errorf("adjustByInputs() expects sufficient funds but account %s only has balance %v and "+
+				"we are deducting %v", in.Address, acc.Balance(), in.Amount)
+		}
+		acc, err := acc.SubtractFromBalance(in.Amount)
+		if err != nil {
+			return err
 		}
-		acc.SubtractFromBalance(in.Amount)
-
 		acc.IncSequence()
 	}
+	return nil
 }
 
-func adjustByOutputs(accs map[acm.Address]acm.MutableAccount, outs []*txs.TxOutput) {
+func adjustByOutputs(accs map[acm.Address]acm.MutableAccount, outs []*txs.TxOutput) error {
 	for _, out := range outs {
 		acc := accs[out.Address]
 		if acc == nil {
-			panic("adjustByOutputs() expects account in accounts")
+			return fmt.Errorf("adjustByOutputs() expects account in accounts, but account %s not found",
+				out.Address)
+		}
+		_, err := acc.AddToBalance(out.Amount)
+		if err != nil {
+			return err
 		}
-		acc.AddToBalance(out.Amount)
 	}
+	return nil
 }
 
 //---------------------------------------------------------------
 
 // Get permission on an account or fall back to global value
-func HasPermission(accountGetter acm.Getter, acc acm.Account, perm ptypes.PermFlag,
-	logger logging_types.InfoTraceLogger) bool {
+func HasPermission(accountGetter acm.Getter, acc acm.Account, perm ptypes.PermFlag, logger logging_types.InfoTraceLogger) bool {
 	if perm > permission.AllPermFlags {
 		panic("Checking an unknown permission in state should never happen")
 	}
diff --git a/genesis/maker.go b/genesis/maker.go
deleted file mode 100644
index 7b722b46062e93ce4be13987c14d939d4df284a2..0000000000000000000000000000000000000000
--- a/genesis/maker.go
+++ /dev/null
@@ -1,324 +0,0 @@
-// Copyright 2017 Monax Industries Limited
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//    http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package genesis
-
-import (
-	"bytes"
-	"encoding/csv"
-	"encoding/hex"
-	"encoding/json"
-	"fmt"
-	"os"
-	"strconv"
-	"time"
-
-	acm "github.com/hyperledger/burrow/account"
-	"github.com/hyperledger/burrow/permission"
-	ptypes "github.com/hyperledger/burrow/permission/types"
-	"github.com/hyperledger/burrow/util"
-	"github.com/tendermint/go-crypto"
-	wire "github.com/tendermint/go-wire"
-)
-
-const (
-	PublicKeyEd25519ByteLength   int = 32
-	PublicKeySecp256k1ByteLength int = 64
-)
-
-// NewGenesisAccount returns a new Account
-func NewGenesisAccount(address acm.Address, amount uint64, name string,
-	permissions *ptypes.AccountPermissions) *Account {
-	return &Account{
-		BasicAccount: BasicAccount{
-			Address: address,
-			Amount:  amount,
-		},
-		Name:        name,
-		Permissions: permissions.Clone(),
-	}
-}
-
-func NewGenesisValidator(amount uint64, name string, unbondToAddress acm.Address,
-	unbondAmount uint64, keyType string, publicKeyBytes []byte) (*Validator, error) {
-	// convert the key bytes into a typed fixed size byte array
-	var typedPublicKeyBytes []byte
-	switch keyType {
-	case "ed25519": // ed25519 has type byte 0x01
-		// 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 (%v bytes provided but expected %v bytes)",
-				len(publicKeyBytes), PublicKeyEd25519ByteLength)
-		}
-		// prepend type byte to public key
-		typedPublicKeyBytes = append([]byte{crypto.TypeEd25519}, publicKeyBytes...)
-	case "secp256k1": // secp256k1 has type byte 0x02
-		if len(publicKeyBytes) != PublicKeySecp256k1ByteLength {
-			return nil, fmt.Errorf("Invalid length provided for secp256k1 public key (%v bytes provided but expected %v bytes)",
-				len(publicKeyBytes), PublicKeySecp256k1ByteLength)
-		}
-		// prepend type byte to public key
-		typedPublicKeyBytes = append([]byte{crypto.TypeSecp256k1}, publicKeyBytes...)
-	default:
-		return nil, fmt.Errorf("Unsupported key type (%s)", keyType)
-	}
-	newPubKey, err := crypto.PubKeyFromBytes(typedPublicKeyBytes)
-	if err != nil {
-		return nil, err
-	}
-	// ability to unbond to multiple accounts currently unused
-	var unbondTo []BasicAccount
-
-	address, err := acm.AddressFromBytes(newPubKey.Address())
-	if err != nil {
-		return nil, err
-	}
-	return &Validator{
-		BasicAccount: BasicAccount{
-			Address:   address,
-			PublicKey: acm.PublicKeyFromPubKey(newPubKey),
-			Amount:    amount,
-		},
-		Name: name,
-		UnbondTo: append(unbondTo, BasicAccount{
-			Address: unbondToAddress,
-			Amount:  unbondAmount,
-		}),
-	}, nil
-}
-
-//------------------------------------------------------------------------------------
-// interface functions that are consumed by monax tooling
-
-func GenerateKnown(chainName, accountsPathCSV, validatorsPathCSV string) (string, error) {
-	return generateKnownWithTime(chainName, accountsPathCSV, validatorsPathCSV,
-		// set the timestamp for the genesis
-		time.Now())
-}
-
-//------------------------------------------------------------------------------------
-// interface functions that are consumed by monax tooling
-
-func GenerateGenesisFileBytes(chainName string, salt []byte, genesisTime time.Time, genesisAccounts map[string]acm.Account,
-	genesisValidators map[string]acm.Validator) ([]byte, error) {
-
-	genesisDoc := MakeGenesisDocFromAccounts(chainName, salt, genesisTime, genesisAccounts, genesisValidators)
-
-	var err error
-	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 chainName, 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(chainName, 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(chainName, 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(chainName string, genesisTime time.Time, nVal, nAcc int) *GenesisDoc {
-	genDoc := GenesisDoc{
-		ChainName:   chainName,
-		GenesisTime: genesisTime,
-	}
-	genDoc.Accounts = make([]Account, nAcc)
-	genDoc.Validators = make([]Validator, nVal)
-	return &genDoc
-}
-
-func genDocAddAccount(genDoc *GenesisDoc, pubKey crypto.PubKeyEd25519, amt uint64, name string,
-	perm, setbit ptypes.PermFlag, index int) {
-	addr, _ := acm.AddressFromBytes(pubKey.Address())
-	acc := Account{
-		BasicAccount: BasicAccount{
-			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 uint64, name string,
-	perm, setbit ptypes.PermFlag, index int) {
-	addr, _ := acm.AddressFromBytes(pubKey.Address())
-	genDoc.Validators[index] = Validator{
-		BasicAccount: BasicAccount{
-			Address:   acm.MustAddressFromBytes(pubKey.Address()),
-			PublicKey: acm.PublicKeyFromPubKey(pubKey.Wrap()),
-			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 []uint64, 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", permission.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([]uint64, len(amtS))
-	for i, a := range amtS {
-		if amts[i], err = strconv.ParseUint(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/spec/presets.go b/genesis/spec/presets.go
index 727b9236e869b5ac1ede7374226155f17dbc9c81..28f3ac94e0c77857976ec37b610c4bb2459138dc 100644
--- a/genesis/spec/presets.go
+++ b/genesis/spec/presets.go
@@ -26,13 +26,56 @@ func FullAccount(index int) GenesisSpec {
 	}
 }
 
+func RootAccount(index int) GenesisSpec {
+	// Inheriting from the arbitrary figures used by monax tool for now
+	amount := uint64(99999999999999)
+	return GenesisSpec{
+		Accounts: []TemplateAccount{{
+			Name:        fmt.Sprintf("Root_%v", index),
+			Amount:      &amount,
+			Permissions: []string{permission.AllString},
+		},
+		},
+	}
+}
+
 func ParticipantAccount(index int) GenesisSpec {
+	// Inheriting from the arbitrary figures used by monax tool for now
 	amount := uint64(9999999999)
 	return GenesisSpec{
 		Accounts: []TemplateAccount{{
-			Name:        fmt.Sprintf("Participant_%v", index),
-			Amount:      &amount,
-			Permissions: []string{permission.SendString, permission.CallString, permission.NameString, permission.HasRoleString},
+			Name:   fmt.Sprintf("Participant_%v", index),
+			Amount: &amount,
+			Permissions: []string{permission.SendString, permission.CallString, permission.NameString,
+				permission.HasRoleString},
+		}},
+	}
+}
+
+func DeveloperAccount(index int) GenesisSpec {
+	// Inheriting from the arbitrary figures used by monax tool for now
+	amount := uint64(9999999999)
+	return GenesisSpec{
+		Accounts: []TemplateAccount{{
+			Name:   fmt.Sprintf("Developer_%v", index),
+			Amount: &amount,
+			Permissions: []string{permission.SendString, permission.CallString, permission.CreateContractString,
+				permission.CreateAccountString, permission.NameString, permission.HasRoleString,
+				permission.RemoveRoleString},
+		}},
+	}
+}
+
+func ValidatorAccount(index int) GenesisSpec {
+	// Inheriting from the arbitrary figures used by monax tool for now
+	amount := uint64(9999999999)
+	amountBonded := amount - 1
+	return GenesisSpec{
+		Accounts: []TemplateAccount{{
+			Name:         fmt.Sprintf("Validator_%v", index),
+			Amount:       &amount,
+			AmountBonded: &amountBonded,
+			Permissions: []string{permission.BondString},
 		}},
 	}
 }