This commit is contained in:
changtong1996 2020-05-02 16:08:54 +08:00 committed by GitHub
parent 9c246b3692
commit e5b1e4d1ce
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
32 changed files with 2932 additions and 0 deletions

33
Makefile Normal file
View File

@ -0,0 +1,33 @@
PACKAGES=$(shell go list ./... | grep -v '/simulation')
VERSION := $(shell echo $(shell git describe --tags) | sed 's/^v//')
COMMIT := $(shell git log -1 --format='%H')
# TODO: Update the ldflags with the app, client & server names
ldflags = -X github.com/cosmos/cosmos-sdk/version.Name=NewApp \
-X github.com/cosmos/cosmos-sdk/version.ServerName=djzhd \
-X github.com/cosmos/cosmos-sdk/version.ClientName=djzhcli \
-X github.com/cosmos/cosmos-sdk/version.Version=$(VERSION) \
-X github.com/cosmos/cosmos-sdk/version.Commit=$(COMMIT)
BUILD_FLAGS := -ldflags '$(ldflags)'
all: install
install: go.sum
go install $(BUILD_FLAGS) ./cmd/djzhd
go install $(BUILD_FLAGS) ./cmd/djzhcli
go.sum: go.mod
@echo "--> Ensure dependencies have not been modified"
GO111MODULE=on go mod verify
# Uncomment when you have some tests
# test:
# @go test -mod=readonly $(PACKAGES)
# look into .golangci.yml for enabling / disabling linters
lint:
@echo "--> Running linter"
@golangci-lint run
@go mod verify

346
app/app.go Normal file
View File

@ -0,0 +1,346 @@
package app
import (
"encoding/json"
"io"
"os"
abci "github.com/tendermint/tendermint/abci/types"
"github.com/tendermint/tendermint/libs/log"
tmos "github.com/tendermint/tendermint/libs/os"
dbm "github.com/tendermint/tm-db"
bam "github.com/cosmos/cosmos-sdk/baseapp"
"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/simapp"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/module"
"github.com/cosmos/cosmos-sdk/version"
"github.com/cosmos/cosmos-sdk/x/auth"
"github.com/cosmos/cosmos-sdk/x/auth/vesting"
"github.com/cosmos/cosmos-sdk/x/bank"
distr "github.com/cosmos/cosmos-sdk/x/distribution"
"github.com/cosmos/cosmos-sdk/x/genutil"
"github.com/cosmos/cosmos-sdk/x/params"
"github.com/cosmos/cosmos-sdk/x/slashing"
"github.com/cosmos/cosmos-sdk/x/staking"
"github.com/cosmos/cosmos-sdk/x/supply"
"github.com/changtong1996/djzh/x/djzh"
)
const appName = "app"
var (
// TODO: rename your cli
// DefaultCLIHome default home directories for the application CLI
DefaultCLIHome = os.ExpandEnv("$HOME/.djzhcli")
// TODO: rename your daemon
// DefaultNodeHome sets the folder where the applcation data and configuration will be stored
DefaultNodeHome = os.ExpandEnv("$HOME/.djzhd")
// ModuleBasics The module BasicManager is in charge of setting up basic,
// non-dependant module elements, such as codec registration
// and genesis verification.
ModuleBasics = module.NewBasicManager(
genutil.AppModuleBasic{},
auth.AppModuleBasic{},
bank.AppModuleBasic{},
staking.AppModuleBasic{},
distr.AppModuleBasic{},
params.AppModuleBasic{},
slashing.AppModuleBasic{},
supply.AppModuleBasic{},
// TODO: Add your module(s) AppModuleBasic
djzh.AppModuleBasic{},
)
// module account permissions
maccPerms = map[string][]string{
auth.FeeCollectorName: nil,
distr.ModuleName: nil,
staking.BondedPoolName: {supply.Burner, supply.Staking},
staking.NotBondedPoolName: {supply.Burner, supply.Staking},
}
)
// MakeCodec creates the application codec. The codec is sealed before it is
// returned.
func MakeCodec() *codec.Codec {
var cdc = codec.New()
ModuleBasics.RegisterCodec(cdc)
vesting.RegisterCodec(cdc)
sdk.RegisterCodec(cdc)
codec.RegisterCrypto(cdc)
return cdc.Seal()
}
// NewApp extended ABCI application
type NewApp struct {
*bam.BaseApp
cdc *codec.Codec
invCheckPeriod uint
// keys to access the substores
keys map[string]*sdk.KVStoreKey
tKeys map[string]*sdk.TransientStoreKey
// subspaces
subspaces map[string]params.Subspace
// keepers
accountKeeper auth.AccountKeeper
bankKeeper bank.Keeper
stakingKeeper staking.Keeper
slashingKeeper slashing.Keeper
distrKeeper distr.Keeper
supplyKeeper supply.Keeper
paramsKeeper params.Keeper
// TODO: Add your module(s)
djzhKeeper djzh.Keeper
// Module Manager
mm *module.Manager
// simulation manager
sm *module.SimulationManager
}
// verify app interface at compile time
var _ simapp.App = (*NewApp)(nil)
// NewdjzhApp is a constructor function for djzhApp
func NewInitApp(
logger log.Logger, db dbm.DB, traceStore io.Writer, loadLatest bool,
invCheckPeriod uint, baseAppOptions ...func(*bam.BaseApp),
) *NewApp {
// First define the top level codec that will be shared by the different modules
cdc := MakeCodec()
// BaseApp handles interactions with Tendermint through the ABCI protocol
bApp := bam.NewBaseApp(appName, logger, db, auth.DefaultTxDecoder(cdc), baseAppOptions...)
bApp.SetCommitMultiStoreTracer(traceStore)
bApp.SetAppVersion(version.Version)
// TODO: Add the keys that module requires
keys := sdk.NewKVStoreKeys(bam.MainStoreKey, auth.StoreKey, staking.StoreKey,
supply.StoreKey, distr.StoreKey, slashing.StoreKey, params.StoreKey, djzh.StoreKey)
tKeys := sdk.NewTransientStoreKeys(staking.TStoreKey, params.TStoreKey)
// Here you initialize your application with the store keys it requires
var app = &NewApp{
BaseApp: bApp,
cdc: cdc,
invCheckPeriod: invCheckPeriod,
keys: keys,
tKeys: tKeys,
subspaces: make(map[string]params.Subspace),
}
// The ParamsKeeper handles parameter storage for the application
app.paramsKeeper = params.NewKeeper(app.cdc, keys[params.StoreKey], tKeys[params.TStoreKey])
// Set specific supspaces
app.subspaces[auth.ModuleName] = app.paramsKeeper.Subspace(auth.DefaultParamspace)
app.subspaces[bank.ModuleName] = app.paramsKeeper.Subspace(bank.DefaultParamspace)
app.subspaces[staking.ModuleName] = app.paramsKeeper.Subspace(staking.DefaultParamspace)
app.subspaces[distr.ModuleName] = app.paramsKeeper.Subspace(distr.DefaultParamspace)
app.subspaces[slashing.ModuleName] = app.paramsKeeper.Subspace(slashing.DefaultParamspace)
// The AccountKeeper handles address -> account lookups
app.accountKeeper = auth.NewAccountKeeper(
app.cdc,
keys[auth.StoreKey],
app.subspaces[auth.ModuleName],
auth.ProtoBaseAccount,
)
// The BankKeeper allows you perform sdk.Coins interactions
app.bankKeeper = bank.NewBaseKeeper(
app.accountKeeper,
app.subspaces[bank.ModuleName],
app.ModuleAccountAddrs(),
)
// The SupplyKeeper collects transaction fees and renders them to the fee distribution module
app.supplyKeeper = supply.NewKeeper(
app.cdc,
keys[supply.StoreKey],
app.accountKeeper,
app.bankKeeper,
maccPerms,
)
// The staking keeper
stakingKeeper := staking.NewKeeper(
app.cdc,
keys[staking.StoreKey],
app.supplyKeeper,
app.subspaces[staking.ModuleName],
)
app.distrKeeper = distr.NewKeeper(
app.cdc,
keys[distr.StoreKey],
app.subspaces[distr.ModuleName],
&stakingKeeper,
app.supplyKeeper,
auth.FeeCollectorName,
app.ModuleAccountAddrs(),
)
app.slashingKeeper = slashing.NewKeeper(
app.cdc,
keys[slashing.StoreKey],
&stakingKeeper,
app.subspaces[slashing.ModuleName],
)
// register the staking hooks
// NOTE: stakingKeeper above is passed by reference, so that it will contain these hooks
app.stakingKeeper = *stakingKeeper.SetHooks(
staking.NewMultiStakingHooks(
app.distrKeeper.Hooks(),
app.slashingKeeper.Hooks()),
)
// TODO: Add your module(s) keepers
app.djzhKeeper = djzh.NewKeeper(
app.bankKeeper,
keys[djzh.StoreKey],
app.cdc,
)
// NOTE: Any module instantiated in the module manager that is later modified
// must be passed by reference here.
app.mm = module.NewManager(
genutil.NewAppModule(app.accountKeeper, app.stakingKeeper, app.BaseApp.DeliverTx),
auth.NewAppModule(app.accountKeeper),
bank.NewAppModule(app.bankKeeper, app.accountKeeper),
supply.NewAppModule(app.supplyKeeper, app.accountKeeper),
distr.NewAppModule(app.distrKeeper, app.accountKeeper, app.supplyKeeper, app.stakingKeeper),
slashing.NewAppModule(app.slashingKeeper, app.accountKeeper, app.stakingKeeper),
// TODO: Add your module(s)
staking.NewAppModule(app.stakingKeeper, app.accountKeeper, app.supplyKeeper),
djzh.NewAppModule(app.djzhKeeper, app.bankKeeper),
)
// During begin block slashing happens after distr.BeginBlocker so that
// there is nothing left over in the validator fee pool, so as to keep the
// CanWithdrawInvariant invariant.
app.mm.SetOrderBeginBlockers(distr.ModuleName, slashing.ModuleName)
app.mm.SetOrderEndBlockers(staking.ModuleName)
// Sets the order of Genesis - Order matters, genutil is to always come last
// NOTE: The genutils module must occur after staking so that pools are
// properly initialized with tokens from genesis accounts.
app.mm.SetOrderInitGenesis(
distr.ModuleName,
staking.ModuleName,
auth.ModuleName,
bank.ModuleName,
slashing.ModuleName,
// TODO: Add your module(s)
supply.ModuleName,
genutil.ModuleName,
djzh.ModuleName,
)
// register all module routes and module queriers
app.mm.RegisterRoutes(app.Router(), app.QueryRouter())
// The initChainer handles translating the genesis.json file into initial state for the network
app.SetInitChainer(app.InitChainer)
app.SetBeginBlocker(app.BeginBlocker)
app.SetEndBlocker(app.EndBlocker)
// The AnteHandler handles signature verification and transaction pre-processing
app.SetAnteHandler(
auth.NewAnteHandler(
app.accountKeeper,
app.supplyKeeper,
auth.DefaultSigVerificationGasConsumer,
),
)
// initialize stores
app.MountKVStores(keys)
app.MountTransientStores(tKeys)
if loadLatest {
err := app.LoadLatestVersion(app.keys[bam.MainStoreKey])
if err != nil {
tmos.Exit(err.Error())
}
}
return app
}
// GenesisState represents chain state at the start of the chain. Any initial state (account balances) are stored here.
type GenesisState map[string]json.RawMessage
// NewDefaultGenesisState generates the default state for the application.
func NewDefaultGenesisState() GenesisState {
return ModuleBasics.DefaultGenesis()
}
// InitChainer application update at chain initialization
func (app *NewApp) InitChainer(ctx sdk.Context, req abci.RequestInitChain) abci.ResponseInitChain {
var genesisState simapp.GenesisState
app.cdc.MustUnmarshalJSON(req.AppStateBytes, &genesisState)
return app.mm.InitGenesis(ctx, genesisState)
}
// BeginBlocker application updates every begin block
func (app *NewApp) BeginBlocker(ctx sdk.Context, req abci.RequestBeginBlock) abci.ResponseBeginBlock {
return app.mm.BeginBlock(ctx, req)
}
// EndBlocker application updates every end block
func (app *NewApp) EndBlocker(ctx sdk.Context, req abci.RequestEndBlock) abci.ResponseEndBlock {
return app.mm.EndBlock(ctx, req)
}
// LoadHeight loads a particular height
func (app *NewApp) LoadHeight(height int64) error {
return app.LoadVersion(height, app.keys[bam.MainStoreKey])
}
// ModuleAccountAddrs returns all the app's module account addresses.
func (app *NewApp) ModuleAccountAddrs() map[string]bool {
modAccAddrs := make(map[string]bool)
for acc := range maccPerms {
modAccAddrs[supply.NewModuleAddress(acc).String()] = true
}
return modAccAddrs
}
// Codec returns the application's sealed codec.
func (app *NewApp) Codec() *codec.Codec {
return app.cdc
}
// SimulationManager implements the SimulationApp interface
func (app *NewApp) SimulationManager() *module.SimulationManager {
return app.sm
}
// GetMaccPerms returns a mapping of the application's module account permissions.
func GetMaccPerms() map[string][]string {
modAccPerms := make(map[string][]string)
for k, v := range maccPerms {
modAccPerms[k] = v
}
return modAccPerms
}

