cosmos-sdk/server/init.go

191 lines
5.0 KiB
Go

package server
import (
"encoding/json"
"fmt"
"github.com/cosmos/cosmos-sdk/crypto/keys"
"github.com/pkg/errors"
"github.com/spf13/pflag"
"github.com/tendermint/tendermint/crypto"
dbm "github.com/tendermint/tendermint/libs/db"
tmtypes "github.com/tendermint/tendermint/types"
clkeys "github.com/cosmos/cosmos-sdk/client/keys"
"github.com/cosmos/cosmos-sdk/codec"
serverconfig "github.com/cosmos/cosmos-sdk/server/config"
sdk "github.com/cosmos/cosmos-sdk/types"
)
//Parameter names, for init gen-tx command
var (
FlagName = "name"
FlagClientHome = "home-client"
FlagOWK = "owk"
)
//parameter names, init command
var (
FlagOverwrite = "overwrite"
FlagWithTxs = "with-txs"
FlagIP = "ip"
FlagChainID = "chain-id"
)
// genesis piece structure for creating combined genesis
type GenesisTx struct {
NodeID string `json:"node_id"`
IP string `json:"ip"`
Validator tmtypes.GenesisValidator `json:"validator"`
AppGenTx json.RawMessage `json:"app_gen_tx"`
}
// Storage for init command input parameters
type InitConfig struct {
ChainID string
GenTxs bool
GenTxsDir string
Overwrite bool
}
//________________________________________________________________________________________
//_____________________________________________________________________
// Core functionality passed from the application to the server init command
type AppInit struct {
// flags required for application init functions
FlagsAppGenState *pflag.FlagSet
FlagsAppGenTx *pflag.FlagSet
// create the application genesis tx
AppGenTx func(cdc *codec.Codec, pk crypto.PubKey, genTxConfig serverconfig.GenTx) (
appGenTx, cliPrint json.RawMessage, validator tmtypes.GenesisValidator, err error)
// AppGenState creates the core parameters initialization. It takes in a
// pubkey meant to represent the pubkey of the validator of this machine.
AppGenState func(cdc *codec.Codec, appGenTxs []json.RawMessage) (appState json.RawMessage, err error)
}
//_____________________________________________________________________
// simple default application init
var DefaultAppInit = AppInit{
AppGenTx: SimpleAppGenTx,
AppGenState: SimpleAppGenState,
}
// simple genesis tx
type SimpleGenTx struct {
Addr sdk.AccAddress `json:"addr"`
}
// Generate a genesis transaction
func SimpleAppGenTx(cdc *codec.Codec, pk crypto.PubKey, genTxConfig serverconfig.GenTx) (
appGenTx, cliPrint json.RawMessage, validator tmtypes.GenesisValidator, err error) {
var addr sdk.AccAddress
var secret string
addr, secret, err = GenerateCoinKey()
if err != nil {
return
}
var bz []byte
simpleGenTx := SimpleGenTx{addr}
bz, err = cdc.MarshalJSON(simpleGenTx)
if err != nil {
return
}
appGenTx = json.RawMessage(bz)
mm := map[string]string{"secret": secret}
bz, err = cdc.MarshalJSON(mm)
if err != nil {
return
}
cliPrint = json.RawMessage(bz)
validator = tmtypes.GenesisValidator{
PubKey: pk,
Power: 10,
}
return
}
// create the genesis app state
func SimpleAppGenState(cdc *codec.Codec, appGenTxs []json.RawMessage) (appState json.RawMessage, err error) {
if len(appGenTxs) != 1 {
err = errors.New("must provide a single genesis transaction")
return
}
var genTx SimpleGenTx
err = cdc.UnmarshalJSON(appGenTxs[0], &genTx)
if err != nil {
return
}
appState = json.RawMessage(fmt.Sprintf(`{
"accounts": [{
"address": "%s",
"coins": [
{
"denom": "mycoin",
"amount": "9007199254740992"
}
]
}]
}`, genTx.Addr))
return
}
//___________________________________________________________________________________________
// GenerateCoinKey returns the address of a public key, along with the secret
// phrase to recover the private key.
func GenerateCoinKey() (sdk.AccAddress, string, error) {
// construct an in-memory key store
keybase := keys.New(
dbm.NewMemDB(),
)
// generate a private key, with recovery phrase
info, secret, err := keybase.CreateMnemonic("name", keys.English, "pass", keys.Secp256k1)
if err != nil {
return sdk.AccAddress([]byte{}), "", err
}
addr := info.GetPubKey().Address()
return sdk.AccAddress(addr), secret, nil
}
// GenerateSaveCoinKey returns the address of a public key, along with the secret
// phrase to recover the private key.
func GenerateSaveCoinKey(clientRoot, keyName, keyPass string, overwrite bool) (sdk.AccAddress, string, error) {
// get the keystore from the client
keybase, err := clkeys.GetKeyBaseFromDir(clientRoot)
if err != nil {
return sdk.AccAddress([]byte{}), "", err
}
// ensure no overwrite
if !overwrite {
_, err := keybase.Get(keyName)
if err == nil {
return sdk.AccAddress([]byte{}), "", errors.New("key already exists, overwrite is disabled")
}
}
// generate a private key, with recovery phrase
info, secret, err := keybase.CreateMnemonic(keyName, keys.English, keyPass, keys.Secp256k1)
if err != nil {
return sdk.AccAddress([]byte{}), "", err
}
addr := info.GetPubKey().Address()
return sdk.AccAddress(addr), secret, nil
}