basecoin init, default to in-proc, fix up guide

This commit is contained in:
Ethan Buchman 2017-03-13 17:23:05 -04:00
parent 6f83510d34
commit 44189d9055
10 changed files with 173 additions and 108 deletions

View File

@ -15,45 +15,25 @@ WARNING: Currently uses plain-text private keys for transactions and is otherwis
## Prerequisites
* Go to https://golang.org/doc/install to install Golang.
* You will also need to set the $GOPATH environment variable as per the instructions [here](https://golang.org/doc/code.html#GOPATH).
[Install and setup Golang](https://tendermint.com/docs/guides/install-go).
## Installation
On a good day, basecoin can be installed like a normal Go program:
```
go get -u github.com/tendermint/basecoin/cmd/basecoin
```
If that fails, or if another branch is required, you may have to compile from source.
You will first need to install the Golang package manager [`glide`](https://github.com/Masterminds/glide).
```
cd $GOPATH/src/github.com/tendermint/basecoin
git checkout develop # (until we release tendermint v0.9)
make get_vendor_deps
make install
```
This will create the `basecoin` binary in `$GOPATH/bin`.
See the [install guide](/docs/guide/install.md) for more details.
## Command Line Interface
The basecoin CLI can be used to start a stand-alone basecoin instance (`basecoin start`),
or to start basecoin with Tendermint in the same process (`basecoin start --in-proc`).
It can also be used to send transactions, eg. `basecoin tx send --to 0x4793A333846E5104C46DD9AB9A00E31821B2F301 --amount 100btc,10gold`
See `basecoin --help` and `basecoin [cmd] --help` for more details`.
## Learn more
## Guide
1. Getting started with the [Basecoin tool](/docs/guide/basecoin-basics.md)
1. Learn more about [Basecoin's design](/docs/guide/basecoin-design.md)
1. Extend Basecoin [using the plugin system](/docs/guide/example-plugin.md)
1. Learn more about [plugin design](/docs/guide/plugin-design.md)
1. See some [more example applications](/docs/guide/more-examples.md)
1. More features of the [Basecoin tool](/docs/guide/basecoin-tool.md)
1. Learn how to use [InterBlockchain Communication (IBC)](/docs/guide/ibc.md)
1. [Deploy testnets](deployment.md) running your basecoin application.

View File

@ -14,6 +14,7 @@ func main() {
app.Usage = "basecoin [command] [args...]"
app.Version = version.Version
app.Commands = []cli.Command{
commands.InitCmd,
commands.StartCmd,
commands.TxCmd,
commands.QueryCmd,

View File

@ -21,15 +21,9 @@ var (
// TODO: move to config file
// eyesCacheSizePtr := flag.Int("eyes-cache-size", 10000, "MerkleEyes db cache size, for embedded")
DirFlag = cli.StringFlag{
Name: "dir",
Value: ".",
Usage: "Root directory",
}
InProcTMFlag = cli.BoolFlag{
Name: "in-proc",
Usage: "Run Tendermint in-process with the App",
ABCIServerFlag = cli.BoolFlag{
Name: "abci-server",
Usage: "Run the Basecoin app and ABCI server, but not Tendermint (run Tendermint in another process)",
}
)

116
cmd/commands/init.go Normal file
View File

@ -0,0 +1,116 @@
package commands
import (
"io/ioutil"
"os"
"path"
"github.com/urfave/cli"
cmn "github.com/tendermint/go-common"
tmcfg "github.com/tendermint/tendermint/config/tendermint"
types "github.com/tendermint/tendermint/types"
)
var InitCmd = cli.Command{
Name: "init",
Usage: "Initialize a basecoin blockchain",
ArgsUsage: "",
Action: func(c *cli.Context) error {
return cmdInit(c)
},
Flags: []cli.Flag{
ChainIDFlag,
},
}
func cmdInit(c *cli.Context) error {
basecoinDir := BasecoinRoot("")
tmDir := path.Join(basecoinDir, "tendermint")
// initalize tendermint
tmConfig := tmcfg.GetConfig(tmDir)
privValFile := tmConfig.GetString("priv_validator_file")
if _, err := os.Stat(privValFile); os.IsNotExist(err) {
privValidator := types.GenPrivValidator()
privValidator.SetFile(privValFile)
privValidator.Save()
genFile := tmConfig.GetString("genesis_file")
if _, err := os.Stat(genFile); os.IsNotExist(err) {
genDoc := types.GenesisDoc{
ChainID: cmn.Fmt("test-chain-%v", cmn.RandStr(6)),
}
genDoc.Validators = []types.GenesisValidator{types.GenesisValidator{
PubKey: privValidator.PubKey,
Amount: 10,
}}
genDoc.SaveAs(genFile)
}
log.Notice("Initialized Tendermint", "genesis", tmConfig.GetString("genesis_file"), "priv_validator", tmConfig.GetString("priv_validator_file"))
} else {
log.Notice("Already initialized Tendermint", "priv_validator", tmConfig.GetString("priv_validator_file"))
}
// initalize basecoin
genesisFile := path.Join(basecoinDir, "genesis.json")
key1File := path.Join(basecoinDir, "key.json")
key2File := path.Join(basecoinDir, "key2.json")
if err := ioutil.WriteFile(genesisFile, []byte(genesisJSON), 0644); err != nil {
return err
}
if err := ioutil.WriteFile(key1File, []byte(key1JSON), 0400); err != nil {
return err
}
if err := ioutil.WriteFile(key2File, []byte(key2JSON), 0400); err != nil {
return err
}
log.Notice("Initialized Basecoin", "genesis", genesisFile, "key", key1File)
return nil
}
const genesisJSON = `[
"base/chainID", "test_chain_id",
"base/account", {
"pub_key": {
"type": "ed25519",
"data": "619D3678599971ED29C7529DDD4DA537B97129893598A17C82E3AC9A8BA95279"
},
"coins": [
{
"denom": "mycoin",
"amount": 9007199254740992
}
]
}
]`
const key1JSON = `{
"address": "1B1BE55F969F54064628A63B9559E7C21C925165",
"priv_key": [
1,
"C70D6934B4F55F1B7BC33B56B9CA8A2061384AFC19E91E44B40C4BBA182953D1619D3678599971ED29C7529DDD4DA537B97129893598A17C82E3AC9A8BA95279"
],
"pub_key": [
1,
"619D3678599971ED29C7529DDD4DA537B97129893598A17C82E3AC9A8BA95279"
]
}`
const key2JSON = `{
"address": "1DA7C74F9C219229FD54CC9F7386D5A3839F0090",
"priv_key": [
1,
"34BAE9E65CE8245FAD035A0E3EED9401BDE8785FFB3199ACCF8F5B5DDF7486A8352195DA90CB0B90C24295B90AEBA25A5A71BC61BAB2FE2387241D439698B7B8"
],
"pub_key": [
1,
"352195DA90CB0B90C24295B90AEBA25A5A71BC61BAB2FE2387241D439698B7B8"
]
}`

View File

@ -3,6 +3,7 @@ package commands
import (
"fmt"
"io/ioutil"
"path"
"github.com/urfave/cli"
@ -60,14 +61,15 @@ func genKey() *Key {
}
}
func LoadKey(filePath string) *Key {
func LoadKey(keyFile string) *Key {
filePath := path.Join(BasecoinRoot(""), keyFile)
keyJSONBytes, err := ioutil.ReadFile(filePath)
if err != nil {
cmn.Exit(err.Error())
}
key := wire.ReadJSON(&Key{}, keyJSONBytes, &err).(*Key)
if err != nil {
cmn.Exit(cmn.Fmt("Error reading PrivValidator from %v: %v\n", filePath, err))
cmn.Exit(cmn.Fmt("Error reading key from %v: %v\n", filePath, err))
}
return key
}

7
cmd/commands/log.go Normal file
View File

@ -0,0 +1,7 @@
package commands
import (
"github.com/tendermint/go-logger"
)
var log = logger.New("module", "commands")

View File

@ -10,8 +10,6 @@ import (
"github.com/tendermint/abci/server"
cmn "github.com/tendermint/go-common"
cfg "github.com/tendermint/go-config"
//logger "github.com/tendermint/go-logger"
eyes "github.com/tendermint/merkleeyes/client"
tmcfg "github.com/tendermint/tendermint/config/tendermint"
@ -23,8 +21,6 @@ import (
"github.com/tendermint/basecoin/types"
)
var config cfg.Config
const EyesCacheSize = 10000
var StartCmd = cli.Command{
@ -37,8 +33,7 @@ var StartCmd = cli.Command{
Flags: []cli.Flag{
AddrFlag,
EyesFlag,
DirFlag,
InProcTMFlag,
ABCIServerFlag,
ChainIDFlag,
},
}
@ -56,11 +51,12 @@ func RegisterStartPlugin(name string, newPlugin func() types.Plugin) {
}
func cmdStart(c *cli.Context) error {
basecoinDir := BasecoinRoot("")
// Connect to MerkleEyes
var eyesCli *eyes.Client
if c.String("eyes") == "local" {
eyesCli = eyes.NewLocalClient(path.Join(c.String("dir"), "merkleeyes.db"), EyesCacheSize)
eyesCli = eyes.NewLocalClient(path.Join(basecoinDir, "merkleeyes.db"), EyesCacheSize)
} else {
var err error
eyesCli, err = eyes.NewClient(c.String("eyes"))
@ -81,7 +77,7 @@ func cmdStart(c *cli.Context) error {
}
// If genesis file exists, set key-value options
genesisFile := path.Join(c.String("dir"), "genesis.json")
genesisFile := path.Join(basecoinDir, "genesis.json")
if _, err := os.Stat(genesisFile); err == nil {
err := basecoinApp.LoadGenesis(genesisFile)
if err != nil {
@ -91,12 +87,14 @@ func cmdStart(c *cli.Context) error {
fmt.Printf("No genesis file at %s, skipping...\n", genesisFile)
}
if c.Bool("in-proc") {
startTendermint(c, basecoinApp)
} else {
if c.Bool("abci-server") {
// run just the abci app/server
if err := startBasecoinABCI(c, basecoinApp); err != nil {
return err
}
} else {
// start the app with tendermint in-process
startTendermint(basecoinDir, basecoinApp)
}
return nil
@ -117,17 +115,18 @@ func startBasecoinABCI(c *cli.Context, basecoinApp *app.Basecoin) error {
}
func startTendermint(c *cli.Context, basecoinApp *app.Basecoin) {
func startTendermint(dir string, basecoinApp *app.Basecoin) {
// Get configuration
config = tmcfg.GetConfig("")
tmConfig := tmcfg.GetConfig(path.Join(dir, "tendermint"))
// logger.SetLogLevel("notice") //config.GetString("log_level"))
// parseFlags(config, args[1:]) // Command line overrides
// Create & start tendermint node
privValidatorFile := config.GetString("priv_validator_file")
privValidatorFile := tmConfig.GetString("priv_validator_file")
privValidator := tmtypes.LoadOrGenPrivValidator(privValidatorFile)
n := node.NewNode(config, privValidator, proxy.NewLocalClientCreator(basecoinApp))
n := node.NewNode(tmConfig, privValidator, proxy.NewLocalClientCreator(basecoinApp))
n.Start()

View File

@ -14,7 +14,6 @@ import (
client "github.com/tendermint/go-rpc/client"
"github.com/tendermint/go-wire"
ctypes "github.com/tendermint/tendermint/rpc/core/types"
tmtypes "github.com/tendermint/tendermint/types"
)
var TxFlags = []cli.Flag{
@ -144,7 +143,7 @@ func AppTx(c *cli.Context, name string, data []byte) error {
gas := int64(c.Int("gas"))
chainID := c.String("chain_id")
privKey := tmtypes.LoadPrivValidator(fromFile)
privKey := LoadKey(fromFile)
sequence, err := getSeq(c, privKey.Address)
if err != nil {

View File

@ -3,6 +3,7 @@ package commands
import (
"encoding/hex"
"errors"
"os"
"regexp"
"strconv"
"strings"
@ -20,6 +21,16 @@ import (
tmtypes "github.com/tendermint/tendermint/types"
)
func BasecoinRoot(rootDir string) string {
if rootDir == "" {
rootDir = os.Getenv("BASECOIN_ROOT")
}
if rootDir == "" {
rootDir = os.Getenv("HOME") + "/.basecoin"
}
return rootDir
}
// Returns true for non-empty hex-string prefixed with "0x"
func isHex(s string) bool {
if len(s) > 2 && s[:2] == "0x" {

View File

@ -5,77 +5,34 @@ and how to send transactions between accounts using the `basecoin` tool.
## Install
Make sure you have [basecoin installed](install.md).
You will also need to [install Tendermint](https://tendermint.com/intro/getting-started/download).
Installing basecoin is simple:
**Note** All code is on the 0.9 pre-release branch, you may have to
[install Tendermint from source](https://tendermint.com/docs/guides/install)
until 0.9 is released. (Make sure to add `git checkout develop` to the linked install instructions)
```
go get -u github.com/tendermint/basecoin/cmd/basecoin
```
If you have trouble, see the [installation guide](install.md).
## Initialization
Basecoin is an ABCI application that runs on Tendermint, so we first need to initialize Tendermint:
To initialize a new Basecoin blockchain, run:
```
tendermint init
basecoin init
```
This will create the necessary files for a single Tendermint node in `~/.tendermint`.
If you had previously run Tendermint, make sure you reset the chain
(note this will delete all chain data, so back it up if you need it):
```
tendermint unsafe_reset_all
```
Now we need some initialization files for basecoin.
We have included some defaults in the basecoin directory, under `data`.
For purposes of convenience, change to that directory:
```
cd $GOPATH/src/github.com/tendermint/basecoin/data
```
The directory contains a genesis file and two private keys.
You can generate your own private keys with `tendermint gen_validator`,
and construct the `genesis.json` as you like.
Note, however, that you must be careful with the `chain_id` field,
as every transaction must contain the correct `chain_id`
(default is `test_chain_id`).
This will create the necessary files for a Basecoin blockchain with one validator and one account in `~/.basecoin`.
For more options on setup, see the [guide to using the Basecoin tool](/docs/guide/basecoin-tool.md).
## Start
Now we can start basecoin:
```
basecoin start --in-proc
```
This will initialize the chain with the `genesis.json` file from the current directory.
If you want to specify another location, you can run:
```
basecoin start --in-proc --dir PATH/TO/CUSTOM/DATA
```
Note that `--in-proc` stands for "in process", which means
basecoin will be started with the Tendermint node running in the same process.
To start Tendermint in a separate process instead, use:
```
basecoin start
```
and in another window:
```
tendermint node
```
In either case, you should see blocks start streaming in!
Note, however, that currently basecoin currently requires the
`develop` branch of Tendermint for this to work.
You should see blocks start streaming in!
## Send transactions
@ -98,8 +55,7 @@ Let's send funds from the first account to the second:
basecoin tx send --to 0x1DA7C74F9C219229FD54CC9F7386D5A3839F0090 --amount 10mycoin
```
By default, the CLI looks for a `priv_validator.json` to sign the transaction with,
so this will only work if you are in the `$GOPATH/src/github.com/tendermint/basecoin/data`.
By default, the CLI looks for a `key.json` to sign the transaction with.
To specify a different key, we can use the `--from` flag.
Now if we check the second account, it should have `10` 'mycoin' coins!