169
app/export.go Normal file
View File

@ -0,0 +1,169 @@
package app
import (
"encoding/json"
"log"
abci "github.com/tendermint/tendermint/abci/types"
tmtypes "github.com/tendermint/tendermint/types"
"github.com/cosmos/cosmos-sdk/codec"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/slashing"
"github.com/cosmos/cosmos-sdk/x/staking"
)
// ExportAppStateAndValidators exports the state of the application for a genesis
// file.
func (app *NewApp) ExportAppStateAndValidators(
forZeroHeight bool, jailWhiteList []string,
) (appState json.RawMessage, validators []tmtypes.GenesisValidator, err error) {
// as if they could withdraw from the start of the next block
ctx := app.NewContext(true, abci.Header{Height: app.LastBlockHeight()})
if forZeroHeight {
app.prepForZeroHeightGenesis(ctx, jailWhiteList)
}
genState := app.mm.ExportGenesis(ctx)
appState, err = codec.MarshalJSONIndent(app.cdc, genState)
if err != nil {
return nil, nil, err
}
validators = staking.WriteValidators(ctx, app.stakingKeeper)
return appState, validators, nil
}
// prepare for fresh start at zero height
// NOTE zero height genesis is a temporary feature which will be deprecated
// in favour of export at a block height
func (app *NewApp) prepForZeroHeightGenesis(ctx sdk.Context, jailWhiteList []string) {
applyWhiteList := false
//Check if there is a whitelist
if len(jailWhiteList) > 0 {
applyWhiteList = true
}
whiteListMap := make(map[string]bool)
for _, addr := range jailWhiteList {
_, err := sdk.ValAddressFromBech32(addr)
if err != nil {
log.Fatal(err)
}
whiteListMap[addr] = true
}
/* Handle fee distribution state. */
// withdraw all validator commission
app.stakingKeeper.IterateValidators(ctx, func(_ int64, val staking.ValidatorI) (stop bool) {
_, err := app.distrKeeper.WithdrawValidatorCommission(ctx, val.GetOperator())
if err != nil {
log.Fatal(err)
}
return false
})
// withdraw all delegator rewards
dels := app.stakingKeeper.GetAllDelegations(ctx)
for _, delegation := range dels {
_, err := app.distrKeeper.WithdrawDelegationRewards(ctx, delegation.DelegatorAddress, delegation.ValidatorAddress)
if err != nil {
log.Fatal(err)
}
}
// clear validator slash events
app.distrKeeper.DeleteAllValidatorSlashEvents(ctx)
// clear validator historical rewards
app.distrKeeper.DeleteAllValidatorHistoricalRewards(ctx)
// set context height to zero
height := ctx.BlockHeight()
ctx = ctx.WithBlockHeight(0)
// reinitialize all validators
app.stakingKeeper.IterateValidators(ctx, func(_ int64, val staking.ValidatorI) (stop bool) {
// donate any unwithdrawn outstanding reward fraction tokens to the community pool
scraps := app.distrKeeper.GetValidatorOutstandingRewards(ctx, val.GetOperator())
feePool := app.distrKeeper.GetFeePool(ctx)
feePool.CommunityPool = feePool.CommunityPool.Add(scraps...)
app.distrKeeper.SetFeePool(ctx, feePool)
app.distrKeeper.Hooks().AfterValidatorCreated(ctx, val.GetOperator())
return false
})
// reinitialize all delegations
for _, del := range dels {
app.distrKeeper.Hooks().BeforeDelegationCreated(ctx, del.DelegatorAddress, del.ValidatorAddress)
app.distrKeeper.Hooks().AfterDelegationModified(ctx, del.DelegatorAddress, del.ValidatorAddress)
}
// reset context height
ctx = ctx.WithBlockHeight(height)
/* Handle staking state. */
// iterate through redelegations, reset creation height
app.stakingKeeper.IterateRedelegations(ctx, func(_ int64, red staking.Redelegation) (stop bool) {
for i := range red.Entries {
red.Entries[i].CreationHeight = 0
}
app.stakingKeeper.SetRedelegation(ctx, red)
return false
})
// iterate through unbonding delegations, reset creation height
app.stakingKeeper.IterateUnbondingDelegations(ctx, func(_ int64, ubd staking.UnbondingDelegation) (stop bool) {
for i := range ubd.Entries {
ubd.Entries[i].CreationHeight = 0
}
app.stakingKeeper.SetUnbondingDelegation(ctx, ubd)
return false
})
// Iterate through validators by power descending, reset bond heights, and
// update bond intra-tx counters.
store := ctx.KVStore(app.keys[staking.StoreKey])
iter := sdk.KVStoreReversePrefixIterator(store, staking.ValidatorsKey)
counter := int16(0)
for ; iter.Valid(); iter.Next() {
addr := sdk.ValAddress(iter.Key()[1:])
validator, found := app.stakingKeeper.GetValidator(ctx, addr)
if !found {
panic("expected validator, not found")
}
validator.UnbondingHeight = 0
if applyWhiteList && !whiteListMap[addr.String()] {
validator.Jailed = true
}
app.stakingKeeper.SetValidator(ctx, validator)
counter++
}
iter.Close()
_ = app.stakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx)
/* Handle slashing state. */
// reset start height on signing infos
app.slashingKeeper.IterateValidatorSigningInfos(
ctx,
func(addr sdk.ConsAddress, info slashing.ValidatorSigningInfo) (stop bool) {
info.StartHeight = 0
app.slashingKeeper.SetValidatorSigningInfo(ctx, addr, info)
return false
},
)
}

173
cmd/djzhcli/main.go Normal file
View File

@ -0,0 +1,173 @@
package main
import (
"fmt"
"os"
"path"
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/flags"
"github.com/cosmos/cosmos-sdk/client/keys"
"github.com/cosmos/cosmos-sdk/client/lcd"
"github.com/cosmos/cosmos-sdk/client/rpc"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/version"
"github.com/cosmos/cosmos-sdk/x/auth"
authcmd "github.com/cosmos/cosmos-sdk/x/auth/client/cli"
authrest "github.com/cosmos/cosmos-sdk/x/auth/client/rest"
"github.com/cosmos/cosmos-sdk/x/bank"
bankcmd "github.com/cosmos/cosmos-sdk/x/bank/client/cli"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"github.com/tendermint/go-amino"
"github.com/tendermint/tendermint/libs/cli"
"github.com/changtong1996/djzh/app"
)
func main() {
// Configure cobra to sort commands
cobra.EnableCommandSorting = false
// Instantiate the codec for the command line application
cdc := app.MakeCodec()
// Read in the configuration file for the sdk
config := sdk.GetConfig()
config.SetBech32PrefixForAccount(sdk.Bech32PrefixAccAddr, sdk.Bech32PrefixAccPub)
config.SetBech32PrefixForValidator(sdk.Bech32PrefixValAddr, sdk.Bech32PrefixValPub)
config.SetBech32PrefixForConsensusNode(sdk.Bech32PrefixConsAddr, sdk.Bech32PrefixConsPub)
config.Seal()
// TODO: setup keybase, viper object, etc. to be passed into
// the below functions and eliminate global vars, like we do
// with the cdc
rootCmd := &cobra.Command{
Use: "djzhcli",
Short: "djzh client",
}
// Add --chain-id to persistent flags and mark it required
rootCmd.PersistentFlags().String(flags.FlagChainID, "", "Chain ID of tendermint node")
rootCmd.PersistentPreRunE = func(_ *cobra.Command, _ []string) error {
return initConfig(rootCmd)
}
// Construct Root Command
rootCmd.AddCommand(
rpc.StatusCommand(),
client.ConfigCmd(app.DefaultCLIHome),
queryCmd(cdc),
txCmd(cdc),
flags.LineBreak,
lcd.ServeCommand(cdc, registerRoutes),
flags.LineBreak,
keys.Commands(),
flags.LineBreak,
version.Cmd,
flags.NewCompletionCmd(rootCmd, true),
)
// Add flags and prefix all env exposed with AA
executor := cli.PrepareMainCmd(rootCmd, "AA", app.DefaultCLIHome)
err := executor.Execute()
if err != nil {
fmt.Printf("Failed executing CLI command: %s, exiting...\n", err)
os.Exit(1)
}
}
func queryCmd(cdc *amino.Codec) *cobra.Command {
queryCmd := &cobra.Command{
Use: "query",
Aliases: []string{"q"},
Short: "Querying subcommands",
}
queryCmd.AddCommand(
authcmd.GetAccountCmd(cdc),
flags.LineBreak,
rpc.ValidatorCommand(cdc),
rpc.BlockCommand(),
authcmd.QueryTxsByEventsCmd(cdc),
authcmd.QueryTxCmd(cdc),
flags.LineBreak,
)
// add modules' query commands
app.ModuleBasics.AddQueryCommands(queryCmd, cdc)
return queryCmd
}
func txCmd(cdc *amino.Codec) *cobra.Command {
txCmd := &cobra.Command{
Use: "tx",
Short: "Transactions subcommands",
}
txCmd.AddCommand(
bankcmd.SendTxCmd(cdc),
flags.LineBreak,
authcmd.GetSignCommand(cdc),
authcmd.GetMultiSignCommand(cdc),
flags.LineBreak,
authcmd.GetBroadcastCommand(cdc),
authcmd.GetEncodeCommand(cdc),
authcmd.GetDecodeCommand(cdc),
flags.LineBreak,
)
// add modules' tx commands
app.ModuleBasics.AddTxCommands(txCmd, cdc)
// remove auth and bank commands as they're mounted under the root tx command
var cmdsToRemove []*cobra.Command
for _, cmd := range txCmd.Commands() {
if cmd.Use == auth.ModuleName || cmd.Use == bank.ModuleName {
cmdsToRemove = append(cmdsToRemove, cmd)
}
}
txCmd.RemoveCommand(cmdsToRemove...)
return txCmd
}
// registerRoutes registers the routes from the different modules for the LCD.
// NOTE: details on the routes added for each module are in the module documentation
// NOTE: If making updates here you also need to update the test helper in client/lcd/test_helper.go
func registerRoutes(rs *lcd.RestServer) {
client.RegisterRoutes(rs.CliCtx, rs.Mux)
authrest.RegisterTxRoutes(rs.CliCtx, rs.Mux)
app.ModuleBasics.RegisterRESTRoutes(rs.CliCtx, rs.Mux)
}
func initConfig(cmd *cobra.Command) error {
home, err := cmd.PersistentFlags().GetString(cli.HomeFlag)
if err != nil {
return err
}
cfgFile := path.Join(home, "config", "config.toml")
if _, err := os.Stat(cfgFile); err == nil {
viper.SetConfigFile(cfgFile)
if err := viper.ReadInConfig(); err != nil {
return err
}
}
if err := viper.BindPFlag(flags.FlagChainID, cmd.PersistentFlags().Lookup(flags.FlagChainID)); err != nil {
return err
}
if err := viper.BindPFlag(cli.EncodingFlag, cmd.PersistentFlags().Lookup(cli.EncodingFlag)); err != nil {
return err
}
return viper.BindPFlag(cli.OutputFlag, cmd.PersistentFlags().Lookup(cli.OutputFlag))
}

