doc edits
go basics doc update exposed comment
This commit is contained in:
committed by
Ethan Buchman
parent
1d8f59644f
commit
c5f837c68e
@@ -8,17 +8,24 @@ import (
|
||||
"github.com/tendermint/basecoin/types"
|
||||
)
|
||||
|
||||
//Called during CLI initialization
|
||||
func init() {
|
||||
|
||||
//Register a plugin specific CLI command as a subcommand of the tx command
|
||||
commands.RegisterTxSubcommand(ExamplePluginTxCmd)
|
||||
|
||||
//Register the example with basecoin at start
|
||||
commands.RegisterStartPlugin("example-plugin", func() types.Plugin { return NewExamplePlugin() })
|
||||
}
|
||||
|
||||
var (
|
||||
//CLI Flags
|
||||
ExampleFlag = cli.BoolFlag{
|
||||
Name: "valid",
|
||||
Usage: "Set this to make the transaction valid",
|
||||
}
|
||||
|
||||
//CLI Plugin Commands
|
||||
ExamplePluginTxCmd = cli.Command{
|
||||
Name: "example",
|
||||
Usage: "Create, sign, and broadcast a transaction to the example plugin",
|
||||
@@ -29,8 +36,17 @@ var (
|
||||
}
|
||||
)
|
||||
|
||||
//Send a transaction
|
||||
func cmdExamplePluginTx(c *cli.Context) error {
|
||||
//Retrieve any flag results
|
||||
exampleFlag := c.Bool("valid")
|
||||
|
||||
//Create a transaction object with flag results
|
||||
exampleTx := ExamplePluginTx{exampleFlag}
|
||||
return commands.AppTx(c, "example-plugin", wire.BinaryBytes(exampleTx))
|
||||
|
||||
//Encode transaction bytes
|
||||
exampleTxBytes := wire.BinaryBytes(exampleTx)
|
||||
|
||||
//Send the transaction and return any errors
|
||||
return commands.AppTx(c, "example-plugin", exampleTxBytes)
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
//Initialize an instance of basecoin with default basecoin commands
|
||||
app := cli.NewApp()
|
||||
app.Name = "example-plugin"
|
||||
app.Usage = "example-plugin [command] [args...]"
|
||||
|
||||
@@ -6,46 +6,104 @@ import (
|
||||
"github.com/tendermint/go-wire"
|
||||
)
|
||||
|
||||
//-----------------------------------------
|
||||
// Structs
|
||||
// * Note the fields in each struct may be expanded/modified
|
||||
|
||||
// Plugin State Struct
|
||||
// * Intended to store the current state of the plugin
|
||||
// * This example contains a field which holds the execution count
|
||||
// * Used by go-wire as the encoding/decoding struct to hold the plugin state
|
||||
// * All fields must be exposed (for go-wire)
|
||||
// * The state is stored within the KVStore using the key retrieved
|
||||
// from the ExamplePlugin.StateKey() function
|
||||
type ExamplePluginState struct {
|
||||
Counter int
|
||||
}
|
||||
|
||||
// Transaction Struct
|
||||
// * Stores transaction-specific plugin-customized information
|
||||
// * This example contains a dummy field 'Valid' intended to specify
|
||||
// if the transaction is a valid and should proceed
|
||||
// * Used by go-wire as the encoding/decoding struct to pass transaction
|
||||
// * All fields must be exposed (for go-wire)
|
||||
// * Passed through txBytes in the RunTx func.
|
||||
type ExamplePluginTx struct {
|
||||
Valid bool
|
||||
}
|
||||
|
||||
// Plugin Struct
|
||||
// * Struct which satisfies the basecoin Plugin interface
|
||||
// * Stores global plugin settings, in this example just the plugin name
|
||||
type ExamplePlugin struct {
|
||||
name string
|
||||
}
|
||||
|
||||
func (ep *ExamplePlugin) Name() string {
|
||||
return ep.name
|
||||
}
|
||||
|
||||
func (ep *ExamplePlugin) StateKey() []byte {
|
||||
return []byte("ExamplePlugin.State")
|
||||
}
|
||||
//-----------------------------------------
|
||||
// Non-Mandatory Functions
|
||||
|
||||
// Return a new example plugin pointer with a hard-coded name. Within other
|
||||
// plugin implementations may choose to include other initialization
|
||||
// information to populate custom fields of your Plugin struct in this example
|
||||
// named ExamplePlugin
|
||||
func NewExamplePlugin() *ExamplePlugin {
|
||||
return &ExamplePlugin{
|
||||
name: "example-plugin",
|
||||
}
|
||||
}
|
||||
|
||||
// Return a byte array unique to this plugin which will be used as the key which
|
||||
// to store the plugin state (ExamplePluginState)
|
||||
func (ep *ExamplePlugin) StateKey() []byte {
|
||||
return []byte("ExamplePlugin.State")
|
||||
}
|
||||
|
||||
//-----------------------------------------
|
||||
// Basecoin Plugin Interface Functions
|
||||
|
||||
//Return the name of the plugin
|
||||
func (ep *ExamplePlugin) Name() string {
|
||||
return ep.name
|
||||
}
|
||||
|
||||
// SetOption may be called during genesis of basecoin and can be used to set
|
||||
// initial plugin parameters. Within genesis.json file entries are made in
|
||||
// the format: "<plugin>/<key>", "<value>" Where <plugin> is the plugin name,
|
||||
// in this file ExamplePlugin.name, and <key> and <value> are the strings passed
|
||||
// into the plugin SetOption function. This function is intended to be used to
|
||||
// set plugin specific information such as the plugin state. Within this example
|
||||
// SetOption is left unimplemented.
|
||||
func (ep *ExamplePlugin) SetOption(store types.KVStore, key string, value string) (log string) {
|
||||
return ""
|
||||
}
|
||||
|
||||
// The core tx logic of the app is containted within the RunTx function
|
||||
// Input fields:
|
||||
// - store types.KVStore
|
||||
// - This term provides read/write capabilities to the merkelized data store
|
||||
// which is accessible cross-plugin
|
||||
// - ctx types.CallContext
|
||||
// - The ctx contains the callers address, a pointer to the callers account,
|
||||
// and an amount of coins sent with the transaction
|
||||
// - txBytes []byte
|
||||
// - Used to send customized information from the basecoin
|
||||
// application to your plugin
|
||||
//
|
||||
// Other more complex plugins may have a variant on the process order within this
|
||||
// example including loading and saving multiple or variable states, or not
|
||||
// including a state stored in the KVStore whatsoever.
|
||||
func (ep *ExamplePlugin) RunTx(store types.KVStore, ctx types.CallContext, txBytes []byte) (res abci.Result) {
|
||||
|
||||
// Decode tx
|
||||
// Decode txBytes using go-wire. Attempt to write the txBytes to the variable
|
||||
// tx, if the txBytes have not been properly encoded from a ExamplePluginTx
|
||||
// struct wire will produce an error.
|
||||
var tx ExamplePluginTx
|
||||
err := wire.ReadBinaryBytes(txBytes, &tx)
|
||||
if err != nil {
|
||||
return abci.ErrBaseEncodingError.AppendLog("Error decoding tx: " + err.Error())
|
||||
}
|
||||
|
||||
// Validate tx
|
||||
// Perform Transaction Validation
|
||||
if !tx.Valid {
|
||||
return abci.ErrInternalError.AppendLog("Valid must be true")
|
||||
}
|
||||
@@ -53,8 +111,10 @@ func (ep *ExamplePlugin) RunTx(store types.KVStore, ctx types.CallContext, txByt
|
||||
// Load PluginState
|
||||
var pluginState ExamplePluginState
|
||||
stateBytes := store.Get(ep.StateKey())
|
||||
// If the state does not exist, stateBytes will be initialized
|
||||
// as an empty byte array with length of zero
|
||||
if len(stateBytes) > 0 {
|
||||
err = wire.ReadBinaryBytes(stateBytes, &pluginState)
|
||||
err = wire.ReadBinaryBytes(stateBytes, &pluginState) //decode using go-wire
|
||||
if err != nil {
|
||||
return abci.ErrInternalError.AppendLog("Error decoding state: " + err.Error())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user