server: consolidate files

This commit is contained in:
Ethan Buchman 2018-04-05 13:31:33 +03:00
parent 609ea0d0f0
commit 9fbbdbbe0f
10 changed files with 159 additions and 313 deletions

View File

@ -1,70 +0,0 @@
# Basecoin
This is the "Basecoin" example application built on the Cosmos-Sdk. This
"Basecoin" is not affiliated with [Coinbase](http://www.getbasecoin.com/), nor
the [stable coin](http://www.getbasecoin.com/).
Assuming you've run `make get_tools && make get_vendor_deps` from the root of
this repository, run `make build` here to build the `basecoind` and `basecli`
binaries.
If you want to create a new application, start by copying the Basecoin app.
# Building your own Blockchain
Basecoin is the equivalent of an ERC20 token contract for blockchains. In order
to deploy your own application all you need to do is clone `examples/basecoin`
and run it. Now you are already running your own blockchain. In the following
I will explain how to add functionality to your blockchain. This is akin to
defining your own vesting schedule within a contract or setting a specific
multisig. You are just extending the base layer with extra functionality here
and there.
## Structure of Basecoin
Basecoin is build with the cosmos-sdk. It is a sample application that works
with any engine that implements the ABCI protocol. Basecoin defines multiple
unique modules as well as uses modules directly from the sdk. If you want
to modify Basecoin, you either remove or add modules according to your wishes.
## Modules
A module is a fundamental unit in the cosmos-sdk. A module defines its own
transaction, handles its own state as well as its own state transition logic.
Globally, in the `app/app.go` file you just have to define a key for that
module to access some parts of the state, as well as initialise the module
object and finally add it to the transaction router. The router ensures that
every module only gets its own messages.
## Transactions
A user can send a transaction to the running blockchain application. This
transaction can be of any of the ones that are supported by any of the
registered modules.
### CheckTx
Once a user has submitted their transaction to the engine,
the engine will first run `checkTx` to confirm that it is a valid transaction.
The module has to define a handler that knows how to handle every transaction
type. The corresponding handler gets invoked with the checkTx flag set to true.
This means that the handler shouldn't do any expensive operations, but it can
and should write to the checkTx state.
### DeliverTx
The engine calls `deliverTx` when a new block has been agreed upon in
consensus. Again, the corresponding module will have its handler invoked
and the state and context is passed in. During deliverTx execution the
transaction needs to be processed fully and the results are written to the
application state.
## CLI
The cosmos-sdk contains a number of helper libraries in `clients/` to build cli
and RPC interfaces for your specific application.

View File

@ -1,70 +0,0 @@
# Democoin
This is the "Democoin" example application built on the Cosmos-Sdk. This
"Democoin" is not affiliated with [Coinbase](http://www.getdemocoin.com/), nor
the [stable coin](http://www.getdemocoin.com/).
Assuming you've run `make get_tools && make get_vendor_deps` from the root of
this repository, run `make build` here to build the `democoind` and `basecli`
binaries.
If you want to create a new application, start by copying the Democoin app.
# Building your own Blockchain
Democoin is the equivalent of an ERC20 token contract for blockchains. In order
to deploy your own application all you need to do is clone `examples/democoin`
and run it. Now you are already running your own blockchain. In the following
I will explain how to add functionality to your blockchain. This is akin to
defining your own vesting schedule within a contract or setting a specific
multisig. You are just extending the base layer with extra functionality here
and there.
## Structure of Democoin
Democoin is build with the cosmos-sdk. It is a sample application that works
with any engine that implements the ABCI protocol. Democoin defines multiple
unique modules as well as uses modules directly from the sdk. If you want
to modify Democoin, you either remove or add modules according to your wishes.
## Modules
A module is a fundamental unit in the cosmos-sdk. A module defines its own
transaction, handles its own state as well as its own state transition logic.
Globally, in the `app/app.go` file you just have to define a key for that
module to access some parts of the state, as well as initialise the module
object and finally add it to the transaction router. The router ensures that
every module only gets its own messages.
## Transactions
A user can send a transaction to the running blockchain application. This
transaction can be of any of the ones that are supported by any of the
registered modules.
### CheckTx
Once a user has submitted their transaction to the engine,
the engine will first run `checkTx` to confirm that it is a valid transaction.
The module has to define a handler that knows how to handle every transaction
type. The corresponding handler gets invoked with the checkTx flag set to true.
This means that the handler shouldn't do any expensive operations, but it can
and should write to the checkTx state.
### DeliverTx
The engine calls `deliverTx` when a new block has been agreed upon in
consensus. Again, the corresponding module will have its handler invoked
and the state and context is passed in. During deliverTx execution the
transaction needs to be processed fully and the results are written to the
application state.
## CLI
The cosmos-sdk contains a number of helper libraries in `clients/` to build cli
and RPC interfaces for your specific application.

View File

@ -1,15 +0,0 @@
package server
import (
cfg "github.com/tendermint/tendermint/config"
"github.com/tendermint/tmlibs/log"
)
type Context struct {
Config *cfg.Config
Logger log.Logger
}
func NewContext(config *cfg.Config, logger log.Logger) *Context {
return &Context{config, logger}
}

View File

@ -8,10 +8,13 @@ import (
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/spf13/cobra"
"github.com/tendermint/go-crypto/keys"
"github.com/tendermint/go-crypto/keys/words"
cfg "github.com/tendermint/tendermint/config"
"github.com/tendermint/tendermint/p2p"
tmtypes "github.com/tendermint/tendermint/types"
cmn "github.com/tendermint/tmlibs/common"
dbm "github.com/tendermint/tmlibs/db"
)
// testnetInformation contains the info necessary
@ -25,6 +28,11 @@ type testnetInformation struct {
NodeID p2p.ID `json:"node_id"`
}
type initCmd struct {
genAppState GenAppState
context *Context
}
// InitCmd will initialize all files for tendermint,
// along with proper app_state.
// The application can pass in a function to generate
@ -43,35 +51,6 @@ func InitCmd(gen GenAppState, ctx *Context) *cobra.Command {
return &cobraCmd
}
// GenAppState takes the command line args, as well
// as an address and coin denomination.
// It returns a default app_state to be included in
// in the genesis file.
// This is application-specific
type GenAppState func(args []string, addr sdk.Address, coinDenom string) (json.RawMessage, error)
// DefaultGenAppState expects two args: an account address
// and a coin denomination, and gives lots of coins to that address.
func DefaultGenAppState(args []string, addr sdk.Address, coinDenom string) (json.RawMessage, error) {
opts := fmt.Sprintf(`{
"accounts": [{
"address": "%s",
"coins": [
{
"denom": "%s",
"amount": 9007199254740992
}
]
}]
}`, addr.String(), coinDenom)
return json.RawMessage(opts), nil
}
type initCmd struct {
genAppState GenAppState
context *Context
}
func (c initCmd) run(cmd *cobra.Command, args []string) error {
// Store testnet information as we go
var testnetInfo testnetInformation
@ -174,6 +153,34 @@ func (c initCmd) initTendermintFiles(config *cfg.Config, info *testnetInformatio
return nil
}
//-------------------------------------------------------------------
// GenAppState takes the command line args, as well
// as an address and coin denomination.
// It returns a default app_state to be included in
// in the genesis file.
// This is application-specific
type GenAppState func(args []string, addr sdk.Address, coinDenom string) (json.RawMessage, error)
// DefaultGenAppState expects two args: an account address
// and a coin denomination, and gives lots of coins to that address.
func DefaultGenAppState(args []string, addr sdk.Address, coinDenom string) (json.RawMessage, error) {
opts := fmt.Sprintf(`{
"accounts": [{
"address": "%s",
"coins": [
{
"denom": "%s",
"amount": 9007199254740992
}
]
}]
}`, addr.String(), coinDenom)
return json.RawMessage(opts), nil
}
//-------------------------------------------------------------------
// GenesisDoc involves some tendermint-specific structures we don't
// want to parse, so we just grab it into a raw object format,
// so we can add one line.
@ -199,3 +206,30 @@ func addGenesisState(filename string, appState json.RawMessage) error {
return ioutil.WriteFile(filename, out, 0600)
}
//-------------------------------------------------------------------
// GenerateCoinKey returns the address of a public key,
// along with the secret phrase to recover the private key.
// You can give coins to this address and return the recovery
// phrase to the user to access them.
func GenerateCoinKey() (sdk.Address, string, error) {
// construct an in-memory key store
codec, err := words.LoadCodec("english")
if err != nil {
return nil, "", err
}
keybase := keys.New(
dbm.NewMemDB(),
codec,
)
// generate a private key, with recovery phrase
info, secret, err := keybase.Create("name", "pass", keys.AlgoEd25519)
if err != nil {
return nil, "", err
}
addr := info.PubKey.Address()
return addr, secret, nil
}

View File

@ -1,34 +0,0 @@
package server
import (
"github.com/tendermint/go-crypto/keys"
"github.com/tendermint/go-crypto/keys/words"
dbm "github.com/tendermint/tmlibs/db"
sdk "github.com/cosmos/cosmos-sdk/types"
)
// GenerateCoinKey returns the address of a public key,
// along with the secret phrase to recover the private key.
// You can give coins to this address and return the recovery
// phrase to the user to access them.
func GenerateCoinKey() (sdk.Address, string, error) {
// construct an in-memory key store
codec, err := words.LoadCodec("english")
if err != nil {
return nil, "", err
}
keybase := keys.New(
dbm.NewMemDB(),
codec,
)
// generate a private key, with recovery phrase
info, secret, err := keybase.Create("name", "pass", keys.AlgoEd25519)
if err != nil {
return nil, "", err
}
addr := info.PubKey.Address()
return addr, secret, nil
}

View File

@ -1,27 +0,0 @@
package server
import (
"github.com/spf13/cobra"
tcmd "github.com/tendermint/tendermint/cmd/tendermint/commands"
)
// UnsafeResetAllCmd - extension of the tendermint command, resets initialization
func UnsafeResetAllCmd(ctx *Context) *cobra.Command {
cmd := resetAll{ctx}
return &cobra.Command{
Use: "unsafe_reset_all",
Short: "Reset all blockchain data",
RunE: cmd.run,
}
}
type resetAll struct {
context *Context
}
func (r resetAll) run(cmd *cobra.Command, args []string) error {
cfg := r.context.Config
tcmd.ResetAll(cfg.DBDir(), cfg.PrivValidatorFile(), r.context.Logger)
return nil
}

View File

@ -1,33 +0,0 @@
package server
import (
"fmt"
"github.com/spf13/cobra"
"github.com/tendermint/tendermint/p2p"
)
// ShowNodeIDCmd - ported from Tendermint, dump node ID to stdout
func ShowNodeIDCmd(ctx *Context) *cobra.Command {
cmd := showNodeId{ctx}
return &cobra.Command{
Use: "show_node_id",
Short: "Show this node's ID",
RunE: cmd.run,
}
}
type showNodeId struct {
context *Context
}
func (s showNodeId) run(cmd *cobra.Command, args []string) error {
cfg := s.context.Config
nodeKey, err := p2p.LoadOrGenNodeKey(cfg.NodeKeyFile())
if err != nil {
return err
}
fmt.Println(nodeKey.ID())
return nil
}

View File

@ -1,35 +0,0 @@
package server
import (
"fmt"
"github.com/spf13/cobra"
"github.com/tendermint/go-wire/data"
"github.com/tendermint/tendermint/types"
)
// ShowValidator - ported from Tendermint, show this node's validator info
func ShowValidatorCmd(ctx *Context) *cobra.Command {
cmd := showValidator{ctx}
return &cobra.Command{
Use: "show_validator",
Short: "Show this node's validator info",
RunE: cmd.run,
}
}
type showValidator struct {
context *Context
}
func (s showValidator) run(cmd *cobra.Command, args []string) error {
cfg := s.context.Config
privValidator := types.LoadOrGenPrivValidatorFS(cfg.PrivValidatorFile())
pubKeyJSONBytes, err := data.ToJSON(privValidator.PubKey)
if err != nil {
return err
}
fmt.Println(string(pubKeyJSONBytes))
return nil
}

85
server/tm_cmds.go Normal file
View File

@ -0,0 +1,85 @@
package server
import (
"fmt"
"github.com/spf13/cobra"
"github.com/tendermint/go-wire/data"
tcmd "github.com/tendermint/tendermint/cmd/tendermint/commands"
"github.com/tendermint/tendermint/p2p"
"github.com/tendermint/tendermint/types"
)
// ShowNodeIDCmd - ported from Tendermint, dump node ID to stdout
func ShowNodeIDCmd(ctx *Context) *cobra.Command {
cmd := showNodeId{ctx}
return &cobra.Command{
Use: "show_node_id",
Short: "Show this node's ID",
RunE: cmd.run,
}
}
type showNodeId struct {
context *Context
}
func (s showNodeId) run(cmd *cobra.Command, args []string) error {
cfg := s.context.Config
nodeKey, err := p2p.LoadOrGenNodeKey(cfg.NodeKeyFile())
if err != nil {
return err
}
fmt.Println(nodeKey.ID())
return nil
}
//--------------------------------------------------------------------------------
// ShowValidator - ported from Tendermint, show this node's validator info
func ShowValidatorCmd(ctx *Context) *cobra.Command {
cmd := showValidator{ctx}
return &cobra.Command{
Use: "show_validator",
Short: "Show this node's validator info",
RunE: cmd.run,
}
}
type showValidator struct {
context *Context
}
func (s showValidator) run(cmd *cobra.Command, args []string) error {
cfg := s.context.Config
privValidator := types.LoadOrGenPrivValidatorFS(cfg.PrivValidatorFile())
pubKeyJSONBytes, err := data.ToJSON(privValidator.PubKey)
if err != nil {
return err
}
fmt.Println(string(pubKeyJSONBytes))
return nil
}
//------------------------------------------------------------------------------
// UnsafeResetAllCmd - extension of the tendermint command, resets initialization
func UnsafeResetAllCmd(ctx *Context) *cobra.Command {
cmd := resetAll{ctx}
return &cobra.Command{
Use: "unsafe_reset_all",
Short: "Reset all blockchain data",
RunE: cmd.run,
}
}
type resetAll struct {
context *Context
}
func (r resetAll) run(cmd *cobra.Command, args []string) error {
cfg := r.context.Config
tcmd.ResetAll(cfg.DBDir(), cfg.PrivValidatorFile(), r.context.Logger)
return nil
}

View File

@ -14,6 +14,17 @@ import (
"github.com/tendermint/tmlibs/log"
)
type Context struct {
Config *cfg.Config
Logger log.Logger
}
func NewContext(config *cfg.Config, logger log.Logger) *Context {
return &Context{config, logger}
}
//--------------------------------------------------------------------
// PersistentPreRunEFn returns a PersistentPreRunE function for cobra
// that initailizes the passed in context with a properly configured
// logger and config objecy