153
cmd/djzhd/genaccounts.go Normal file
View File

@ -0,0 +1,153 @@
package main
import (
"bufio"
"errors"
"fmt"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"github.com/tendermint/tendermint/libs/cli"
"github.com/cosmos/cosmos-sdk/client/flags"
"github.com/cosmos/cosmos-sdk/crypto/keys"
"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/server"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/auth"
authexported "github.com/cosmos/cosmos-sdk/x/auth/exported"
authvesting "github.com/cosmos/cosmos-sdk/x/auth/vesting"
"github.com/cosmos/cosmos-sdk/x/genutil"
)
const (
flagClientHome = "home-client"
flagVestingStart = "vesting-start-time"
flagVestingEnd = "vesting-end-time"
flagVestingAmt = "vesting-amount"
)
// AddGenesisAccountCmd returns add-genesis-account cobra Command.
func AddGenesisAccountCmd(
ctx *server.Context, cdc *codec.Codec, defaultNodeHome, defaultClientHome string,
) *cobra.Command {
cmd := &cobra.Command{
Use: "add-genesis-account [address_or_key_name] [coin][,[coin]]",
Short: "Add a genesis account to genesis.json",
Long: `Add a genesis account to genesis.json. The provided account must specify
the account address or key name and a list of initial coins. If a key name is given,
the address will be looked up in the local Keybase. The list of initial tokens must
contain valid denominations. Accounts may optionally be supplied with vesting parameters.
`,
Args: cobra.ExactArgs(2),
RunE: func(cmd *cobra.Command, args []string) error {
config := ctx.Config
config.SetRoot(viper.GetString(cli.HomeFlag))
addr, err := sdk.AccAddressFromBech32(args[0])
inBuf := bufio.NewReader(cmd.InOrStdin())
if err != nil {
// attempt to lookup address from Keybase if no address was provided
kb, err := keys.NewKeyring(
sdk.KeyringServiceName(),
viper.GetString(flags.FlagKeyringBackend),
viper.GetString(flagClientHome),
inBuf,
)
if err != nil {
return err
}
info, err := kb.Get(args[0])
if err != nil {
return fmt.Errorf("failed to get address from Keybase: %w", err)
}
addr = info.GetAddress()
}
coins, err := sdk.ParseCoins(args[1])
if err != nil {
return fmt.Errorf("failed to parse coins: %w", err)
}
vestingStart := viper.GetInt64(flagVestingStart)
vestingEnd := viper.GetInt64(flagVestingEnd)
vestingAmt, err := sdk.ParseCoins(viper.GetString(flagVestingAmt))
if err != nil {
return fmt.Errorf("failed to parse vesting amount: %w", err)
}
// create concrete account type based on input parameters
var genAccount authexported.GenesisAccount
baseAccount := auth.NewBaseAccount(addr, coins.Sort(), nil, 0, 0)
if !vestingAmt.IsZero() {
baseVestingAccount, err := authvesting.NewBaseVestingAccount(baseAccount, vestingAmt.Sort(), vestingEnd)
if err != nil {
return fmt.Errorf("failed to create base vesting account: %w", err)
}
switch {
case vestingStart != 0 && vestingEnd != 0:
genAccount = authvesting.NewContinuousVestingAccountRaw(baseVestingAccount, vestingStart)
case vestingEnd != 0:
genAccount = authvesting.NewDelayedVestingAccountRaw(baseVestingAccount)
default:
return errors.New("invalid vesting parameters; must supply start and end time or end time")
}
} else {
genAccount = baseAccount
}
if err := genAccount.Validate(); err != nil {
return fmt.Errorf("failed to validate new genesis account: %w", err)
}
genFile := config.GenesisFile()
appState, genDoc, err := genutil.GenesisStateFromGenFile(cdc, genFile)
if err != nil {
return fmt.Errorf("failed to unmarshal genesis state: %w", err)
}
authGenState := auth.GetGenesisStateFromAppState(cdc, appState)
if authGenState.Accounts.Contains(addr) {
return fmt.Errorf("cannot add account at existing address %s", addr)
}
// Add the new account to the set of genesis accounts and sanitize the
// accounts afterwards.
authGenState.Accounts = append(authGenState.Accounts, genAccount)
authGenState.Accounts = auth.SanitizeGenesisAccounts(authGenState.Accounts)
authGenStateBz, err := cdc.MarshalJSON(authGenState)
if err != nil {
return fmt.Errorf("failed to marshal auth genesis state: %w", err)
}
appState[auth.ModuleName] = authGenStateBz
appStateJSON, err := cdc.MarshalJSON(appState)
if err != nil {
return fmt.Errorf("failed to marshal application genesis state: %w", err)
}
genDoc.AppState = appStateJSON
return genutil.ExportGenesisFile(genDoc, genFile)
},
}
cmd.Flags().String(cli.HomeFlag, defaultNodeHome, "node's home directory")
//cmd.Flags().String(flags.FlagKeyringBackend, flags.DefaultKeyringBackend, "Select keyring's backend (os|file|test)")
cmd.Flags().String(flagClientHome, defaultClientHome, "client's home directory")
cmd.Flags().String(flagVestingAmt, "", "amount of coins for vesting accounts")
cmd.Flags().Uint64(flagVestingStart, 0, "schedule start time (unix epoch) for vesting accounts")
cmd.Flags().Uint64(flagVestingEnd, 0, "schedule end time (unix epoch) for vesting accounts")
return cmd
}

109
cmd/djzhd/main.go Normal file
View File

@ -0,0 +1,109 @@
package main
import (
"encoding/json"
"io"
"github.com/spf13/cobra"
"github.com/spf13/viper"
abci "github.com/tendermint/tendermint/abci/types"
"github.com/tendermint/tendermint/libs/cli"
"github.com/tendermint/tendermint/libs/log"
tmtypes "github.com/tendermint/tendermint/types"
dbm "github.com/tendermint/tm-db"
"github.com/changtong1996/djzh/app"
"github.com/cosmos/cosmos-sdk/baseapp"
"github.com/cosmos/cosmos-sdk/client/debug"
"github.com/cosmos/cosmos-sdk/client/flags"
"github.com/cosmos/cosmos-sdk/server"
"github.com/cosmos/cosmos-sdk/store"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/auth"
genutilcli "github.com/cosmos/cosmos-sdk/x/genutil/client/cli"
"github.com/cosmos/cosmos-sdk/x/staking"
)
const flagInvCheckPeriod = "inv-check-period"
var invCheckPeriod uint
func main() {
cdc := app.MakeCodec()
config := sdk.GetConfig()
config.SetBech32PrefixForAccount(sdk.Bech32PrefixAccAddr, sdk.Bech32PrefixAccPub)
config.SetBech32PrefixForValidator(sdk.Bech32PrefixValAddr, sdk.Bech32PrefixValPub)
config.SetBech32PrefixForConsensusNode(sdk.Bech32PrefixConsAddr, sdk.Bech32PrefixConsPub)
config.Seal()
ctx := server.NewDefaultContext()
cobra.EnableCommandSorting = false
rootCmd := &cobra.Command{
Use: "djzhd",
Short: "djzh Daemon (server)",
PersistentPreRunE: server.PersistentPreRunEFn(ctx),
}
rootCmd.AddCommand(genutilcli.InitCmd(ctx, cdc, app.ModuleBasics, app.DefaultNodeHome))
rootCmd.AddCommand(genutilcli.CollectGenTxsCmd(ctx, cdc, auth.GenesisAccountIterator{}, app.DefaultNodeHome))
rootCmd.AddCommand(genutilcli.MigrateGenesisCmd(ctx, cdc))
rootCmd.AddCommand(
genutilcli.GenTxCmd(
ctx, cdc, app.ModuleBasics, staking.AppModuleBasic{},
auth.GenesisAccountIterator{}, app.DefaultNodeHome, app.DefaultCLIHome,
),
)
rootCmd.AddCommand(genutilcli.ValidateGenesisCmd(ctx, cdc, app.ModuleBasics))
rootCmd.AddCommand(AddGenesisAccountCmd(ctx, cdc, app.DefaultNodeHome, app.DefaultCLIHome))
rootCmd.AddCommand(flags.NewCompletionCmd(rootCmd, true))
rootCmd.AddCommand(debug.Cmd(cdc))
server.AddCommands(ctx, cdc, rootCmd, newApp, exportAppStateAndTMValidators)
// prepare and add flags
executor := cli.PrepareBaseCmd(rootCmd, "AU", app.DefaultNodeHome)
rootCmd.PersistentFlags().UintVar(&invCheckPeriod, flagInvCheckPeriod,
0, "Assert registered invariants every N blocks")
err := executor.Execute()
if err != nil {
panic(err)
}
}
func newApp(logger log.Logger, db dbm.DB, traceStore io.Writer) abci.Application {
var cache sdk.MultiStorePersistentCache
if viper.GetBool(server.FlagInterBlockCache) {
cache = store.NewCommitKVStoreCacheManager()
}
return app.NewInitApp(
logger, db, traceStore, true, invCheckPeriod,
baseapp.SetPruning(store.NewPruningOptionsFromString(viper.GetString("pruning"))),
baseapp.SetMinGasPrices(viper.GetString(server.FlagMinGasPrices)),
baseapp.SetHaltHeight(viper.GetUint64(server.FlagHaltHeight)),
baseapp.SetHaltTime(viper.GetUint64(server.FlagHaltTime)),
baseapp.SetInterBlockCache(cache),
)
}
func exportAppStateAndTMValidators(
logger log.Logger, db dbm.DB, traceStore io.Writer, height int64, forZeroHeight bool, jailWhiteList []string,
) (json.RawMessage, []tmtypes.GenesisValidator, error) {
if height != -1 {
aApp := app.NewInitApp(logger, db, traceStore, true, uint(1))
err := aApp.LoadHeight(height)
if err != nil {
return nil, nil, err
}
return aApp.ExportAppStateAndValidators(forZeroHeight, jailWhiteList)
}
aApp := app.NewInitApp(logger, db, traceStore, true, uint(1))
return aApp.ExportAppStateAndValidators(forZeroHeight, jailWhiteList)
}

20
go.mod Normal file
View File

@ -0,0 +1,20 @@
module github.com/changtong1996/djzh
go 1.13
require (
github.com/btcsuite/btcd v0.0.0-20190807005414-4063feeff79a // indirect
github.com/cosmos/cosmos-sdk v0.38.0
github.com/golang/mock v1.3.1 // indirect
github.com/onsi/ginkgo v1.8.0 // indirect
github.com/onsi/gomega v1.5.0 // indirect
github.com/prometheus/client_golang v1.1.0 // indirect
github.com/rcrowley/go-metrics v0.0.0-20190706150252-9beb055b7962 // indirect
github.com/spf13/afero v1.2.2 // indirect
github.com/spf13/cobra v0.0.5
github.com/spf13/viper v1.6.2
github.com/tendermint/go-amino v0.15.1
github.com/tendermint/tendermint v0.33.0
github.com/tendermint/tm-db v0.4.0
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297 // indirect
golang.org/x/text v0.3.2 // indirect
)

7
x/djzh/README.md Normal file
View File

