Merge pull request #789 from cosmos/bucky/cmd-makefile
move gaia to cmd, update makefile, refactor server
This commit is contained in:
commit
15aa929f42
24
Makefile
24
Makefile
|
@ -13,13 +13,16 @@ ci: get_tools get_vendor_deps build test_cover
|
||||||
### Build
|
### Build
|
||||||
|
|
||||||
# This can be unified later, here for easy demos
|
# This can be unified later, here for easy demos
|
||||||
gaia:
|
|
||||||
go build $(BUILD_FLAGS) -o build/gaiad ./examples/gaia/gaiad
|
|
||||||
go build $(BUILD_FLAGS) -o build/gaiacli ./examples/gaia/gaiacli
|
|
||||||
|
|
||||||
build:
|
build:
|
||||||
@rm -rf $(shell pwd)/examples/basecoin/vendor/
|
ifeq ($(OS),Windows_NT)
|
||||||
@rm -rf $(shell pwd)/examples/democoin/vendor/
|
go build $(BUILD_FLAGS) -o build/gaiad.exe ./cmd/gaiad
|
||||||
|
go build $(BUILD_FLAGS) -o build/gaiacli.exe ./cmd/gaiacli
|
||||||
|
else
|
||||||
|
go build $(BUILD_FLAGS) -o build/gaiad ./cmd/gaiad
|
||||||
|
go build $(BUILD_FLAGS) -o build/gaiacli ./cmd/gaiacli
|
||||||
|
endif
|
||||||
|
|
||||||
|
build_examples:
|
||||||
ifeq ($(OS),Windows_NT)
|
ifeq ($(OS),Windows_NT)
|
||||||
go build $(BUILD_FLAGS) -o build/basecoind.exe ./examples/basecoin/cmd/basecoind
|
go build $(BUILD_FLAGS) -o build/basecoind.exe ./examples/basecoin/cmd/basecoind
|
||||||
go build $(BUILD_FLAGS) -o build/basecli.exe ./examples/basecoin/cmd/basecli
|
go build $(BUILD_FLAGS) -o build/basecli.exe ./examples/basecoin/cmd/basecli
|
||||||
|
@ -33,6 +36,10 @@ else
|
||||||
endif
|
endif
|
||||||
|
|
||||||
install:
|
install:
|
||||||
|
go install $(BUILD_FLAGS) ./cmd/gaiad
|
||||||
|
go install $(BUILD_FLAGS) ./cmd/gaiacli
|
||||||
|
|
||||||
|
install_examples:
|
||||||
go install $(BUILD_FLAGS) ./examples/basecoin/cmd/basecoind
|
go install $(BUILD_FLAGS) ./examples/basecoin/cmd/basecoind
|
||||||
go install $(BUILD_FLAGS) ./examples/basecoin/cmd/basecli
|
go install $(BUILD_FLAGS) ./examples/basecoin/cmd/basecli
|
||||||
go install $(BUILD_FLAGS) ./examples/democoin/cmd/democoind
|
go install $(BUILD_FLAGS) ./examples/democoin/cmd/democoind
|
||||||
|
@ -84,12 +91,9 @@ test: test_unit # test_cli
|
||||||
# go test -coverprofile=c.out && go tool cover -html=c.out
|
# go test -coverprofile=c.out && go tool cover -html=c.out
|
||||||
|
|
||||||
test_unit:
|
test_unit:
|
||||||
@rm -rf examples/basecoin/vendor/
|
|
||||||
@rm -rf examples/democoin/vendor/
|
|
||||||
@go test $(PACKAGES)
|
@go test $(PACKAGES)
|
||||||
|
|
||||||
test_cover:
|
test_cover:
|
||||||
@rm -rf examples/basecoin/vendor/
|
|
||||||
@bash tests/test_cover.sh
|
@bash tests/test_cover.sh
|
||||||
|
|
||||||
benchmark:
|
benchmark:
|
||||||
|
@ -123,4 +127,4 @@ devdoc_update:
|
||||||
# To avoid unintended conflicts with file names, always add to .PHONY
|
# To avoid unintended conflicts with file names, always add to .PHONY
|
||||||
# unless there is a reason not to.
|
# unless there is a reason not to.
|
||||||
# https://www.gnu.org/software/make/manual/html_node/Phony-Targets.html
|
# https://www.gnu.org/software/make/manual/html_node/Phony-Targets.html
|
||||||
.PHONY: build dist check_tools get_tools get_vendor_deps draw_deps test test_unit test_tutorial benchmark devdoc_init devdoc devdoc_save devdoc_update
|
.PHONY: build build_examples install install_examples dist check_tools get_tools get_vendor_deps draw_deps test test_unit test_tutorial benchmark devdoc_init devdoc devdoc_save devdoc_update
|
||||||
|
|
|
@ -17,9 +17,9 @@ const (
|
||||||
flagFee = "fee"
|
flagFee = "fee"
|
||||||
)
|
)
|
||||||
|
|
||||||
// gaiacliCmd is the entry point for this binary
|
// rootCmd is the entry point for this binary
|
||||||
var (
|
var (
|
||||||
gaiacliCmd = &cobra.Command{
|
rootCmd = &cobra.Command{
|
||||||
Use: "gaiacli",
|
Use: "gaiacli",
|
||||||
Short: "Gaia light-client",
|
Short: "Gaia light-client",
|
||||||
}
|
}
|
||||||
|
@ -54,16 +54,16 @@ func main() {
|
||||||
cobra.EnableCommandSorting = false
|
cobra.EnableCommandSorting = false
|
||||||
|
|
||||||
// generic client commands
|
// generic client commands
|
||||||
AddClientCommands(gaiacliCmd)
|
AddClientCommands(rootCmd)
|
||||||
// query commands (custom to binary)
|
// query commands (custom to binary)
|
||||||
gaiacliCmd.AddCommand(
|
rootCmd.AddCommand(
|
||||||
GetCommands(getAccountCmd)...)
|
GetCommands(getAccountCmd)...)
|
||||||
// post tx commands (custom to binary)
|
// post tx commands (custom to binary)
|
||||||
gaiacliCmd.AddCommand(
|
rootCmd.AddCommand(
|
||||||
PostCommands(postSendCommand())...)
|
PostCommands(postSendCommand())...)
|
||||||
|
|
||||||
// add proxy, version and key info
|
// add proxy, version and key info
|
||||||
gaiacliCmd.AddCommand(
|
rootCmd.AddCommand(
|
||||||
lineBreak,
|
lineBreak,
|
||||||
serveCommand(),
|
serveCommand(),
|
||||||
KeyCommands(),
|
KeyCommands(),
|
||||||
|
@ -72,6 +72,6 @@ func main() {
|
||||||
)
|
)
|
||||||
|
|
||||||
// prepare and add flags
|
// prepare and add flags
|
||||||
executor := cli.PrepareBaseCmd(gaiacliCmd, "GA", os.ExpandEnv("$HOME/.gaiacli"))
|
executor := cli.PrepareBaseCmd(rootCmd, "GA", os.ExpandEnv("$HOME/.gaiacli"))
|
||||||
executor.Execute()
|
executor.Execute()
|
||||||
}
|
}
|
|
@ -0,0 +1,63 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
|
abci "github.com/tendermint/abci/types"
|
||||||
|
"github.com/tendermint/tmlibs/cli"
|
||||||
|
dbm "github.com/tendermint/tmlibs/db"
|
||||||
|
"github.com/tendermint/tmlibs/log"
|
||||||
|
|
||||||
|
"github.com/cosmos/cosmos-sdk/examples/basecoin/app"
|
||||||
|
"github.com/cosmos/cosmos-sdk/server"
|
||||||
|
)
|
||||||
|
|
||||||
|
// rootCmd is the entry point for this binary
|
||||||
|
var (
|
||||||
|
context = server.NewContext(nil, nil)
|
||||||
|
rootCmd = &cobra.Command{
|
||||||
|
Use: "gaiad",
|
||||||
|
Short: "Gaia Daemon (server)",
|
||||||
|
PersistentPreRunE: server.PersistentPreRunEFn(context),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
// TODO: distinguish from basecoin
|
||||||
|
func generateApp(rootDir string, logger log.Logger) (abci.Application, error) {
|
||||||
|
dataDir := filepath.Join(rootDir, "data")
|
||||||
|
dbMain, err := dbm.NewGoLevelDB("gaia", dataDir)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
dbAcc, err := dbm.NewGoLevelDB("gaia-acc", dataDir)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
dbIBC, err := dbm.NewGoLevelDB("gaia-ibc", dataDir)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
dbStaking, err := dbm.NewGoLevelDB("gaia-staking", dataDir)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
dbs := map[string]dbm.DB{
|
||||||
|
"main": dbMain,
|
||||||
|
"acc": dbAcc,
|
||||||
|
"ibc": dbIBC,
|
||||||
|
"staking": dbStaking,
|
||||||
|
}
|
||||||
|
bapp := app.NewBasecoinApp(logger, dbs)
|
||||||
|
return bapp, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
server.AddCommands(rootCmd, server.DefaultGenAppState, generateApp, context)
|
||||||
|
|
||||||
|
// prepare and add flags
|
||||||
|
executor := cli.PrepareBaseCmd(rootCmd, "GA", os.ExpandEnv("$HOME/.gaiad"))
|
||||||
|
executor.Execute()
|
||||||
|
}
|
|
@ -1,204 +0,0 @@
|
||||||
Cosmos-SDK Basecoin (template)
|
|
||||||
License: Apache2.0
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
APPENDIX: How to apply the Apache License to your work.
|
|
||||||
|
|
||||||
To apply the Apache License to your work, attach the following
|
|
||||||
boilerplate notice, with the fields enclosed by brackets "{}"
|
|
||||||
replaced with your own identifying information. (Don't include
|
|
||||||
the brackets!) The text should be enclosed in the appropriate
|
|
||||||
comment syntax for the file format. We also recommend that a
|
|
||||||
file or class name and description of purpose be included on the
|
|
||||||
same "printed page" as the copyright notice for easier
|
|
||||||
identification within third-party archives.
|
|
||||||
|
|
||||||
Copyright 2018 All in Bits, Inc
|
|
||||||
|
|
||||||
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.
|
|
|
@ -1,22 +0,0 @@
|
||||||
PACKAGES=$(shell go list ./... | grep -v '/vendor/')
|
|
||||||
BUILD_FLAGS = -ldflags "-X github.com/cosmos/cosmos-sdk/examples/basecoin/version.GitCommit=`git rev-parse --short HEAD`"
|
|
||||||
|
|
||||||
all: get_tools get_vendor_deps build test
|
|
||||||
|
|
||||||
get_tools:
|
|
||||||
go get github.com/golang/dep/cmd/dep
|
|
||||||
|
|
||||||
build:
|
|
||||||
go build $(BUILD_FLAGS) -o build/basecoin ./cmd/...
|
|
||||||
|
|
||||||
get_vendor_deps:
|
|
||||||
@rm -rf vendor/
|
|
||||||
@dep ensure
|
|
||||||
|
|
||||||
test:
|
|
||||||
@go test $(PACKAGES)
|
|
||||||
|
|
||||||
benchmark:
|
|
||||||
@go test -bench=. $(PACKAGES)
|
|
||||||
|
|
||||||
.PHONY: all build test benchmark
|
|
|
@ -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.
|
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
@ -24,18 +23,14 @@ import (
|
||||||
"github.com/cosmos/cosmos-sdk/examples/basecoin/types"
|
"github.com/cosmos/cosmos-sdk/examples/basecoin/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
// gaiacliCmd is the entry point for this binary
|
// rootCmd is the entry point for this binary
|
||||||
var (
|
var (
|
||||||
basecliCmd = &cobra.Command{
|
rootCmd = &cobra.Command{
|
||||||
Use: "basecli",
|
Use: "basecli",
|
||||||
Short: "Basecoin light-client",
|
Short: "Basecoin light-client",
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
func todoNotImplemented(_ *cobra.Command, _ []string) error {
|
|
||||||
return errors.New("TODO: Command not yet implemented")
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
// disable sorting
|
// disable sorting
|
||||||
cobra.EnableCommandSorting = false
|
cobra.EnableCommandSorting = false
|
||||||
|
@ -48,36 +43,36 @@ func main() {
|
||||||
// with the cdc
|
// with the cdc
|
||||||
|
|
||||||
// add standard rpc, and tx commands
|
// add standard rpc, and tx commands
|
||||||
rpc.AddCommands(basecliCmd)
|
rpc.AddCommands(rootCmd)
|
||||||
basecliCmd.AddCommand(client.LineBreak)
|
rootCmd.AddCommand(client.LineBreak)
|
||||||
tx.AddCommands(basecliCmd, cdc)
|
tx.AddCommands(rootCmd, cdc)
|
||||||
basecliCmd.AddCommand(client.LineBreak)
|
rootCmd.AddCommand(client.LineBreak)
|
||||||
|
|
||||||
// add query/post commands (custom to binary)
|
// add query/post commands (custom to binary)
|
||||||
basecliCmd.AddCommand(
|
rootCmd.AddCommand(
|
||||||
client.GetCommands(
|
client.GetCommands(
|
||||||
authcmd.GetAccountCmd("main", cdc, types.GetAccountDecoder(cdc)),
|
authcmd.GetAccountCmd("main", cdc, types.GetAccountDecoder(cdc)),
|
||||||
)...)
|
)...)
|
||||||
basecliCmd.AddCommand(
|
rootCmd.AddCommand(
|
||||||
client.PostCommands(
|
client.PostCommands(
|
||||||
bankcmd.SendTxCmd(cdc),
|
bankcmd.SendTxCmd(cdc),
|
||||||
)...)
|
)...)
|
||||||
basecliCmd.AddCommand(
|
rootCmd.AddCommand(
|
||||||
client.PostCommands(
|
client.PostCommands(
|
||||||
ibccmd.IBCTransferCmd(cdc),
|
ibccmd.IBCTransferCmd(cdc),
|
||||||
)...)
|
)...)
|
||||||
basecliCmd.AddCommand(
|
rootCmd.AddCommand(
|
||||||
client.PostCommands(
|
client.PostCommands(
|
||||||
ibccmd.IBCRelayCmd(cdc),
|
ibccmd.IBCRelayCmd(cdc),
|
||||||
simplestakingcmd.BondTxCmd(cdc),
|
simplestakingcmd.BondTxCmd(cdc),
|
||||||
)...)
|
)...)
|
||||||
basecliCmd.AddCommand(
|
rootCmd.AddCommand(
|
||||||
client.PostCommands(
|
client.PostCommands(
|
||||||
simplestakingcmd.UnbondTxCmd(cdc),
|
simplestakingcmd.UnbondTxCmd(cdc),
|
||||||
)...)
|
)...)
|
||||||
|
|
||||||
// add proxy, version and key info
|
// add proxy, version and key info
|
||||||
basecliCmd.AddCommand(
|
rootCmd.AddCommand(
|
||||||
client.LineBreak,
|
client.LineBreak,
|
||||||
lcd.ServeCommand(cdc),
|
lcd.ServeCommand(cdc),
|
||||||
keys.Commands(),
|
keys.Commands(),
|
||||||
|
@ -86,6 +81,6 @@ func main() {
|
||||||
)
|
)
|
||||||
|
|
||||||
// prepare and add flags
|
// prepare and add flags
|
||||||
executor := cli.PrepareMainCmd(basecliCmd, "BC", os.ExpandEnv("$HOME/.basecli"))
|
executor := cli.PrepareMainCmd(rootCmd, "BC", os.ExpandEnv("$HOME/.basecli"))
|
||||||
executor.Execute()
|
executor.Execute()
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,93 +1,45 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"github.com/spf13/viper"
|
|
||||||
|
|
||||||
abci "github.com/tendermint/abci/types"
|
abci "github.com/tendermint/abci/types"
|
||||||
tcmd "github.com/tendermint/tendermint/cmd/tendermint/commands"
|
|
||||||
cfg "github.com/tendermint/tendermint/config"
|
|
||||||
"github.com/tendermint/tmlibs/cli"
|
"github.com/tendermint/tmlibs/cli"
|
||||||
tmflags "github.com/tendermint/tmlibs/cli/flags"
|
|
||||||
cmn "github.com/tendermint/tmlibs/common"
|
|
||||||
dbm "github.com/tendermint/tmlibs/db"
|
dbm "github.com/tendermint/tmlibs/db"
|
||||||
"github.com/tendermint/tmlibs/log"
|
"github.com/tendermint/tmlibs/log"
|
||||||
|
|
||||||
"github.com/cosmos/cosmos-sdk/examples/basecoin/app"
|
"github.com/cosmos/cosmos-sdk/examples/basecoin/app"
|
||||||
"github.com/cosmos/cosmos-sdk/server"
|
"github.com/cosmos/cosmos-sdk/server"
|
||||||
"github.com/cosmos/cosmos-sdk/version"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// basecoindCmd is the entry point for this binary
|
// basecoindCmd is the entry point for this binary
|
||||||
var (
|
var (
|
||||||
context = server.NewContext(nil, nil)
|
context = server.NewContext(nil, nil)
|
||||||
basecoindCmd = &cobra.Command{
|
rootCmd = &cobra.Command{
|
||||||
Use: "gaiad",
|
Use: "basecoind",
|
||||||
Short: "Gaia Daemon (server)",
|
Short: "Basecoin Daemon (server)",
|
||||||
PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
|
PersistentPreRunE: server.PersistentPreRunEFn(context),
|
||||||
if cmd.Name() == version.VersionCmd.Name() {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
config, err := tcmd.ParseConfig()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout))
|
|
||||||
logger, err = tmflags.ParseLogLevel(config.LogLevel, logger, cfg.DefaultLogLevel())
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if viper.GetBool(cli.TraceFlag) {
|
|
||||||
logger = log.NewTracingLogger(logger)
|
|
||||||
}
|
|
||||||
logger = logger.With("module", "main")
|
|
||||||
context.Config = config
|
|
||||||
context.Logger = logger
|
|
||||||
return nil
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
// defaultOptions sets up the app_options for the
|
|
||||||
// default genesis file
|
|
||||||
func defaultOptions(args []string) (json.RawMessage, string, cmn.HexBytes, error) {
|
|
||||||
addr, secret, err := server.GenerateCoinKey()
|
|
||||||
if err != nil {
|
|
||||||
return nil, "", nil, err
|
|
||||||
}
|
|
||||||
opts := fmt.Sprintf(`{
|
|
||||||
"accounts": [{
|
|
||||||
"address": "%s",
|
|
||||||
"coins": [
|
|
||||||
{
|
|
||||||
"denom": "mycoin",
|
|
||||||
"amount": 9007199254740992
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}]
|
|
||||||
}`, addr)
|
|
||||||
return json.RawMessage(opts), secret, addr, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func generateApp(rootDir string, logger log.Logger) (abci.Application, error) {
|
func generateApp(rootDir string, logger log.Logger) (abci.Application, error) {
|
||||||
dbMain, err := dbm.NewGoLevelDB("basecoin", filepath.Join(rootDir, "data"))
|
dataDir := filepath.Join(rootDir, "data")
|
||||||
|
dbMain, err := dbm.NewGoLevelDB("basecoin", dataDir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
dbAcc, err := dbm.NewGoLevelDB("basecoin-acc", filepath.Join(rootDir, "data"))
|
dbAcc, err := dbm.NewGoLevelDB("basecoin-acc", dataDir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
dbIBC, err := dbm.NewGoLevelDB("basecoin-ibc", filepath.Join(rootDir, "data"))
|
dbIBC, err := dbm.NewGoLevelDB("basecoin-ibc", dataDir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
dbStaking, err := dbm.NewGoLevelDB("basecoin-staking", filepath.Join(rootDir, "data"))
|
dbStaking, err := dbm.NewGoLevelDB("basecoin-staking", dataDir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -102,17 +54,10 @@ func generateApp(rootDir string, logger log.Logger) (abci.Application, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
basecoindCmd.AddCommand(
|
server.AddCommands(rootCmd, server.DefaultGenAppState, generateApp, context)
|
||||||
server.InitCmd(defaultOptions, context),
|
|
||||||
server.StartCmd(generateApp, context),
|
|
||||||
server.UnsafeResetAllCmd(context),
|
|
||||||
server.ShowNodeIdCmd(context),
|
|
||||||
server.ShowValidatorCmd(context),
|
|
||||||
version.VersionCmd,
|
|
||||||
)
|
|
||||||
|
|
||||||
// prepare and add flags
|
// prepare and add flags
|
||||||
rootDir := os.ExpandEnv("$HOME/.basecoind")
|
rootDir := os.ExpandEnv("$HOME/.basecoind")
|
||||||
executor := cli.PrepareBaseCmd(basecoindCmd, "BC", rootDir)
|
executor := cli.PrepareBaseCmd(rootCmd, "BC", rootDir)
|
||||||
executor.Execute()
|
executor.Execute()
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,204 +0,0 @@
|
||||||
Cosmos-SDK Democoin (template)
|
|
||||||
License: Apache2.0
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
APPENDIX: How to apply the Apache License to your work.
|
|
||||||
|
|
||||||
To apply the Apache License to your work, attach the following
|
|
||||||
boilerplate notice, with the fields enclosed by brackets "{}"
|
|
||||||
replaced with your own identifying information. (Don't include
|
|
||||||
the brackets!) The text should be enclosed in the appropriate
|
|
||||||
comment syntax for the file format. We also recommend that a
|
|
||||||
file or class name and description of purpose be included on the
|
|
||||||
same "printed page" as the copyright notice for easier
|
|
||||||
identification within third-party archives.
|
|
||||||
|
|
||||||
Copyright 2018 All in Bits, Inc
|
|
||||||
|
|
||||||
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.
|
|
|
@ -1,22 +0,0 @@
|
||||||
PACKAGES=$(shell go list ./... | grep -v '/vendor/')
|
|
||||||
BUILD_FLAGS = -ldflags "-X github.com/cosmos/cosmos-sdk/examples/democoin/version.GitCommit=`git rev-parse --short HEAD`"
|
|
||||||
|
|
||||||
all: get_tools get_vendor_deps build test
|
|
||||||
|
|
||||||
get_tools:
|
|
||||||
go get github.com/golang/dep/cmd/dep
|
|
||||||
|
|
||||||
build:
|
|
||||||
go build $(BUILD_FLAGS) -o build/democoin ./cmd/...
|
|
||||||
|
|
||||||
get_vendor_deps:
|
|
||||||
@rm -rf vendor/
|
|
||||||
@dep ensure
|
|
||||||
|
|
||||||
test:
|
|
||||||
@go test $(PACKAGES)
|
|
||||||
|
|
||||||
benchmark:
|
|
||||||
@go test -bench=. $(PACKAGES)
|
|
||||||
|
|
||||||
.PHONY: all build test benchmark
|
|
|
@ -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.
|
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
@ -24,18 +23,14 @@ import (
|
||||||
"github.com/cosmos/cosmos-sdk/examples/democoin/types"
|
"github.com/cosmos/cosmos-sdk/examples/democoin/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
// gaiacliCmd is the entry point for this binary
|
// rootCmd is the entry point for this binary
|
||||||
var (
|
var (
|
||||||
democliCmd = &cobra.Command{
|
rootCmd = &cobra.Command{
|
||||||
Use: "democli",
|
Use: "democli",
|
||||||
Short: "Democoin light-client",
|
Short: "Democoin light-client",
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
func todoNotImplemented(_ *cobra.Command, _ []string) error {
|
|
||||||
return errors.New("TODO: Command not yet implemented")
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
// disable sorting
|
// disable sorting
|
||||||
cobra.EnableCommandSorting = false
|
cobra.EnableCommandSorting = false
|
||||||
|
@ -48,36 +43,36 @@ func main() {
|
||||||
// with the cdc
|
// with the cdc
|
||||||
|
|
||||||
// add standard rpc, and tx commands
|
// add standard rpc, and tx commands
|
||||||
rpc.AddCommands(democliCmd)
|
rpc.AddCommands(rootCmd)
|
||||||
democliCmd.AddCommand(client.LineBreak)
|
rootCmd.AddCommand(client.LineBreak)
|
||||||
tx.AddCommands(democliCmd, cdc)
|
tx.AddCommands(rootCmd, cdc)
|
||||||
democliCmd.AddCommand(client.LineBreak)
|
rootCmd.AddCommand(client.LineBreak)
|
||||||
|
|
||||||
// add query/post commands (custom to binary)
|
// add query/post commands (custom to binary)
|
||||||
democliCmd.AddCommand(
|
rootCmd.AddCommand(
|
||||||
client.GetCommands(
|
client.GetCommands(
|
||||||
authcmd.GetAccountCmd("main", cdc, types.GetAccountDecoder(cdc)),
|
authcmd.GetAccountCmd("main", cdc, types.GetAccountDecoder(cdc)),
|
||||||
)...)
|
)...)
|
||||||
democliCmd.AddCommand(
|
rootCmd.AddCommand(
|
||||||
client.PostCommands(
|
client.PostCommands(
|
||||||
bankcmd.SendTxCmd(cdc),
|
bankcmd.SendTxCmd(cdc),
|
||||||
)...)
|
)...)
|
||||||
democliCmd.AddCommand(
|
rootCmd.AddCommand(
|
||||||
client.PostCommands(
|
client.PostCommands(
|
||||||
ibccmd.IBCTransferCmd(cdc),
|
ibccmd.IBCTransferCmd(cdc),
|
||||||
)...)
|
)...)
|
||||||
democliCmd.AddCommand(
|
rootCmd.AddCommand(
|
||||||
client.PostCommands(
|
client.PostCommands(
|
||||||
ibccmd.IBCRelayCmd(cdc),
|
ibccmd.IBCRelayCmd(cdc),
|
||||||
simplestakingcmd.BondTxCmd(cdc),
|
simplestakingcmd.BondTxCmd(cdc),
|
||||||
)...)
|
)...)
|
||||||
democliCmd.AddCommand(
|
rootCmd.AddCommand(
|
||||||
client.PostCommands(
|
client.PostCommands(
|
||||||
simplestakingcmd.UnbondTxCmd(cdc),
|
simplestakingcmd.UnbondTxCmd(cdc),
|
||||||
)...)
|
)...)
|
||||||
|
|
||||||
// add proxy, version and key info
|
// add proxy, version and key info
|
||||||
democliCmd.AddCommand(
|
rootCmd.AddCommand(
|
||||||
client.LineBreak,
|
client.LineBreak,
|
||||||
lcd.ServeCommand(cdc),
|
lcd.ServeCommand(cdc),
|
||||||
keys.Commands(),
|
keys.Commands(),
|
||||||
|
@ -86,6 +81,6 @@ func main() {
|
||||||
)
|
)
|
||||||
|
|
||||||
// prepare and add flags
|
// prepare and add flags
|
||||||
executor := cli.PrepareMainCmd(democliCmd, "BC", os.ExpandEnv("$HOME/.democli"))
|
executor := cli.PrepareMainCmd(rootCmd, "BC", os.ExpandEnv("$HOME/.democli"))
|
||||||
executor.Execute()
|
executor.Execute()
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,82 +2,48 @@ package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"github.com/spf13/viper"
|
|
||||||
|
|
||||||
abci "github.com/tendermint/abci/types"
|
abci "github.com/tendermint/abci/types"
|
||||||
tcmd "github.com/tendermint/tendermint/cmd/tendermint/commands"
|
|
||||||
cfg "github.com/tendermint/tendermint/config"
|
|
||||||
"github.com/tendermint/tmlibs/cli"
|
"github.com/tendermint/tmlibs/cli"
|
||||||
tmflags "github.com/tendermint/tmlibs/cli/flags"
|
|
||||||
cmn "github.com/tendermint/tmlibs/common"
|
|
||||||
dbm "github.com/tendermint/tmlibs/db"
|
dbm "github.com/tendermint/tmlibs/db"
|
||||||
"github.com/tendermint/tmlibs/log"
|
"github.com/tendermint/tmlibs/log"
|
||||||
|
|
||||||
"github.com/cosmos/cosmos-sdk/examples/democoin/app"
|
"github.com/cosmos/cosmos-sdk/examples/democoin/app"
|
||||||
"github.com/cosmos/cosmos-sdk/server"
|
"github.com/cosmos/cosmos-sdk/server"
|
||||||
"github.com/cosmos/cosmos-sdk/version"
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
// democoindCmd is the entry point for this binary
|
// democoindCmd is the entry point for this binary
|
||||||
var (
|
var (
|
||||||
context = server.NewContext(nil, nil)
|
context = server.NewContext(nil, nil)
|
||||||
democoindCmd = &cobra.Command{
|
rootCmd = &cobra.Command{
|
||||||
Use: "democoind",
|
Use: "democoind",
|
||||||
Short: "Gaia Daemon (server)",
|
Short: "Democoin Daemon (server)",
|
||||||
PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
|
PersistentPreRunE: server.PersistentPreRunEFn(context),
|
||||||
if cmd.Name() == version.VersionCmd.Name() {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
config, err := tcmd.ParseConfig()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout))
|
|
||||||
logger, err = tmflags.ParseLogLevel(config.LogLevel, logger, cfg.DefaultLogLevel())
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if viper.GetBool(cli.TraceFlag) {
|
|
||||||
logger = log.NewTracingLogger(logger)
|
|
||||||
}
|
|
||||||
logger = logger.With("module", "main")
|
|
||||||
context.Config = config
|
|
||||||
context.Logger = logger
|
|
||||||
return nil
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
// defaultOptions sets up the app_options for the
|
// defaultAppState sets up the app_state for the
|
||||||
// default genesis file
|
// default genesis file
|
||||||
func defaultOptions(args []string) (json.RawMessage, string, cmn.HexBytes, error) {
|
func defaultAppState(args []string, addr sdk.Address, coinDenom string) (json.RawMessage, error) {
|
||||||
addr, secret, err := server.GenerateCoinKey()
|
baseJSON, err := server.DefaultGenAppState(args, addr, coinDenom)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, "", nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
fmt.Println("Secret phrase to access coins:")
|
var jsonMap map[string]json.RawMessage
|
||||||
fmt.Println(secret)
|
err = json.Unmarshal(baseJSON, &jsonMap)
|
||||||
|
if err != nil {
|
||||||
opts := fmt.Sprintf(`{
|
return nil, err
|
||||||
"accounts": [{
|
}
|
||||||
"address": "%s",
|
jsonMap["cool"] = json.RawMessage(`{
|
||||||
"coins": [
|
|
||||||
{
|
|
||||||
"denom": "mycoin",
|
|
||||||
"amount": 9007199254740992
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}],
|
|
||||||
"cool": {
|
|
||||||
"trend": "ice-cold"
|
"trend": "ice-cold"
|
||||||
}
|
}`)
|
||||||
}`, addr)
|
bz, err := json.Marshal(jsonMap)
|
||||||
return json.RawMessage(opts), "", nil, nil
|
return json.RawMessage(bz), err
|
||||||
}
|
}
|
||||||
|
|
||||||
func generateApp(rootDir string, logger log.Logger) (abci.Application, error) {
|
func generateApp(rootDir string, logger log.Logger) (abci.Application, error) {
|
||||||
|
@ -108,17 +74,10 @@ func generateApp(rootDir string, logger log.Logger) (abci.Application, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
democoindCmd.AddCommand(
|
server.AddCommands(rootCmd, defaultAppState, generateApp, context)
|
||||||
server.InitCmd(defaultOptions, context),
|
|
||||||
server.StartCmd(generateApp, context),
|
|
||||||
server.UnsafeResetAllCmd(context),
|
|
||||||
server.ShowNodeIdCmd(context),
|
|
||||||
server.ShowValidatorCmd(context),
|
|
||||||
version.VersionCmd,
|
|
||||||
)
|
|
||||||
|
|
||||||
// prepare and add flags
|
// prepare and add flags
|
||||||
rootDir := os.ExpandEnv("$HOME/.democoind")
|
rootDir := os.ExpandEnv("$HOME/.democoind")
|
||||||
executor := cli.PrepareBaseCmd(democoindCmd, "BC", rootDir)
|
executor := cli.PrepareBaseCmd(rootCmd, "BC", rootDir)
|
||||||
executor.Execute()
|
executor.Execute()
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +0,0 @@
|
||||||
Gaiad is the abci application, which can be run stand-alone, or in-process with tendermint.
|
|
||||||
|
|
||||||
Gaiacli is a client application, which connects to tendermint rpc, and sends transactions and queries the state. It uses light-client proofs to guarantee the results even if it doesn't have 100% trust in the node it connects to.
|
|
|
@ -1,95 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"os"
|
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
|
||||||
"github.com/spf13/viper"
|
|
||||||
|
|
||||||
abci "github.com/tendermint/abci/types"
|
|
||||||
tcmd "github.com/tendermint/tendermint/cmd/tendermint/commands"
|
|
||||||
cfg "github.com/tendermint/tendermint/config"
|
|
||||||
"github.com/tendermint/tmlibs/cli"
|
|
||||||
tmflags "github.com/tendermint/tmlibs/cli/flags"
|
|
||||||
cmn "github.com/tendermint/tmlibs/common"
|
|
||||||
"github.com/tendermint/tmlibs/log"
|
|
||||||
|
|
||||||
"github.com/cosmos/cosmos-sdk/baseapp"
|
|
||||||
"github.com/cosmos/cosmos-sdk/server"
|
|
||||||
"github.com/cosmos/cosmos-sdk/version"
|
|
||||||
)
|
|
||||||
|
|
||||||
// gaiadCmd is the entry point for this binary
|
|
||||||
var (
|
|
||||||
context = server.NewContext(nil, nil)
|
|
||||||
gaiadCmd = &cobra.Command{
|
|
||||||
Use: "gaiad",
|
|
||||||
Short: "Gaia Daemon (server)",
|
|
||||||
PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
|
|
||||||
if cmd.Name() == version.VersionCmd.Name() {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
config, err := tcmd.ParseConfig()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout))
|
|
||||||
logger, err = tmflags.ParseLogLevel(config.LogLevel, logger, cfg.DefaultLogLevel())
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if viper.GetBool(cli.TraceFlag) {
|
|
||||||
logger = log.NewTracingLogger(logger)
|
|
||||||
}
|
|
||||||
logger = logger.With("module", "main")
|
|
||||||
context.Config = config
|
|
||||||
context.Logger = logger
|
|
||||||
return nil
|
|
||||||
},
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
// defaultOptions sets up the app_options for the
|
|
||||||
// default genesis file
|
|
||||||
func defaultOptions(args []string) (json.RawMessage, string, cmn.HexBytes, error) {
|
|
||||||
addr, secret, err := server.GenerateCoinKey()
|
|
||||||
if err != nil {
|
|
||||||
return nil, "", nil, err
|
|
||||||
}
|
|
||||||
fmt.Println("Secret phrase to access coins:")
|
|
||||||
fmt.Println(secret)
|
|
||||||
|
|
||||||
opts := fmt.Sprintf(`{
|
|
||||||
"accounts": [{
|
|
||||||
"address": "%s",
|
|
||||||
"coins": [
|
|
||||||
{
|
|
||||||
"denom": "mycoin",
|
|
||||||
"amount": 9007199254740992
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}]
|
|
||||||
}`, addr)
|
|
||||||
return json.RawMessage(opts), secret, addr, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func generateApp(rootDir string, logger log.Logger) (abci.Application, error) {
|
|
||||||
// TODO: set this to something real
|
|
||||||
app := new(baseapp.BaseApp)
|
|
||||||
return app, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
gaiadCmd.AddCommand(
|
|
||||||
server.InitCmd(defaultOptions, context),
|
|
||||||
server.StartCmd(generateApp, context),
|
|
||||||
server.UnsafeResetAllCmd(context),
|
|
||||||
version.VersionCmd,
|
|
||||||
)
|
|
||||||
|
|
||||||
// prepare and add flags
|
|
||||||
executor := cli.PrepareBaseCmd(gaiadCmd, "GA", os.ExpandEnv("$HOME/.gaiad"))
|
|
||||||
executor.Execute()
|
|
||||||
}
|
|
|
@ -6,7 +6,6 @@ import (
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
abci "github.com/tendermint/abci/types"
|
abci "github.com/tendermint/abci/types"
|
||||||
cmn "github.com/tendermint/tmlibs/common"
|
|
||||||
dbm "github.com/tendermint/tmlibs/db"
|
dbm "github.com/tendermint/tmlibs/db"
|
||||||
"github.com/tendermint/tmlibs/log"
|
"github.com/tendermint/tmlibs/log"
|
||||||
|
|
||||||
|
@ -107,7 +106,7 @@ func InitChainer(key sdk.StoreKey) func(sdk.Context, abci.RequestInitChain) abci
|
||||||
// GenInitOptions can be passed into InitCmd,
|
// GenInitOptions can be passed into InitCmd,
|
||||||
// returns a static string of a few key-values that can be parsed
|
// returns a static string of a few key-values that can be parsed
|
||||||
// by InitChainer
|
// by InitChainer
|
||||||
func GenInitOptions(args []string) (json.RawMessage, string, cmn.HexBytes, error) {
|
func GenInitOptions(args []string, addr sdk.Address, coinDenom string) (json.RawMessage, error) {
|
||||||
opts := []byte(`{
|
opts := []byte(`{
|
||||||
"values": [
|
"values": [
|
||||||
{
|
{
|
||||||
|
@ -120,5 +119,5 @@ func GenInitOptions(args []string) (json.RawMessage, string, cmn.HexBytes, error
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}`)
|
}`)
|
||||||
return opts, "", nil, nil
|
return opts, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,7 @@ func TestInitApp(t *testing.T) {
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
// initialize it future-way
|
// initialize it future-way
|
||||||
opts, _, _, err := GenInitOptions(nil)
|
opts, err := GenInitOptions(nil, nil, "")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
req := abci.RequestInitChain{AppStateBytes: opts}
|
req := abci.RequestInitChain{AppStateBytes: opts}
|
||||||
app.InitChain(req)
|
app.InitChain(req)
|
||||||
|
|
|
@ -1,62 +0,0 @@
|
||||||
// +build scripts
|
|
||||||
|
|
||||||
package main
|
|
||||||
|
|
||||||
/*
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"os"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/gorilla/websocket"
|
|
||||||
"github.com/tendermint/go-wire"
|
|
||||||
_ "github.com/tendermint/tendermint/rpc/core/types" // Register RPCResponse > Result types
|
|
||||||
"github.com/tendermint/tendermint/rpc/lib/client"
|
|
||||||
"github.com/tendermint/tendermint/rpc/lib/types"
|
|
||||||
cmn "github.com/tendermint/tmlibs/common"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
ws := rpcclient.NewWSClient(os.Args[1]+":46657", "/websocket")
|
|
||||||
|
|
||||||
_, err := ws.Start()
|
|
||||||
if err != nil {
|
|
||||||
cmn.Exit(err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
// Read a bunch of responses
|
|
||||||
go func() {
|
|
||||||
for {
|
|
||||||
res, ok := <-ws.ResultsCh
|
|
||||||
if !ok {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
//fmt.Println(counter, "res:", Blue(string(res)))
|
|
||||||
var result []interface{}
|
|
||||||
err := json.Unmarshal([]byte(string(res)), &result)
|
|
||||||
if err != nil {
|
|
||||||
Exit("Error unmarshalling block: " + err.Error())
|
|
||||||
}
|
|
||||||
height := result[1].(map[string]interface{})["block"].(map[string]interface{})["header"].(map[string]interface{})["height"]
|
|
||||||
txs := result[1].(map[string]interface{})["block"].(map[string]interface{})["data"].(map[string]interface{})["txs"]
|
|
||||||
if len(txs.([]interface{})) > 0 {
|
|
||||||
fmt.Println(">>", height, txs)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
for i := 0; i < 100000; i++ {
|
|
||||||
request := rpctypes.NewRPCRequest("fakeid", "block", Arr(i))
|
|
||||||
reqBytes := wire.JSONBytes(request)
|
|
||||||
err = ws.WriteMessage(websocket.TextMessage, reqBytes)
|
|
||||||
if err != nil {
|
|
||||||
cmn.Exit("writing websocket request: " + err.Error())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
time.Sleep(time.Second * 1000)
|
|
||||||
|
|
||||||
ws.Stop()
|
|
||||||
}
|
|
||||||
*/
|
|
|
@ -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}
|
|
||||||
}
|
|
|
@ -5,20 +5,32 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
|
|
||||||
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
|
"github.com/tendermint/go-crypto/keys"
|
||||||
|
"github.com/tendermint/go-crypto/keys/words"
|
||||||
cfg "github.com/tendermint/tendermint/config"
|
cfg "github.com/tendermint/tendermint/config"
|
||||||
"github.com/tendermint/tendermint/p2p"
|
"github.com/tendermint/tendermint/p2p"
|
||||||
tmtypes "github.com/tendermint/tendermint/types"
|
tmtypes "github.com/tendermint/tendermint/types"
|
||||||
cmn "github.com/tendermint/tmlibs/common"
|
cmn "github.com/tendermint/tmlibs/common"
|
||||||
|
dbm "github.com/tendermint/tmlibs/db"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// testnetInformation contains the info necessary
|
||||||
|
// to setup a testnet including this account and validator.
|
||||||
type testnetInformation struct {
|
type testnetInformation struct {
|
||||||
Secret string `json:"secret"`
|
Secret string `json:"secret"`
|
||||||
|
|
||||||
|
ChainID string `json:"chain_id"`
|
||||||
Account string `json:"account"`
|
Account string `json:"account"`
|
||||||
Validator tmtypes.GenesisValidator `json:"validator"`
|
Validator tmtypes.GenesisValidator `json:"validator"`
|
||||||
NodeID p2p.ID `json:"node_id"`
|
NodeID p2p.ID `json:"node_id"`
|
||||||
ChainID string `json:"chain_id"`
|
}
|
||||||
|
|
||||||
|
type initCmd struct {
|
||||||
|
genAppState GenAppState
|
||||||
|
context *Context
|
||||||
}
|
}
|
||||||
|
|
||||||
// InitCmd will initialize all files for tendermint,
|
// InitCmd will initialize all files for tendermint,
|
||||||
|
@ -39,17 +51,6 @@ func InitCmd(gen GenAppState, ctx *Context) *cobra.Command {
|
||||||
return &cobraCmd
|
return &cobraCmd
|
||||||
}
|
}
|
||||||
|
|
||||||
// GenAppState can parse command-line to
|
|
||||||
// generate default app_state for the genesis file.
|
|
||||||
// Also must return generated seed and address
|
|
||||||
// This is application-specific
|
|
||||||
type GenAppState func(args []string) (json.RawMessage, string, cmn.HexBytes, error)
|
|
||||||
|
|
||||||
type initCmd struct {
|
|
||||||
genAppState GenAppState
|
|
||||||
context *Context
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c initCmd) run(cmd *cobra.Command, args []string) error {
|
func (c initCmd) run(cmd *cobra.Command, args []string) error {
|
||||||
// Store testnet information as we go
|
// Store testnet information as we go
|
||||||
var testnetInfo testnetInformation
|
var testnetInfo testnetInformation
|
||||||
|
@ -67,14 +68,22 @@ func (c initCmd) run(cmd *cobra.Command, args []string) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// generate secrete and address
|
||||||
|
addr, secret, err := GenerateCoinKey()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var DEFAULT_DENOM = "mycoin"
|
||||||
|
|
||||||
// Now, we want to add the custom app_state
|
// Now, we want to add the custom app_state
|
||||||
appState, secret, address, err := c.genAppState(args)
|
appState, err := c.genAppState(args, addr, DEFAULT_DENOM)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
testnetInfo.Secret = secret
|
testnetInfo.Secret = secret
|
||||||
testnetInfo.Account = address.String()
|
testnetInfo.Account = addr.String()
|
||||||
|
|
||||||
// And add them to the genesis file
|
// And add them to the genesis file
|
||||||
genFile := config.GenesisFile()
|
genFile := config.GenesisFile()
|
||||||
|
@ -144,6 +153,34 @@ func (c initCmd) initTendermintFiles(config *cfg.Config, info *testnetInformatio
|
||||||
return nil
|
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
|
// GenesisDoc involves some tendermint-specific structures we don't
|
||||||
// want to parse, so we just grab it into a raw object format,
|
// want to parse, so we just grab it into a raw object format,
|
||||||
// so we can add one line.
|
// so we can add one line.
|
||||||
|
@ -169,3 +206,30 @@ func addGenesisState(filename string, appState json.RawMessage) error {
|
||||||
|
|
||||||
return ioutil.WriteFile(filename, out, 0600)
|
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
|
||||||
|
}
|
||||||
|
|
|
@ -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
|
|
||||||
}
|
|
|
@ -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
|
|
||||||
}
|
|
|
@ -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
|
|
||||||
}
|
|
|
@ -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
|
|
||||||
}
|
|
|
@ -21,13 +21,13 @@ const (
|
||||||
flagAddress = "address"
|
flagAddress = "address"
|
||||||
)
|
)
|
||||||
|
|
||||||
// appGenerator lets us lazily initialize app, using home dir
|
// AppCreator lets us lazily initialize app, using home dir
|
||||||
// and other flags (?) to start
|
// and other flags (?) to start
|
||||||
type appCreator func(string, log.Logger) (abci.Application, error)
|
type AppCreator func(string, log.Logger) (abci.Application, error)
|
||||||
|
|
||||||
// StartCmd runs the service passed in, either
|
// StartCmd runs the service passed in, either
|
||||||
// stand-alone, or in-process with tendermint
|
// stand-alone, or in-process with tendermint
|
||||||
func StartCmd(app appCreator, ctx *Context) *cobra.Command {
|
func StartCmd(app AppCreator, ctx *Context) *cobra.Command {
|
||||||
start := startCmd{
|
start := startCmd{
|
||||||
appCreator: app,
|
appCreator: app,
|
||||||
context: ctx,
|
context: ctx,
|
||||||
|
@ -48,7 +48,7 @@ func StartCmd(app appCreator, ctx *Context) *cobra.Command {
|
||||||
}
|
}
|
||||||
|
|
||||||
type startCmd struct {
|
type startCmd struct {
|
||||||
appCreator appCreator
|
appCreator AppCreator
|
||||||
context *Context
|
context *Context
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
}
|
|
@ -0,0 +1,68 @@
|
||||||
|
package server
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
"github.com/spf13/viper"
|
||||||
|
|
||||||
|
"github.com/cosmos/cosmos-sdk/version"
|
||||||
|
tcmd "github.com/tendermint/tendermint/cmd/tendermint/commands"
|
||||||
|
cfg "github.com/tendermint/tendermint/config"
|
||||||
|
"github.com/tendermint/tmlibs/cli"
|
||||||
|
tmflags "github.com/tendermint/tmlibs/cli/flags"
|
||||||
|
"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
|
||||||
|
func PersistentPreRunEFn(context *Context) func(*cobra.Command, []string) error {
|
||||||
|
return func(cmd *cobra.Command, args []string) error {
|
||||||
|
if cmd.Name() == version.VersionCmd.Name() {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
config, err := tcmd.ParseConfig()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout))
|
||||||
|
logger, err = tmflags.ParseLogLevel(config.LogLevel, logger, cfg.DefaultLogLevel())
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if viper.GetBool(cli.TraceFlag) {
|
||||||
|
logger = log.NewTracingLogger(logger)
|
||||||
|
}
|
||||||
|
logger = logger.With("module", "main")
|
||||||
|
context.Config = config
|
||||||
|
context.Logger = logger
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func AddCommands(
|
||||||
|
rootCmd *cobra.Command,
|
||||||
|
appState GenAppState, appCreator AppCreator,
|
||||||
|
context *Context) {
|
||||||
|
|
||||||
|
rootCmd.AddCommand(
|
||||||
|
InitCmd(appState, context),
|
||||||
|
StartCmd(appCreator, context),
|
||||||
|
UnsafeResetAllCmd(context),
|
||||||
|
ShowNodeIDCmd(context),
|
||||||
|
ShowValidatorCmd(context),
|
||||||
|
version.VersionCmd,
|
||||||
|
)
|
||||||
|
}
|
Loading…
Reference in New Issue