@ -0,0 +1,7 @@
# TODO
The scaffolding tool creates a module with countless todos. These todos are placed in places in which you much delete them and fill them with what the module you are building needs.
## APP
Once you have created your module and you are ready to integrate it into your app then you can follow the readme that is generated in the scaffolding of the app.

17
x/djzh/abci.go Normal file
View File

@ -0,0 +1,17 @@
package djzh
import (
sdk "github.com/cosmos/cosmos-sdk/types"
abci "github.com/tendermint/tendermint/abci/types"
)
// BeginBlocker check for infraction evidence or downtime of validators
// on every begin block
func BeginBlocker(ctx sdk.Context, req abci.RequestBeginBlock, k Keeper) {
// TODO: fill out if your application requires beginblock, if not you can delete this function
}
// EndBlocker called every block, process inflation, update validator set.
func EndBlocker(ctx sdk.Context, k Keeper) {
// TODO: fill out if your application requires endblock, if not you can delete this function
}

46
x/djzh/alias.go Normal file
View File

@ -0,0 +1,46 @@
package djzh
import (
"github.com/changtong1996/djzh/x/djzh/internal/keeper"
"github.com/changtong1996/djzh/x/djzh/internal/types"
)
const (
// TODO: define constants that you would like exposed from the internal package
ModuleName = types.ModuleName
RouterKey = types.RouterKey
StoreKey = types.StoreKey
DefaultParamspace = types.DefaultParamspace
//QueryParams = types.QueryParams
QuerierRoute = types.QuerierRoute
)
var (
// functions aliases
NewKeeper = keeper.NewKeeper
NewQuerier = keeper.NewQuerier
RegisterCodec = types.RegisterCodec
NewGenesisState = types.NewGenesisState
DefaultGenesisState = types.DefaultGenesisState
ValidateGenesis = types.ValidateGenesis
// TODO: Fill out function aliases
// variable aliases
ModuleCdc = types.ModuleCdc
// TODO: Fill out variable aliases
)
type (
Keeper = keeper.Keeper
GenesisState = types.GenesisState
Params = types.Params
/* QueryArticleNames = types.QueryArticleNames*/
// TODO: Fill out module types
/* QueryVoteNum = types.QueryVoteNum*/
MsgCreateArticle = types.MsgCreateArticle
MsgCreateComment = types.MsgCreateComment
MsgCreateReturnVisit= types.MsgCreateReturnVisit
MsgCreateAVote = types.MsgCreateAVote
MsgCreateCVote = types.MsgCreateCVote
)

View File

@ -0,0 +1,82 @@
package cli
import (
"fmt"
"github.com/spf13/cobra"
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/flags"
"github.com/cosmos/cosmos-sdk/client/context"
"github.com/cosmos/cosmos-sdk/codec"
/* sdk "github.com/cosmos/cosmos-sdk/types"*/
"github.com/changtong1996/djzh/x/djzh/internal/types"
)
// GetQueryCmd returns the cli query commands for this module
func GetQueryCmd(queryRoute string, cdc *codec.Codec) *cobra.Command {
// Group djzh queries under a subcommand
djzhQueryCmd := &cobra.Command{
Use: types.ModuleName,
Short: fmt.Sprintf("Querying commands for the %s module", types.ModuleName),
DisableFlagParsing: true,
SuggestionsMinimumDistance: 2,
RunE: client.ValidateCmd,
}
djzhQueryCmd.AddCommand(
flags.GetCommands(
// TODO: Add query Cmds
GetCmdArticle(queryRoute, cdc),
GetCmdVoteNum(queryRoute, cdc),
)...,
)
return djzhQueryCmd
}
// TODO: Add Query Commands
func GetCmdArticle(queryRoute string, cdc *codec.Codec) *cobra.Command {
return &cobra.Command{
Use: "article [article_id]",
Short: "Query a article by article_id",
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error{
cliCtx := context.NewCLIContext().WithCodec(cdc)
article_id := args[0]
res, _, err := cliCtx.QueryWithData(fmt.Sprintf("custom/%s/getarticle/%s", queryRoute, article_id), nil)
if err != nil {
fmt.Printf("could not get article - %s \n", article_id)
return nil
}
var out types.Article
cdc.MustUnmarshalJSON(res, &out)
return cliCtx.PrintOutput(out)
},
}
}
func GetCmdVoteNum(queryRoute string, cdc *codec.Codec) *cobra.Command {
return &cobra.Command{
Use: "vote number of article [name]",
Short: "get the vote number of a article",
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error{
cliCtx := context.NewCLIContext().WithCodec(cdc)
name := args[0]
res, _, err := cliCtx.QueryWithData(fmt.Sprintf("custom/%s/whois/%s", queryRoute, name), nil)
if err != nil {
fmt.Printf("could not get - %s \n", name)
return nil
}
var out types.Article
cdc.MustUnmarshalJSON(res, &out)
return cliCtx.PrintOutput(out)
},
}
}

83
x/djzh/client/cli/tx.go Normal file
View File

@ -0,0 +1,83 @@
package cli
import (
"fmt"
/* "bufio"
"strconv"*/
"github.com/spf13/cobra"
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/flags"
/* "github.com/cosmos/cosmos-sdk/client/context"*/
"github.com/cosmos/cosmos-sdk/codec"
/* sdk "github.com/cosmos/cosmos-sdk/types"*/
/* "github.com/cosmos/cosmos-sdk/x/auth"*/
/* "github.com/cosmos/cosmos-sdk/x/auth/client/utils"*/
"github.com/changtong1996/djzh/x/djzh/internal/types"
)
// GetTxCmd returns the transaction commands for this module
func GetTxCmd(cdc *codec.Codec) *cobra.Command {
djzhTxCmd := &cobra.Command{
Use: types.ModuleName,
Short: fmt.Sprintf("%s transactions subcommands", types.ModuleName),
DisableFlagParsing: true,
SuggestionsMinimumDistance: 2,
RunE: client.ValidateCmd,
}
djzhTxCmd.AddCommand(flags.PostCommands(
// TODO: Add tx based commands
// GetCmd<Action>(cdc)
)...)
return djzhTxCmd
}
/*func GetCmdNewVote(cdc *codec.Codec) *cobra.Command {
return &cobra.Command{
Use: "add-vote [article_id][voteup]",
Short: "add a vote",
Args: cobra.ExactArgs(2), // Does your request require arguments
RunE: func(cmd *cobra.Command, args []string) error {
cliCtx := context.NewCLIContext().WithCodec(cdc)
inBuf := bufio.NewReader(cmd.InOrStdin())
txBldr := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(utils.GetTxEncoder(cdc))
voteUP, err := strconv.Atoi(args[1])
msg := types.NewMsgCreateAVote(cliCtx.GetFromAddress(), args[0], voteUP)
err = msg.ValidateBasic()
if err != nil {
return err
}
return utils.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg})
},
}
}*/
// Example:
//
// GetCmd<Action> is the CLI command for doing <Action>
// func GetCmd<Action>(cdc *codec.Codec) *cobra.Command {
// return &cobra.Command{
// Use: "/* Describe your action cmd */",
// Short: "/* Provide a short description on the cmd */",
// Args: cobra.ExactArgs(2), // Does your request require arguments
// RunE: func(cmd *cobra.Command, args []string) error {
// cliCtx := context.NewCLIContext().WithCodec(cdc)
// inBuf := bufio.NewReader(cmd.InOrStdin())
// txBldr := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(utils.GetTxEncoder(cdc))
// msg := types.NewMsg<Action>(/* Action params */)
// err = msg.ValidateBasic()
// if err != nil {
// return err
// }
// return utils.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg})
// },
// }
// }

View File

@ -0,0 +1,58 @@
package rest
import (
"fmt"
"net/http"
"github.com/gorilla/mux"
"github.com/cosmos/cosmos-sdk/client/context"
"github.com/cosmos/cosmos-sdk/types/rest"
/* "github.com/changtong1996/djzh/x/djzh/internal/types"*/
)
func GetArticleHandler(cliCtx context.CLIContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r) //这个地方有点问题?得到的结果是什么
paramType := vars[article_id]
res, _, err := cliCtx.QueryWithData(fmt.Sprintf("custom/djzh/getarticle/%s", paramType), nil)
if err != nil {
rest.WriteErrorResponse(w, http.StatusNotFound, err.Error())
return
}
rest.PostProcessResponse(w, cliCtx, res)
}
}
/*func registerQueryRoutes(cliCtx context.CLIContext, r *mux.Router) {
// TODO: Define your GET REST endpoints
r.HandleFunc(
"/djzh/parameters",
queryParamsHandlerFn(cliCtx),
).Methods("GET")
}
func queryParamsHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
cliCtx, ok := rest.ParseQueryHeightOrReturnBadRequest(w, cliCtx, r)
if !ok {
return
}
route := fmt.Sprintf("custom/%s/parameters", types.QuerierRoute)
res, height, err := cliCtx.QueryWithData(route, nil)
if err != nil {
rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error())
return
}
cliCtx = cliCtx.WithHeight(height)
rest.PostProcessResponse(w, cliCtx, res)
}
}*/

View File

@ -0,0 +1,24 @@
package rest
import (
"fmt"
"github.com/gorilla/mux"
"github.com/cosmos/cosmos-sdk/client/context"
)
const(
article_id = "article_id"
)
// RegisterRoutes registers djzh-related REST handlers to a router
func RegisterRoutes(cliCtx context.CLIContext, r *mux.Router) {
/* registerQueryRoutes(cliCtx, r)
registerTxRoutes(cliCtx, r)*/
r.HandleFunc(fmt.Sprintf("/djzh/articles/getarticle"), GetArticleHandler(cliCtx)).Methods("POST")
r.HandleFunc(fmt.Sprintf("/djzh/articles/createarticle"), CreateArticleHandler(cliCtx)).Methods("POST")
r.HandleFunc(fmt.Sprintf("/djzh/articles/createcomment"), CreateCommentHandler(cliCtx)).Methods("POST")
r.HandleFunc(fmt.Sprintf("/djzh/articles/createreturnvisit"), CreateReturnVisitHandler(cliCtx)).Methods("POST")
r.HandleFunc(fmt.Sprintf("/djzh/articles/createavote"), CreateAVoteHandler(cliCtx)).Methods("POST")
r.HandleFunc(fmt.Sprintf("/djzh/articles/createcvote"), CreateCVoteHandler(cliCtx)).Methods("POST")
}

279
x/djzh/client/rest/tx.go Normal file
View File

@ -0,0 +1,279 @@
package rest
import (
/*"bytes"*/
"net/http"
/*
"github.com/gorilla/mux"*/
"github.com/cosmos/cosmos-sdk/client/context"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/rest"
"github.com/cosmos/cosmos-sdk/x/auth/client/utils"
"github.com/changtong1996/djzh/x/djzh/internal/types"
)
type CreateArticleReq struct {
BaseReq rest.BaseReq `json:"base_req"`
Creator string `json:"creator"` // address of the article creator
A_text string `json:"a_text"`
A_title string `json:"a_title"`
Tag string `json:"tag"`
Article_id string `json:"article_id"`
Tid string `json:"tid"`
Uid string `json:"uid"`
A_timestamp string `json:"a_timestamp"`
Reward sdk.Coins `json:"reward"` // reward of the article
}
func CreateArticleHandler(cliCtx context.CLIContext) http.HandlerFunc{
return func(w http.ResponseWriter, r *http.Request) {
var req CreateArticleReq
if !rest.ReadRESTReq(w, r, cliCtx.Codec, &req) {
rest.WriteErrorResponse(w, http.StatusBadRequest, "failed to parse request")
return
}
baseReq := req.BaseReq.Sanitize()
if !baseReq.ValidateBasic(w) {
return
}
addr, err := sdk.AccAddressFromBech32(req.Creator)
if err != nil {
rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error())
return
}
// create the message
msg := types.NewMsgCreateArticle(addr, req.A_text, req.A_title, req.Tag, req.Article_id, req.Tid, req.Uid, req.A_timestamp, req.Reward)
err = msg.ValidateBasic()
if err != nil {
rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error())
return
}
utils.WriteGenerateStdTxResponse(w, cliCtx, baseReq, []sdk.Msg{msg})
}
}
type CreateCommentReq struct {
BaseReq rest.BaseReq `json:"base_req"`
Creator string `json:"creator"` // address of the article creator
Comment_id string `json:"comment_id"` // id of the comment
Article_id string `json:"article_id"` // id of the article
Tid string `json:"tid"` // id of the transaction
Uid string `json:"uid"` // id of the user
C_timestamp string `json:"c_timestamp"` // timestamp of the comment
C_text string `json:"c_text"` // context of the comment
Reward sdk.Coins `json:"reward"`
}
func CreateCommentHandler(cliCtx context.CLIContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var req CreateCommentReq
if !rest.ReadRESTReq(w, r, cliCtx.Codec, &req) {
rest.WriteErrorResponse(w, http.StatusBadRequest, "failed to parse request")
return
}
baseReq := req.BaseReq.Sanitize()
if !baseReq.ValidateBasic(w) {
return
}
addr, err := sdk.AccAddressFromBech32(req.Creator)
if err != nil {
rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error())
return
}
// create the message
msg := types.NewMsgCreateComment(addr, req.Comment_id, req.Article_id, req.Tid, req.Uid, req.C_timestamp, req.C_text, req.Reward)
err = msg.ValidateBasic()
if err != nil {
rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error())
return
}
utils.WriteGenerateStdTxResponse(w, cliCtx, baseReq, []sdk.Msg{msg})
}
}
type CreateReturnVisitReq struct {
BaseReq rest.BaseReq `json:"base_req"`
Creator string `json:"creator"` // address of the article creator
Return_visit_id string `json:"return_visit_id"`
Article_id string `json:"article_id"`
Tid string `json:"tid"`
Uid string `json:"uid"`
Rv_timestamp string `json:"rv_timestamp"`
Rv_text string `json:"rv_text"`
Flag string `json:"flag"`
Reward sdk.Coins `json:"reward"` // reward of the article
}
func CreateReturnVisitHandler(cliCtx context.CLIContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var req CreateReturnVisitReq
if !rest.ReadRESTReq(w, r, cliCtx.Codec, &req) {
rest.WriteErrorResponse(w, http.StatusBadRequest, "failed to parse request")
return
}
baseReq := req.BaseReq.Sanitize()
if !baseReq.ValidateBasic(w) {
return
}
addr, err := sdk.AccAddressFromBech32(req.Creator)
if err != nil {
rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error())
return
}
// create the message
msg := types.NewMsgCreateReturnVisit(addr, req.Return_visit_id, req.Article_id, req.Tid, req.Uid, req.Rv_timestamp, req.Rv_text, req.Flag, req.Reward)
err = msg.ValidateBasic()
if err != nil {
rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error())
return
}
utils.WriteGenerateStdTxResponse(w, cliCtx, baseReq, []sdk.Msg{msg})
}
}
type CreateAVoteReq struct {
BaseReq rest.BaseReq `json:"base_req"`
Creator string `json:"creator"` // address of the article creator
Article_id string `json:"article_id"` // id of the article
VoteUP int `json:"voteUP"`
VoteDOWN int `json:"voteDOWN"`
Num int `json:"num"`
}
func CreateAVoteHandler(cliCtx context.CLIContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var req CreateAVoteReq
if !rest.ReadRESTReq(w, r, cliCtx.Codec, &req) {
rest.WriteErrorResponse(w, http.StatusBadRequest, "failed to parse request")
return
}
baseReq := req.BaseReq.Sanitize()
if !baseReq.ValidateBasic(w) {
return
}
addr, err := sdk.AccAddressFromBech32(req.Creator)
if err != nil {
rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error())
return
}
// create the message
msg := types.NewMsgCreateAVote(addr, req.Article_id, req.VoteUP, req.VoteDOWN, req.Num)
err = msg.ValidateBasic()
if err != nil {
rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error())
return
}
utils.WriteGenerateStdTxResponse(w, cliCtx, baseReq, []sdk.Msg{msg})
}
}
type CreateCVoteReq struct {
BaseReq rest.BaseReq `json:"base_req"`
Creator string `json:"creator"` // address of the comment creator
Comment_id string `json:"comment_id"` // id of the comment
VoteUP int `json:"voteUP"`
VoteDOWN int `json:"voteDOWN"`
Num int `json:"num"`
}
func CreateCVoteHandler(cliCtx context.CLIContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var req CreateCVoteReq
if !rest.ReadRESTReq(w, r, cliCtx.Codec, &req) {
rest.WriteErrorResponse(w, http.StatusBadRequest, "failed to parse request")
return
}
baseReq := req.BaseReq.Sanitize()
if !baseReq.ValidateBasic(w) {
return
}
addr, err := sdk.AccAddressFromBech32(req.Creator)
if err != nil {
rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error())
return
}
// create the message
msg := types.NewMsgCreateCVote(addr, req.Comment_id, req.VoteUP, req.VoteDOWN, req.Num)
err = msg.ValidateBasic()
if err != nil {
rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error())
return
}
utils.WriteGenerateStdTxResponse(w, cliCtx, baseReq, []sdk.Msg{msg})
}
}
/*func registerTxRoutes(cliCtx context.CLIContext, r *mux.Router) {
// r.HandleFunc(
// TODO: Define the Rest route ,
// Call the function which should be executed for this route),
// ).Methods("POST")
}*/
/*
// Action TX body
type <Action>Req struct {
BaseReq rest.BaseReq `json:"base_req" yaml:"base_req"`
// TODO: Define more types if needed
}
func <Action>RequestHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var req <Action>Req
vars := mux.Vars(r)
baseReq := req.BaseReq.Sanitize()
if !baseReq.ValidateBasic(w) {
return
}
// TODO: Define the module tx logic for this action
utils.WriteGenerateStdTxResponse(w, cliCtx, BaseReq, []sdk.Msg{msg})
}
}
*/

21
x/djzh/genesis.go Normal file
View File

@ -0,0 +1,21 @@
package djzh
import (
sdk "github.com/cosmos/cosmos-sdk/types"
/* abci "github.com/tendermint/tendermint/abci/types"*/
)
// InitGenesis initialize default parameters
// and the keeper's address to pubkey map
func InitGenesis(ctx sdk.Context, k Keeper, /* TODO: Define what keepers the module needs *//*,*/ data GenesisState) {
// TODO: Define logic for when you would like to initalize a new genesis
/* return []abci.ValidatorUpdate{}*/
}
// ExportGenesis writes the current store values
// to a genesis file, which can be imported again
// with InitGenesis
func ExportGenesis(ctx sdk.Context, k Keeper) (data GenesisState) {
// TODO: Define logic for exporting state
return NewGenesisState()
}

236
x/djzh/handler.go Normal file
View File

@ -0,0 +1,236 @@
package djzh
import (
"fmt"
"github.com/tendermint/tendermint/crypto"
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
"github.com/changtong1996/djzh/x/djzh/internal/types"
)
// NewHandler creates an sdk.Handler for all the djzh type messages
func NewHandler(k Keeper) sdk.Handler {
return func(ctx sdk.Context, msg sdk.Msg) (*sdk.Result, error) {
ctx = ctx.WithEventManager(sdk.NewEventManager())
switch msg := msg.(type) {
// TODO: Define your msg cases
//
//Example:
// case Msg<Action>:
// return handleMsg<Action>(ctx, k, msg)
case MsgCreateArticle:
return handleMsgCreateArticle(ctx, k, msg)
case MsgCreateComment:
return handleMsgCreateComment(ctx, k, msg)
case MsgCreateReturnVisit:
return handleMsgCreateReturnVisit(ctx, k, msg)
case MsgCreateAVote:
return handleMsgCreateAVote(ctx, k, msg)
case MsgCreateCVote:
return handleMsgCreateCVote(ctx, k, msg)
default:
errMsg := fmt.Sprintf("unrecognized %s message type: %T", ModuleName, msg)
return nil, sdkerrors.Wrap(sdkerrors.ErrUnknownRequest, errMsg)
}
}
}
// handleMsgCreateArticle creates a new article and moves the reward into escrow
func handleMsgCreateArticle(ctx sdk.Context, k Keeper, msg MsgCreateArticle) (*sdk.Result, error) {
var article = types.Article{
Creator: msg.Creator,
A_text: msg.A_text,
A_title: msg.A_title,
Tag: msg.Tag,
Article_id: msg.Article_id,
Tid: msg.Tid,
Uid: msg.Uid,
A_timestamp: msg.A_timestamp,
Reward: msg.Reward,
}
_, err := k.GetArticle(ctx, article.Article_id)
if err == nil {
return nil, sdkerrors.Wrap(err, "Article with that hash already exists")
}
moduleAcct := sdk.AccAddress(crypto.AddressHash([]byte(types.ModuleName)))
sdkError := k.CoinKeeper.SendCoins(ctx, article.Creator, moduleAcct, article.Reward)
if sdkError != nil {
return nil, sdkError
}
k.SetArticle(ctx, article)
ctx.EventManager().EmitEvent(
sdk.NewEvent(
sdk.EventTypeMessage,
sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory),
sdk.NewAttribute(sdk.AttributeKeyAction, types.EventTypeCreateArticle),
sdk.NewAttribute(sdk.AttributeKeySender, msg.Creator.String()),
sdk.NewAttribute(types.AttributeText, msg.A_text),
sdk.NewAttribute(types.AttributeA_title, msg.A_title),
sdk.NewAttribute(types.AttributeTag, msg.Tag),
sdk.NewAttribute(types.AttributeArticle_id, msg.Article_id),
sdk.NewAttribute(types.AttributeTid, msg.Tid),
sdk.NewAttribute(types.AttributeUid, msg.Uid),
sdk.NewAttribute(types.AttributeA_timestamp, msg.A_timestamp),
sdk.NewAttribute(types.AttributeReward, msg.Reward.String()),
),
)
return &sdk.Result{Events: ctx.EventManager().Events()}, nil
}
func handleMsgCreateComment(ctx sdk.Context, k Keeper, msg MsgCreateComment) (*sdk.Result, error) {
var comment = types.Comment{
Creator: msg.Creator,
Comment_id: msg.Comment_id,
Article_id: msg.Article_id,
Tid: msg.Tid,
Uid: msg.Uid,
C_timestamp: msg.C_timestamp,
C_text: msg.C_text,
Reward: msg.Reward,
}
_, err := k.GetComment(ctx, comment.Comment_id)
if err == nil {
return nil, sdkerrors.Wrap(err, "Comment with that id already exists")
}
moduleAcct := sdk.AccAddress(crypto.AddressHash([]byte(types.ModuleName)))
sdkError := k.CoinKeeper.SendCoins(ctx, comment.Creator, moduleAcct, comment.Reward)
if sdkError != nil {
return nil, sdkError
}
k.SetComment(ctx, comment)
ctx.EventManager().EmitEvent(
sdk.NewEvent(
sdk.EventTypeMessage,
sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory),
sdk.NewAttribute(sdk.AttributeKeyAction, types.EventTypeCreateComment),
sdk.NewAttribute(sdk.AttributeKeySender, msg.Creator.String()),
sdk.NewAttribute(types.AttributeReward, msg.Reward.String()),
),
)
return &sdk.Result{Events: ctx.EventManager().Events()}, nil
}
func handleMsgCreateReturnVisit(ctx sdk.Context, k Keeper, msg MsgCreateReturnVisit) (*sdk.Result, error) {
var rv = types.ReturnVisit{
Creator: msg.Creator,
Return_visit_id: msg.Return_visit_id,
Article_id: msg.Article_id,
Tid: msg.Tid,
Uid: msg.Uid,
Rv_timestamp: msg.Rv_timestamp,
Rv_text: msg.Rv_text,
Flag: msg.Flag,
Reward: msg.Reward,
}
_, err := k.GetReturnVisit(ctx, rv.Return_visit_id)
if err == nil {
return nil, sdkerrors.Wrap(err, "Rv with that id already exists")
}
moduleAcct := sdk.AccAddress(crypto.AddressHash([]byte(types.ModuleName)))
sdkError := k.CoinKeeper.SendCoins(ctx, rv.Creator, moduleAcct, rv.Reward)
if sdkError != nil {
return nil, sdkError
}
k.SetReturnVisit(ctx, rv)
ctx.EventManager().EmitEvent(
sdk.NewEvent(
sdk.EventTypeMessage,
sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory),
sdk.NewAttribute(sdk.AttributeKeyAction, types.EventTypeCreateReturnVisit),
sdk.NewAttribute(sdk.AttributeKeySender, msg.Creator.String()),
sdk.NewAttribute(types.AttributeReward, msg.Reward.String()),
),
)
return &sdk.Result{Events: ctx.EventManager().Events()}, nil
}
func handleMsgCreateAVote(ctx sdk.Context, k Keeper, msg MsgCreateAVote) (*sdk.Result, error) {
var aVote = types.ArticleVote{
Creator: msg.Creator,
Article_id: msg.Article_id,
VoteUP: msg.VoteUP,
VoteDOWN: msg.VoteDOWN,
Num: msg.Num,
}
_, err := k.GetAVote(ctx, aVote.Article_id)
if err == nil {
return nil, sdkerrors.Wrap(err, "Rv with that id already exists")
}
k.SetAVote(ctx, aVote)
ctx.EventManager().EmitEvent(
sdk.NewEvent(
sdk.EventTypeMessage,
sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory),
sdk.NewAttribute(sdk.AttributeKeyAction, types.EventTypeCreateAVote),
sdk.NewAttribute(sdk.AttributeKeySender, msg.Creator.String()),
),
)
return &sdk.Result{Events: ctx.EventManager().Events()}, nil
}
func handleMsgCreateCVote(ctx sdk.Context, k Keeper, msg MsgCreateCVote) (*sdk.Result, error) {
var cVote = types.CommentVote{
Creator: msg.Creator,
Comment_id: msg.Comment_id,
VoteUP: msg.VoteUP,
VoteDOWN: msg.VoteDOWN,
Num: msg.Num,
}
_, err := k.GetCVote(ctx, cVote.Comment_id)
if err == nil {
return nil, sdkerrors.Wrap(err, "Rv with that id already exists")
}
k.SetCVote(ctx, cVote)
ctx.EventManager().EmitEvent(
sdk.NewEvent(
sdk.EventTypeMessage,
sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory),
sdk.NewAttribute(sdk.AttributeKeyAction, types.EventTypeCreateCVote),
sdk.NewAttribute(sdk.AttributeKeySender, msg.Creator.String()),
),
)
return &sdk.Result{Events: ctx.EventManager().Events()}, nil
}
/*// handde<Action> does x
func handleMsg<Action>(ctx sdk.Context, k Keeper, msg Msg<Action>) (*sdk.Result, error) {
err := k.<Action>(ctx, msg.ValidatorAddr)
if err != nil {
return nil, err
}
// TODO: Define your msg events
ctx.EventManager().EmitEvent(
sdk.NewEvent(
sdk.EventTypeMessage,
sdk.NewAttribute(sdk.AttributeKeyModule, AttributeValueCategory),
sdk.NewAttribute(sdk.AttributeKeySender, msg.ValidatorAddr.String()),
),
)
return &sdk.Result{Events: ctx.EventManager().Events()}, nil
}
*/

View File

@ -0,0 +1,178 @@
package keeper
import (
"fmt"
/* "github.com/tendermint/tendermint/crypto"*/
"github.com/tendermint/tendermint/libs/log"
"github.com/cosmos/cosmos-sdk/codec"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/bank"
"github.com/changtong1996/djzh/x/djzh/internal/types"
)
// Keeper of the djzh store
type Keeper struct {
CoinKeeper bank.Keeper
storeKey sdk.StoreKey
cdc *codec.Codec
}
// NewKeeper creates a djzh keeper
func NewKeeper(coinKeeper bank.Keeper, key sdk.StoreKey, cdc *codec.Codec) Keeper {
keeper := Keeper{
CoinKeeper: coinKeeper,
storeKey: key,
cdc: cdc,
}
return keeper
}
// Logger returns a module-specific logger.
func (k Keeper) Logger(ctx sdk.Context) log.Logger {
return ctx.Logger().With("module", fmt.Sprintf("x/%s", types.ModuleName))
}
func (k Keeper) GetArticle(ctx sdk.Context, article_id string) (types.Article, error) {
store := ctx.KVStore(k.storeKey)
var article types.Article
byteKey := []byte(article_id)
err := k.cdc.UnmarshalBinaryLengthPrefixed(store.Get(byteKey), &article)
if err != nil {
return article, err
}
return article, nil
}
func (k Keeper) SetArticle(ctx sdk.Context, article types.Article ) {
article_id := article.Article_id
store := ctx.KVStore(k.storeKey)
bz := k.cdc.MustMarshalBinaryLengthPrefixed(article)
key := []byte(article_id)
store.Set(key, bz)
}
func (k Keeper) DeleteArticle(ctx sdk.Context, article_id string) {
store := ctx.KVStore(k.storeKey)
store.Delete([]byte(article_id))
}
func (k Keeper) GetComment(ctx sdk.Context, comment_id string) (types.Comment, error) {
store := ctx.KVStore(k.storeKey)
var comment types.Comment
byteKey := []byte(comment_id)
err := k.cdc.UnmarshalBinaryLengthPrefixed(store.Get(byteKey), &comment)
if err != nil {
return comment, err
}
return comment, nil
}
func (k Keeper) SetComment(ctx sdk.Context, comment types.Comment ) {
comment_id := comment.Comment_id
store := ctx.KVStore(k.storeKey)
bz := k.cdc.MustMarshalBinaryLengthPrefixed(comment)
key := []byte(comment_id)
store.Set(key, bz)
}
func (k Keeper) DeleteComment(ctx sdk.Context, comment_id string) {
store := ctx.KVStore(k.storeKey)
store.Delete([]byte(comment_id))
}
// Get returns the pubkey from the adddress-pubkey relation
func (k Keeper) GetReturnVisit(ctx sdk.Context, return_visit_id string) (types.ReturnVisit, error) {
store := ctx.KVStore(k.storeKey)
var rv types.ReturnVisit
byteKey := []byte(return_visit_id)
err := k.cdc.UnmarshalBinaryLengthPrefixed(store.Get(byteKey), &rv)
if err != nil {
return rv, err
}
return rv, nil
}
func (k Keeper) SetReturnVisit(ctx sdk.Context, rv types.ReturnVisit ) {
return_visit_id := rv.Return_visit_id
store := ctx.KVStore(k.storeKey)
bz := k.cdc.MustMarshalBinaryLengthPrefixed(rv)
key := []byte(return_visit_id)
store.Set(key, bz)
}
func (k Keeper) DeleteReturnVisit(ctx sdk.Context, return_visit_id string) {
store := ctx.KVStore(k.storeKey)
store.Delete([]byte(return_visit_id))
}
// Get returns the pubkey from the adddress-pubkey relation
func (k Keeper) GetAVote(ctx sdk.Context, article_id string) (types.ArticleVote, error) {
store := ctx.KVStore(k.storeKey)
var aVote types.ArticleVote
byteKey := []byte(article_id)
err := k.cdc.UnmarshalBinaryLengthPrefixed(store.Get(byteKey), &aVote)
if err != nil {
return aVote, err
}
return aVote, nil
}
func (k Keeper) SetAVote(ctx sdk.Context, aVote types.ArticleVote ) {
article_id := aVote.Article_id
store := ctx.KVStore(k.storeKey)
bz := k.cdc.MustMarshalBinaryLengthPrefixed(aVote)
key := []byte(article_id)
store.Set(key, bz)
}
func (k Keeper) DeleteAVote(ctx sdk.Context, article_id string) {
store := ctx.KVStore(k.storeKey)
store.Delete([]byte(article_id))
}
// Get returns the pubkey from the adddress-pubkey relation
func (k Keeper) GetCVote(ctx sdk.Context, comment_id string) (types.CommentVote, error) {
store := ctx.KVStore(k.storeKey)
var cVote types.CommentVote
byteKey := []byte(comment_id)
err := k.cdc.UnmarshalBinaryLengthPrefixed(store.Get(byteKey), &cVote)
if err != nil {
return cVote, err
}
return cVote, nil
}
func (k Keeper) SetCVote(ctx sdk.Context, cVote types.CommentVote ) {
comment_id := cVote.Comment_id
store := ctx.KVStore(k.storeKey)
bz := k.cdc.MustMarshalBinaryLengthPrefixed(cVote)
key := []byte(comment_id)
store.Set(key, bz)
}
func (k Keeper) DeleteCVote(ctx sdk.Context, comment_id string) {
store := ctx.KVStore(k.storeKey)
store.Delete([]byte(comment_id))
}

View File

@ -0,0 +1,22 @@
package keeper
/*
// TODO: Define if your module needs Parameters, if not this can be deleted
import (
"time"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/changtong/djzh/x/djzh/internal/types"
)
// GetParams returns the total set of djzh parameters.
func (k Keeper) GetParams(ctx sdk.Context) (params types.Params) {
k.paramspace.GetParamSet(ctx, &params)
return params
}
// SetParams sets the djzh parameters to the param space.
func (k Keeper) SetParams(ctx sdk.Context, params types.Params) {
k.paramspace.SetParamSet(ctx, &params)
}
*/

View File

@ -0,0 +1,66 @@
package keeper
import (
/* "fmt"*/
abci "github.com/tendermint/tendermint/abci/types"
/* "github.com/cosmos/cosmos-sdk/client"*/
"github.com/cosmos/cosmos-sdk/codec"
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"/*
"github.com/changtong1996/djzh/x/djzh/internal/types"*/
)
const(
QueryVoteNum = "voteNum"
QueryGetArticle = "getarticle"//used in /cli/query.go QueryWithData
)
// NewQuerier creates a new querier for djzh clients.不太懂这个path的作用是什么
func NewQuerier(k Keeper) sdk.Querier {
return func(ctx sdk.Context, path []string, req abci.RequestQuery) ([]byte, error) {
switch path[0] {
case QueryVoteNum:
return queryVoteNum(ctx, k, path[1:])
case QueryGetArticle:
return queryGetArticle(ctx, k, path[1:])
// TODO: Put the modules query routes
default:
return nil, sdkerrors.Wrap(sdkerrors.ErrUnknownRequest, "unknown djzh query endpoint")
}
}
}
func queryVoteNum(ctx sdk.Context, k Keeper, path []string) ([]byte, error) {
voteNum, err := k.GetAVote(ctx, path[0])
if err != nil {
return nil, err
}
res, err := codec.MarshalJSONIndent(k.cdc, voteNum)
if err != nil {
return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error())
}
return res, nil
}
func queryGetArticle(ctx sdk.Context, k Keeper, path []string) ([]byte, error) {
article, err := k.GetArticle(ctx, path[0])
if err != nil {
return nil, err
}
res, err := codec.MarshalJSONIndent(k.cdc, article)
if err != nil {
return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error())
}
return res, nil
}
// TODO: Add the modules query functions
// They will be similar to the above one: queryParams()

View File

@ -0,0 +1,25 @@
package types
import (
"github.com/cosmos/cosmos-sdk/codec"
)
// RegisterCodec registers concrete types on codec
func RegisterCodec(cdc *codec.Codec) {
// TODO: Register the modules msgs
cdc.RegisterConcrete(MsgCreateArticle{}, "djzh/MsgCreateArticle", nil)
cdc.RegisterConcrete(MsgCreateComment{}, "djzh/MsgCreateComment", nil)
cdc.RegisterConcrete(MsgCreateReturnVisit{}, "djzh/MsgCreateReturnVisit", nil)
cdc.RegisterConcrete(MsgCreateAVote{}, "djzh/MsgCreateAVote", nil)
cdc.RegisterConcrete(MsgCreateCVote{}, "djzh/MsgCreateCVote", nil)
}
// ModuleCdc defines the module codec
var ModuleCdc *codec.Codec
func init() {
ModuleCdc = codec.New()
RegisterCodec(ModuleCdc)
codec.RegisterCrypto(ModuleCdc)
ModuleCdc.Seal()
}

View File

@ -0,0 +1,11 @@
package types
/*import (
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
)*/
// TODO: Fill out some custom errors for the module
// You can see how they are constructed below:
// var (
// ErrInvalid = sdkerrors.Register(ModuleName, 1, "custom error message")
// )

View File

@ -0,0 +1,31 @@
package types
// djzh module event types
const (
// TODO: Create your event types
// EventType<Action> = "action"
// TODO: Create keys fo your events, the values will be derivided from the msg
// AttributeKeyAddress = "address"
// TODO: Some events may not have values for that reason you want to emit that something happened.
// AttributeValueDoubleSign = "double_sign"
EventTypeCreateArticle = "CreateArticle"
EventTypeCreateComment = "CreateComment"
EventTypeCreateReturnVisit = "CreateReturnVisit"
EventTypeCreateAVote = "CreateAVote"
EventTypeCreateCVote = "CreateCVote"
AttributeText = "a_text"
AttributeA_title = "a_title"
AttributeTag = "tag"
AttributeArticle_id = "article_id"
AttributeTid = "tid"
AttributeUid = "uid"
AttributeA_timestamp = "a_timestamp"
AttributeReward = "reward"
AttributeValueCategory = ModuleName
)

View File

@ -0,0 +1,24 @@
package types
import (
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/params"
)
// ParamSubspace defines the expected Subspace interfacace
type ParamSubspace interface {
WithKeyTable(table params.KeyTable) params.Subspace
Get(ctx sdk.Context, key []byte, ptr interface{})
GetParamSet(ctx sdk.Context, ps params.ParamSet)
SetParamSet(ctx sdk.Context, ps params.ParamSet)
}
/*
When a module wishes to interact with an otehr module it is good practice to define what it will use
as an interface so the module can not use things that are not permitted.
TODO: Create interfaces of what you expect the other keepers to have to be able to use this module.
type BankKeeper interface {
SubtractCoins(ctx sdk.Context, addr sdk.AccAddress, amt sdk.Coins) (sdk.Coins, error)
SendCoins(ctx sdk.Context, fromAddr sdk.AccAddress, toAddr sdk.AccAddress, amt sdk.Coins) error
}
*/

View File

@ -0,0 +1,26 @@
package types
// GenesisState - all djzh state that must be provided at genesis
type GenesisState struct {
// TODO: Fill out what is needed by the module for genesis
}
// NewGenesisState creates a new GenesisState object
func NewGenesisState( /* TODO: Fill out with what is needed for genesis state */) GenesisState {
return GenesisState{
// TODO: Fill out according to your genesis state
}
}
// DefaultGenesisState - default GenesisState used by Cosmos Hub
func DefaultGenesisState() GenesisState {
return GenesisState{
// TODO: Fill out according to your genesis state, these values will be initialized but empty
}
}
// ValidateGenesis validates the djzh genesis parameters
func ValidateGenesis(data GenesisState) error {
// TODO: Create a sanity check to make sure the state conforms to the modules needs
return nil
}

View File

@ -0,0 +1,15 @@
package types
const (
// ModuleName is the name of the module
ModuleName = "djzh"
// StoreKey to be used when creating the KVStore
StoreKey = ModuleName
// RouterKey to be used for routing msgs
RouterKey = ModuleName
// QuerierRoute to be used for querierer msgs
QuerierRoute = ModuleName
)

View File

@ -0,0 +1,322 @@
package types
import (
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
)
type MsgCreateArticle struct {
Creator sdk.AccAddress `json:"creator"` // address of the article creator
A_text string `json:"a_text"` //
A_title string `json:"a_title"`
Tag string `json:"tag"`
Article_id string `json:"article_id"`
Tid string `json:"tid"`
Uid string `json:"uid"`
A_timestamp string `json:"a_timestamp"`
Reward sdk.Coins `json:"reward"` // reward of the article
}
func NewMsgCreateArticle(creator sdk.AccAddress, a_text string, a_title string, tag string, article_id string,
tid string, uid string, a_timestamp string, reward sdk.Coins) MsgCreateArticle {
return MsgCreateArticle{
Creator: creator,
A_text: a_text,
A_title: a_title,
Tag: tag,
Article_id: article_id,
Tid: tid,
Uid: uid,
A_timestamp: a_timestamp,
Reward: reward,
}
}
const CreateArticleConst = "CreateArticle"
//nolint
func (msg MsgCreateArticle) Route() string { return RouterKey }
func (msg MsgCreateArticle) Type() string { return CreateArticleConst }
func (msg MsgCreateArticle) GetSigners() []sdk.AccAddress{
return []sdk.AccAddress{sdk.AccAddress(msg.Creator)}
}
func (msg MsgCreateArticle) GetSignBytes() []byte {
bz := ModuleCdc.MustMarshalJSON(msg)
return sdk.MustSortJSON(bz)
}
// ValidateBasic validity check for the AnteHandler
func (msg MsgCreateArticle) ValidateBasic() error {
if msg.Creator.Empty() {
return sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, "creator can't be empty")
}
if msg.Article_id == "" {
return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "articleid can't be empty")
}
return nil
}
type MsgCreateComment struct {
Creator sdk.AccAddress `json:"creator"` // address of the article creator
Comment_id string `json:"comment_id"` // id of the comment
Article_id string `json:"article_id"` // id of the article
Tid string `json:"tid"` // id of the transaction
Uid string `json:"uid"` // id of the user
C_timestamp string `json:"c_timestamp"` // timestamp of the comment
C_text string `json:"c_text"` // context of the comment
Reward sdk.Coins `json:"reward"`
}
func NewMsgCreateComment(creator sdk.AccAddress, comment_id string, article_id string, tid string, uid string,
c_timestamp string, c_text string, reward sdk.Coins) MsgCreateComment {
return MsgCreateComment{
Creator: creator,
Comment_id: comment_id,
Article_id: article_id,
Tid: tid,
Uid: uid,
C_timestamp: c_timestamp,
C_text: c_text,
Reward: reward,
}
}
const CreateCommentConst = "CreateComment"
//nolint
func (msg MsgCreateComment) Route() string { return RouterKey }
func (msg MsgCreateComment) Type() string { return CreateCommentConst }
func (msg MsgCreateComment) GetSigners() []sdk.AccAddress{
return []sdk.AccAddress{sdk.AccAddress(msg.Creator)}
}
func (msg MsgCreateComment) GetSignBytes() []byte {
bz := ModuleCdc.MustMarshalJSON(msg)
return sdk.MustSortJSON(bz)
}
// ValidateBasic validity check for the AnteHandler
func (msg MsgCreateComment) ValidateBasic() error {
if msg.Creator.Empty() {
return sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, "creator can't be empty")
}
if msg.Comment_id == "" {
return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "solutionScavengerHash can't be empty")
}
return nil
}
type MsgCreateReturnVisit struct {
Creator sdk.AccAddress `json:"creator"` // address of the article creator
Return_visit_id string `json:"return_visit_id"`
Article_id string `json:"article_id"`
Tid string `json:"tid"`
Uid string `json:"uid"`
Rv_timestamp string `json:"rv_timestamp"`
Rv_text string `json:"rv_text"`
Flag string `json:"flag"`
Reward sdk.Coins `json:"reward"` // reward of the article
}
func NewMsgCreateReturnVisit(creator sdk.AccAddress, return_visit_id string, article_id string, tid string, uid string,
rv_timestamp string, rv_text string, flag string, reward sdk.Coins) MsgCreateReturnVisit {
return MsgCreateReturnVisit{
Creator: creator,
Return_visit_id: return_visit_id,
Article_id: article_id,
Tid: tid,
Uid: uid,
Rv_timestamp: rv_timestamp,
Rv_text: rv_text,
Flag: flag,
Reward: reward,
}
}
const CreateReturnVisitConst = "CreateReturnVisit"
//nolint
func (msg MsgCreateReturnVisit) Route() string { return RouterKey }
func (msg MsgCreateReturnVisit) Type() string { return CreateReturnVisitConst }
func (msg MsgCreateReturnVisit) GetSigners() []sdk.AccAddress{
return []sdk.AccAddress{sdk.AccAddress(msg.Creator)}
}
func (msg MsgCreateReturnVisit) GetSignBytes() []byte {
bz := ModuleCdc.MustMarshalJSON(msg)
return sdk.MustSortJSON(bz)
}
// ValidateBasic validity check for the AnteHandler
func (msg MsgCreateReturnVisit) ValidateBasic() error {
if msg.Creator.Empty() {
return sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, "creator can't be empty")
}
if msg.Return_visit_id == "" {
return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "rv can't be empty")
}
return nil
}
type MsgCreateAVote struct {
Creator sdk.AccAddress `json:"creator"` // address of the article creator
Article_id string `json:"article_id"` // id of the article
VoteUP int `json:"voteUP"`
VoteDOWN int `json:"voteDOWN"`
Num int `json:"num"`
}
func NewMsgCreateAVote(creator sdk.AccAddress, article_id string, voteUP int, voteDOWN int, num int) MsgCreateAVote {
return MsgCreateAVote{
Creator: creator,
Article_id: article_id,
VoteUP: voteUP,
VoteDOWN: voteDOWN,
Num: num,
}
}
const CreateAVoteConst = "CreateAVote"
//nolint
func (msg MsgCreateAVote) Route() string { return RouterKey }
func (msg MsgCreateAVote) Type() string { return CreateAVoteConst }
func (msg MsgCreateAVote) GetSigners() []sdk.AccAddress{
return []sdk.AccAddress{sdk.AccAddress(msg.Creator)}
}
func (msg MsgCreateAVote) GetSignBytes() []byte {
bz := ModuleCdc.MustMarshalJSON(msg)
return sdk.MustSortJSON(bz)
}
// ValidateBasic validity check for the AnteHandler
func (msg MsgCreateAVote) ValidateBasic() error {
if msg.Creator.Empty() {
return sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, "creator can't be empty")
}
if msg.Article_id == "" {
return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "solutionScavengerHash can't be empty")
}
return nil
}
type MsgCreateCVote struct {
Creator sdk.AccAddress `json:"creator"` // address of the article creator
Comment_id string `json:"comment_id"` // id of the article
VoteUP int `json:"voteUP"`
VoteDOWN int `json:"voteDOWN"`
Num int `json:"num"`
}
func NewMsgCreateCVote(creator sdk.AccAddress, comment_id string, voteUP int, voteDOWN int, num int) MsgCreateCVote {
return MsgCreateCVote{
Creator: creator,
Comment_id: comment_id,
VoteUP: voteUP,
VoteDOWN: voteDOWN,
Num: num,
}
}
const CreateCVoteConst = "CreateCVote"
//nolint
func (msg MsgCreateCVote) Route() string { return RouterKey }
func (msg MsgCreateCVote) Type() string { return CreateCVoteConst }
func (msg MsgCreateCVote) GetSigners() []sdk.AccAddress{
return []sdk.AccAddress{sdk.AccAddress(msg.Creator)}
}
func (msg MsgCreateCVote) GetSignBytes() []byte {
bz := ModuleCdc.MustMarshalJSON(msg)
return sdk.MustSortJSON(bz)
}
// ValidateBasic validity check for the AnteHandler
func (msg MsgCreateCVote) ValidateBasic() error {
if msg.Creator.Empty() {
return sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, "creator can't be empty")
}
if msg.Comment_id == "" {
return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "comment_id can't be empty")
}
return nil
}
// TODO: Describe your actions, these will implment the interface of `sdk.Msg`
/*
verify interface at compile time
var _ sdk.Msg = &Msg<Action>{}
Msg<Action> - struct for unjailing jailed validator
type Msg<Action> struct {
ValidatorAddr sdk.ValAddress `json:"address" yaml:"address"` // address of the validator operator
}
NewMsg<Action> creates a new Msg<Action> instance
func NewMsg<Action>(validatorAddr sdk.ValAddress) Msg<Action> {
return Msg<Action>{
ValidatorAddr: validatorAddr,
}
}
const <action>Const = "<action>"
// nolint
func (msg Msg<Action>) Route() string { return RouterKey }
func (msg Msg<Action>) Type() string { return <action>Const }
func (msg Msg<Action>) GetSigners() []sdk.AccAddress {
return []sdk.AccAddress{sdk.AccAddress(msg.ValidatorAddr)}
}
GetSignBytes gets the bytes for the message signer to sign on
func (msg Msg<Action>) GetSignBytes() []byte {
bz := ModuleCdc.MustMarshalJSON(msg)
return sdk.MustSortJSON(bz)
}
ValidateBasic validity check for the AnteHandler
func (msg Msg<Action>) ValidateBasic() error {
if msg.ValidatorAddr.Empty() {
return sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, "missing validator address"
}
return nil
}
*/

View File

@ -0,0 +1,57 @@
package types
import (
"fmt"
"github.com/cosmos/cosmos-sdk/x/params"
)
// Default parameter namespace
const (
DefaultParamspace = ModuleName
// TODO: Define your default parameters
)
// Parameter store keys
var (
// TODO: Define your keys for the parameter store
// KeyParamName = []byte("ParamName")
)
// ParamKeyTable for djzh module
func ParamKeyTable() params.KeyTable {
return params.NewKeyTable().RegisterParamSet(&Params{})
}
// Params - used for initializing default parameter for djzh at genesis
type Params struct {
// TODO: Add your Paramaters to the Paramter struct
// KeyParamName string `json:"key_param_name"`
}
// NewParams creates a new Params object
func NewParams(/* TODO: Pass in the paramters*/) Params {
return Params{
// TODO: Create your Params Type
}
}
// String implements the stringer interface for Params
func (p Params) String() string {
return fmt.Sprintf(`
// TODO: Return all the params as a string
`, )
}
// ParamSetPairs - Implements params.ParamSet
func (p *Params) ParamSetPairs() params.ParamSetPairs {
return params.ParamSetPairs{
// TODO: Pair your key with the param
// params.NewParamSetPair(KeyParamName, &p.ParamName),
}
}
// DefaultParams defines the parameters for this module
func DefaultParams() Params {
return NewParams( /* TODO: Pass in your default Params */ )
}

View File

@ -0,0 +1,19 @@
package types
/*import "strings"*/
// Query endpoints supported by the djzh querier
const (
// TODO: Describe query parameters, update <action> with your query
// Query<Action> = "<action>"
)
// QueryResList Queries Result Payload for a query
/*type QueryVoteNum []string
// implement fmt.Stringer
func (n QueryVoteNum) String() string {
return strings.Join(n[:], "\n")
}
*/

View File

@ -0,0 +1,117 @@
package types
import (
"fmt"
"strings"
sdk "github.com/cosmos/cosmos-sdk/types"
)
type Article struct {
Creator sdk.AccAddress `json:"creator"`
Article_id string `json:"article_id"` // id of the article
Uid string `json:"uid"` // id of the user
Tid string `json:"tid"` // id of the transaction
A_timestamp string `json:"a_timestamp"` // timestamp of the article
A_title string `json:"a_title"` // title of the article
A_text string `json:"a_text"` // text of the article
Tag string `json:"tag"`
Flag int `json:"flag"`
Reward sdk.Coins `json:"reward"`
}
func (a Article) String() string {
return strings.TrimSpace(fmt.Sprintf(`Creator: %s
Article_id: %s
Uid: %s
Tid: %s
A_timestamp: %s
A_title: %s
A_text: %s
Tag: %s
Flag: %d
Reward:%s`,
a.Creator,
a.Article_id,
a.Uid,
a.Tid,
a.A_timestamp,
a.A_title,
a.A_text,
a.Tag,
a.Flag,
a.Reward,
))
}
type ArticleVote struct {
Creator sdk.AccAddress `json:"creator"`
Article_id string `json:"article_id"` // id of the article
VoteUP int `json:"voteUP"`
VoteDOWN int `json:"voteDOWN"`
Num int `json:"num"`
}
type Comment struct {
Creator sdk.AccAddress `json:"creator"`
Comment_id string `json:"comment_id"` // id of the comment
Article_id string `json:"article_id"` // id of the article
Tid string `json:"tid"` // id of the transaction
Uid string `json:"uid"` // id of the user
C_timestamp string `json:"c_timestamp"` // timestamp of the comment
C_text string `json:"c_text"` // context of the comment
Flag int `json:"flag"`
Reward sdk.Coins `json:"reward"`
}
type CommentVote struct {
Creator sdk.AccAddress `json:"creator"`
Comment_id string `json:"comment_id"` // id of the comment
VoteUP int `json:"voteUP"`
VoteDOWN int `json:"voteDOWN"`
Num int `json:"num"`
}
type Domain struct {
Domainn string `json:"domain"` //
Ip string `json:"ip"`
Owner string `json:"owner"`
Suffix string `json:"suffix"`
}
type Equity struct {
Uid string `json:"uid"`
Balance string `json:"balance"` // 股权资产数
Detail string `json:"detail"`
}
type EquityTransaction struct {
Et_id string `json:"et_id"`
Source_id string `json:"source_id"`
Destination_id string `json:"destination_id"`
Tid string `json:"tid"`
Balance string `json:"balance"`
Et_timestamp int `json:"et_timestamp"`
Detail string `json:"detail"`
}
type ReturnVisit struct{
Creator sdk.AccAddress `json:"creator"`
Return_visit_id string `json:"return_visit_id"`
Article_id string `json:"article_id"`
Tid string `json:"tid"`
Uid string `json:"uid"`
Rv_timestamp string `json:"rv_timestamp"`
Rv_text string `json:"rv_text"`
Flag string `json:"flag"`
Reward sdk.Coins `json:"reward"`
}

146
x/djzh/module.go Normal file
View File

@ -0,0 +1,146 @@
package djzh
import (
"encoding/json"
"github.com/gorilla/mux"
"github.com/spf13/cobra"
abci "github.com/tendermint/tendermint/abci/types"
"github.com/cosmos/cosmos-sdk/client/context"
"github.com/cosmos/cosmos-sdk/codec"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/module"
"github.com/cosmos/cosmos-sdk/x/bank"
/* "github.com/changtong1996/djzh/x/djzh/internal/types"*/
"github.com/changtong1996/djzh/x/djzh/client/cli"
"github.com/changtong1996/djzh/x/djzh/client/rest"
)
var (
_ module.AppModule = AppModule{}
_ module.AppModuleBasic = AppModuleBasic{}
)
// AppModuleBasic defines the basic application module used by the djzh module.
type AppModuleBasic struct{}
var _ module.AppModuleBasic = AppModuleBasic{}
// Name returns the djzh module's name.
func (AppModuleBasic) Name() string {
return ModuleName
}
// RegisterCodec registers the djzh module's types for the given codec.
func (AppModuleBasic) RegisterCodec(cdc *codec.Codec) {
RegisterCodec(cdc)
}
// DefaultGenesis returns default genesis state as raw bytes for the djzh
// module.
func (AppModuleBasic) DefaultGenesis() json.RawMessage {
return ModuleCdc.MustMarshalJSON(DefaultGenesisState())
}
// ValidateGenesis performs genesis state validation for the djzh module.
func (AppModuleBasic) ValidateGenesis(bz json.RawMessage) error {
var data GenesisState
err := ModuleCdc.UnmarshalJSON(bz, &data)
if err != nil {
return err
}
return ValidateGenesis(data)
}
// RegisterRESTRoutes registers the REST routes for the djzh module.
func (AppModuleBasic) RegisterRESTRoutes(ctx context.CLIContext, rtr *mux.Router) {
rest.RegisterRoutes(ctx, rtr)
}
// GetTxCmd returns the root tx command for the djzh module.
func (AppModuleBasic) GetTxCmd(cdc *codec.Codec) *cobra.Command {
return cli.GetTxCmd(cdc)
}
// GetQueryCmd returns no root query command for the djzh module.
func (AppModuleBasic) GetQueryCmd(cdc *codec.Codec) *cobra.Command {
return cli.GetQueryCmd(StoreKey, cdc)
}
//____________________________________________________________________________
// AppModule implements an application module for the djzh module.
type AppModule struct {
AppModuleBasic
keeper Keeper
// TODO: Add keepers that your application depends on
coinKeeper bank.Keeper
}
// NewAppModule creates a new AppModule object
func NewAppModule(k Keeper, bankKeeper bank.Keeper) AppModule {
return AppModule{
AppModuleBasic: AppModuleBasic{},
keeper: k,
// TODO: Add keepers that your application depends on
coinKeeper: bankKeeper,
}
}
// Name returns the djzh module's name.
func (AppModule) Name() string {
return ModuleName
}
// RegisterInvariants registers the djzh module invariants.
func (am AppModule) RegisterInvariants(_ sdk.InvariantRegistry) {}
// Route returns the message routing key for the djzh module.
func (AppModule) Route() string {
return RouterKey
}
// NewHandler returns an sdk.Handler for the djzh module.
func (am AppModule) NewHandler() sdk.Handler {
return NewHandler(am.keeper)
}
// QuerierRoute returns the djzh module's querier route name.
func (AppModule) QuerierRoute() string {
return QuerierRoute
}
// NewQuerierHandler returns the djzh module sdk.Querier.
func (am AppModule) NewQuerierHandler() sdk.Querier {
return NewQuerier(am.keeper)
}
// InitGenesis performs genesis initialization for the djzh module. It returns
// no validator updates.
func (am AppModule) InitGenesis(ctx sdk.Context, data json.RawMessage) []abci.ValidatorUpdate {
var genesisState GenesisState
ModuleCdc.MustUnmarshalJSON(data, &genesisState)
InitGenesis(ctx, am.keeper, genesisState)
return []abci.ValidatorUpdate{}
}
// ExportGenesis returns the exported genesis state as raw bytes for the djzh
// module.
func (am AppModule) ExportGenesis(ctx sdk.Context) json.RawMessage {
gs := ExportGenesis(ctx, am.keeper)
return ModuleCdc.MustMarshalJSON(gs)
}
// BeginBlock returns the begin blocker for the djzh module.
func (am AppModule) BeginBlock(ctx sdk.Context, req abci.RequestBeginBlock) {
BeginBlocker(ctx, req, am.keeper)
}
// EndBlock returns the end blocker for the djzh module. It returns no validator
// updates.
func (AppModule) EndBlock(_ sdk.Context, _ abci.RequestEndBlock) []abci.ValidatorUpdate {
return []abci.ValidatorUpdate{}
}

17
x/djzh/spec/README.md Normal file
View File

@ -0,0 +1,17 @@
# djzh module specification
## Abstract
<!-- TODO: Create a abstract definition of what this module does, what functionality does it enable and how it can be used. -->
## Contents
// TODO: Create the below files if they are needed.
1. **[Concepts](01_concepts.md)**
2. **[State](02_state.md)**
3. **[Messages](03_messages.md)**
4. **[Begin-Block](04_begin_block.md)**
5. **[End-Block](06_end_bloc.md)**
6. **[05_hooks](06_hooks.md)**
7. **[Events](07_events.md)**
8. **[Parameters](08_params.md)**