diff --git a/docs/guides/guide.md b/docs/guides/guide.md deleted file mode 100644 index 21e8b70fe..000000000 --- a/docs/guides/guide.md +++ /dev/null @@ -1,464 +0,0 @@ -## Introduction - -If you want to see some examples, take a look at the [examples/basecoin](/examples/basecoin) directory. - -## Design Goals - -The design of the Cosmos SDK is based on the principles of "capabilities systems". - -## Capabilities systems - -### Need for module isolation -### Capability is implied permission -### TODO Link to thesis - -## Tx & Msg - -The SDK distinguishes between transactions (Tx) and messages -(Msg). A Tx is a list of Msgs wrapped with authentication and fee data. - -### Messages - -Users can create messages containing arbitrary information by -implementing the `Msg` interface: - -```go -type Msg interface { - - // Return the message type. - // Must be alphanumeric or empty. - Type() string - - // Get the canonical byte representation of the Msg. - GetSignBytes() []byte - - // ValidateBasic does a simple validation check that - // doesn't require access to any other information. - ValidateBasic() error - - // Signers returns the addrs of signers that must sign. - // CONTRACT: All signatures must be present to be valid. - // CONTRACT: Returns addrs in some deterministic order. - GetSigners() []Address -} - -``` - -Messages must specify their type via the `Type()` method. The type should -correspond to the messages handler, so there can be many messages with the same -type. - -Messages must also specify how they are to be authenticated. The `GetSigners()` -method return a list of addresses that must sign the message, while the -`GetSignBytes()` method returns the bytes that must be signed for a signature -to be valid. - -Addresses in the SDK are arbitrary byte arrays that are hex-encoded when -displayed as a string or rendered in JSON. - -Messages can specify basic self-consistency checks using the `ValidateBasic()` -method to enforce that message contents are well formed before any actual logic -begins. - -For instance, the `Basecoin` message types are defined in `x/bank/tx.go`: - -```go -type MsgSend struct { - Inputs []Input `json:"inputs"` - Outputs []Output `json:"outputs"` -} - -type MsgIssue struct { - Banker sdk.Address `json:"banker"` - Outputs []Output `json:"outputs"` -} -``` - -Each specifies the addresses that must sign the message: - -```go -func (msg MsgSend) GetSigners() []sdk.Address { - addrs := make([]sdk.Address, len(msg.Inputs)) - for i, in := range msg.Inputs { - addrs[i] = in.Address - } - return addrs -} - -func (msg MsgIssue) GetSigners() []sdk.Address { - return []sdk.Address{msg.Banker} -} -``` - -### Transactions - -A transaction is a list of messages with additional information for authentication: - -```go -type Tx interface { - - GetMsgs() Msg -} -``` - -The standard way to create a transaction from a message is to use the `StdTx` struct defined in the `x/auth` module. - -```go -type StdTx struct { - Msg sdk.Msg `json:"msg"` - Fee StdFee `json:"fee"` - Signatures []StdSignature `json:"signatures"` -} -``` - -The `StdTx.GetSignatures()` method returns a list of signatures, which must match -the list of addresses returned by `tx.Msg.GetSigners()`. The signatures come in -a standard form: - -```go -type StdSignature struct { - crypto.PubKey // optional - crypto.Signature - AccountNumber int64 - Sequence int64 -} -``` - -It contains the signature itself, as well as the corresponding account's -sequence number. The sequence number is expected to increment every time a -message is signed by a given account. This prevents "replay attacks", where -the same message could be executed over and over again. - -The `StdSignature` can also optionally include the public key for verifying the -signature. An application can store the public key for each address it knows -about, making it optional to include the public key in the transaction. In the -case of Basecoin, the public key only needs to be included in the first -transaction send by a given account - after that, the public key is forever -stored by the application and can be left out of transactions. - -The address responsible for paying the transactions fee is the first address -returned by msg.GetSigners(). The convenience function `FeePayer(tx Tx)` is provided -to return this. - -The standard bytes for signers to sign over is provided by: - -```go -func StdSignByes(chainID string, accnums []int64, sequences []int64, fee StdFee, msg sdk.Msg) []byte -``` - -in `x/auth`. The standard way to construct fees to pay for the processing of transactions is: - -```go -// StdFee includes the amount of coins paid in fees and the maximum -// gas to be used by the transaction. The ratio yields an effective "gasprice", -// which must be above some miminum to be accepted into the mempool. -type StdFee struct { - Amount sdk.Coins `json:"amount"` - Gas int64 `json:"gas"` -} -``` - -### Encoding and Decoding Transactions - -Messages and transactions are designed to be generic enough for developers to -specify their own encoding schemes. This enables the SDK to be used as the -framwork for constructing already specified cryptocurrency state machines, for -instance Ethereum. - -When initializing an application, a developer can specify a `TxDecoder` -function which determines how an arbitrary byte array should be unmarshalled -into a `Tx`: - -```go -type TxDecoder func(txBytes []byte) (Tx, error) -``` - -The default tx decoder is the Tendermint wire format which uses the go-amino library -for encoding and decoding all message types. - -In `Basecoin`, we use the default transaction decoder. The `go-amino` library has the nice -property that it can unmarshal into interface types, but it requires the -relevant types to be registered ahead of type. Registration happens on a -`Codec` object, so as not to taint the global name space. - -For instance, in `Basecoin`, we wish to register the `MsgSend` and `MsgIssue` -types: - -```go -cdc.RegisterInterface((*sdk.Msg)(nil), nil) -cdc.RegisterConcrete(bank.MsgSend{}, "cosmos-sdk/MsgSend", nil) -cdc.RegisterConcrete(bank.MsgIssue{}, "cosmos-sdk/MsgIssue", nil) -``` - -Note how each concrete type is given a name - these name determine the type's -unique "prefix bytes" during encoding. A registered type will always use the -same prefix-bytes, regardless of what interface it is satisfying. For more -details, see the [go-amino documentation](https://github.com/tendermint/go-amino/blob/develop). - -If you wish to use a custom encoding scheme, you must define a TxDecoder function -and set it as the decoder in your extended baseapp using the `SetTxDecoder(decoder sdk.TxDecoder)`. - -Ex: - -```go -app.SetTxDecoder(CustomTxDecodeFn) -``` - -## Storage - -### MultiStore - -MultiStore is like a root filesystem of an operating system, except -all the entries are fully Merkleized. You mount onto a MultiStore -any number of Stores. Currently only KVStores are supported, but in -the future we may support more kinds of stores, such as a HeapStore -or a NDStore for multidimensional storage. - -The MultiStore as well as all mounted stores provide caching (aka -cache-wrapping) for intermediate state (aka software transactional -memory) during the execution of transactions. In the case of the -KVStore, this also works for iterators. For example, after running -the app's AnteHandler, the MultiStore is cache-wrapped (and each -store is also cache-wrapped) so that should processing of the -transaction fail, at least the transaction fees are paid and -sequence incremented. - -The MultiStore as well as all stores support (or will support) -historical state pruning and snapshotting and various kinds of -queries with proofs. - -### KVStore - -Here we'll focus on the IAVLStore, which is a kind of KVStore. - -IAVLStore is a fast balanced dynamic Merkle store that also supports -iteration, and of course cache-wrapping, state pruning, and various -queries with proofs, such as proofs of existence, absence, range, -and so on. - -Here's how you mount them to a MultiStore. - -```go -mainDB, catDB := dbm.NewMemDB(), dbm.NewMemDB() -fooKey := sdk.NewKVStoreKey("foo") -barKey := sdk.NewKVStoreKey("bar") -catKey := sdk.NewKVStoreKey("cat") -ms := NewCommitMultiStore(mainDB) -ms.MountStoreWithDB(fooKey, sdk.StoreTypeIAVL, nil) -ms.MountStoreWithDB(barKey, sdk.StoreTypeIAVL, nil) -ms.MountStoreWithDB(catKey, sdk.StoreTypeIAVL, catDB) -``` - -In the example above, all IAVL nodes (inner and leaf) will be stored -in mainDB with the prefix of "s/k:foo/" and "s/k:bar/" respectively, -thus sharing the mainDB. All IAVL nodes (inner and leaf) for the -cat KVStore are stored separately in catDB with the prefix of -"s/\_/". The "s/k:KEY/" and "s/\_/" prefixes are there to -disambiguate store items from other items of non-storage concern. - - -## Context - -The SDK uses a `Context` to propogate common information across functions. The -`Context` is modeled after the Golang `context.Context` object, which has -become ubiquitous in networking middleware and routing applications as a means -to easily propogate request context through handler functions. - -The main information stored in the `Context` includes the application -MultiStore (see below), the last block header, and the transaction bytes. -Effectively, the context contains all data that may be necessary for processing -a transaction. - -Many methods on SDK objects receive a context as the first argument. - -## Handler - -Message processing in the SDK is defined through `Handler` functions: - -```go -type Handler func(ctx Context, msg Msg) Result -``` - -A handler takes a context and a message and returns a result. All -information necessary for processing a message should be available in the -context. - -While the context holds the entire application state (all referenced from the -root MultiStore), a particular handler only needs a particular kind of access -to a particular store (or two or more). Access to stores is managed using -capabilities keys and mappers. When a handler is initialized, it is passed a -key or mapper that gives it access to the relevant stores. - -```go -// File: cosmos-sdk/examples/basecoin/app/init_stores.go -app.BaseApp.MountStore(app.capKeyMainStore, sdk.StoreTypeIAVL) -app.accountMapper = auth.NewAccountMapper( - app.capKeyMainStore, // target store - &types.AppAccount{}, // prototype -) - -// File: cosmos-sdk/examples/basecoin/app/init_handlers.go -app.router.AddRoute("bank", bank.NewHandler(app.accountMapper)) - -// File: cosmos-sdk/x/bank/handler.go -// NOTE: Technically, NewHandler only needs a CoinMapper -func NewHandler(am sdk.AccountMapper) sdk.Handler { - return func(ctx sdk.Context, msg sdk.Msg) sdk.Result { - cm := CoinMapper{am} - ... - } -} -``` - -## AnteHandler - -The AnteHandler is used to do all transaction-level processing (i.e. Fee payment, signature verification) -before passing the message to its respective handler. - -```go -type AnteHandler func(ctx Context, tx Tx) (newCtx Context, result Result, abort bool) -``` - -The antehandler takes a Context and a transaction and returns a new Context, a Result, and the abort boolean. -As with the handler, all information necessary for processing a message should be available in the -context. - -If the transaction fails, then the application should not waste time processing the message. Thus, the antehandler should -return an Error's Result method and set the abort boolean to `true` so that the application knows not to process the message in a handler. - -Most applications can use the provided antehandler implementation in `x/auth` which handles signature verification -as well as collecting fees. - -Note: Signatures must be over `auth.StdSignDoc` introduced above to use the provided antehandler. - -```go -// File: cosmos-sdk/examples/basecoin/app/app.go -app.SetAnteHandler(auth.NewAnteHandler(app.accountMapper, app.feeCollectionKeeper)) -``` - -### Handling Fee payment -### Handling Authentication - -The antehandler is responsible for handling all authentication of a transaction before passing the message onto its handler. -This generally involves signature verification. The antehandler should check that all of the addresses that are returned in -`tx.GetMsg().GetSigners()` signed the message and that they signed over `tx.GetMsg().GetSignBytes()`. - -## Accounts and x/auth - -### auth.Account - -```go -// Account is a standard account using a sequence number for replay protection -// and a pubkey for authentication. -type Account interface { - GetAddress() sdk.Address - SetAddress(sdk.Address) error // errors if already set. - - GetPubKey() crypto.PubKey // can return nil. - SetPubKey(crypto.PubKey) error - - GetAccountNumber() int64 - SetAccountNumber(int64) error - - GetSequence() int64 - SetSequence(int64) error - - GetCoins() sdk.Coins - SetCoins(sdk.Coins) error -} -``` - -Accounts are the standard way for an application to keep track of addresses and their associated balances. - -### auth.BaseAccount - -```go -// BaseAccount - base account structure. -// Extend this by embedding this in your AppAccount. -// See the examples/basecoin/types/account.go for an example. -type BaseAccount struct { - Address sdk.Address `json:"address"` - Coins sdk.Coins `json:"coins"` - PubKey crypto.PubKey `json:"public_key"` - AccountNumber int64 `json:"account_number"` - Sequence int64 `json:"sequence"` -} -``` - -The `auth.BaseAccount` struct provides a standard implementation of the Account interface with replay protection. -BaseAccount can be extended by embedding it in your own Account struct. - -### auth.AccountMapper - -```go -// This AccountMapper encodes/decodes accounts using the -// go-amino (binary) encoding/decoding library. -type AccountMapper struct { - - // The (unexposed) key used to access the store from the Context. - key sdk.StoreKey - - // The prototypical Account concrete type. - proto Account - - // The wire codec for binary encoding/decoding of accounts. - cdc *wire.Codec -} -``` - -The AccountMapper is responsible for managing and storing the state of all accounts in the application. - -Example Initialization: - -```go -// File: examples/basecoin/app/app.go -// Define the accountMapper. -app.accountMapper = auth.NewAccountMapper( - cdc, - app.keyAccount, // target store - &types.AppAccount{}, // prototype -) -``` - -The accountMapper allows you to retrieve the current account state by `GetAccount(ctx Context, addr auth.Address)` and change the state by -`SetAccount(ctx Context, acc Account)`. - -Note: To update an account you will first have to get the account, update the appropriate fields with its associated setter method, and then call -`SetAccount(ctx Context, acc updatedAccount)`. - -Updating accounts is made easier by using the `Keeper` struct in the `x/bank` module. - -Example Initialization: - -```go -// File: examples/basecoin/app/app.go -app.coinKeeper = bank.NewKeeper(app.accountMapper) -``` - -Example Usage: - -```go -// Finds account with addr in accountmapper -// Adds coins to account's coin array -// Sets updated account in accountmapper -app.coinKeeper.AddCoins(ctx, addr, coins) -``` - -## Wire codec - -### Why another codec? -### vs encoding/json -### vs protobuf - -## KVStore example - -## Basecoin example - -The quintessential SDK application is Basecoin - a simple -multi-asset cryptocurrency. Basecoin consists of a set of -accounts stored in a Merkle tree, where each account may have -many coins. There are two message types: MsgSend and MsgIssue. -MsgSend allows coins to be sent around, while MsgIssue allows a -set of predefined users to issue new coins. - -## Conclusion diff --git a/docs/guides/sdk/README.md b/docs/guides/sdk/README.md new file mode 100644 index 000000000..2986bc4b9 --- /dev/null +++ b/docs/guides/sdk/README.md @@ -0,0 +1,3 @@ +DEPRECATED + +See the [docs](/docs/sdk) diff --git a/docs/guides/sdk/apps.md b/docs/guides/sdk/apps.md index 01210cb66..442c1c889 100644 --- a/docs/guides/sdk/apps.md +++ b/docs/guides/sdk/apps.md @@ -1,70 +1,2 @@ -# Apps in the SDK +[Moved](/docs/sdk/overview/apps.md) -The SDK has multiple levels of "application": the ABCI app, the BaseApp, the BasecoinApp, and now your App. - -## ABCI App - -The basic ABCI interface allowing Tendermint to drive the applications state machine with transaction blocks. - -## BaseApp - -Implements an ABCI App using a MultiStore for persistence and a Router to handle transactions. -The goal is to provide a secure interface between the store and the extensible state machine -while defining as little about that state machine as possible (staying true to the ABCI). - -BaseApp requires stores to be mounted via capabilities keys - handlers can only access -stores they're given the key for. The BaseApp ensures all stores are properly loaded, cached, and committed. -One mounted store is considered the "main" - it holds the latest block header, from which we can find and load the -most recent state ([TODO](https://github.com/cosmos/cosmos-sdk/issues/522)). - -BaseApp distinguishes between two handler types - the `AnteHandler` and the `MsgHandler`. -The former is a global validity check (checking nonces, sigs and sufficient balances to pay fees, -e.g. things that apply to all transaction from all modules), the later is the full state transition function. -During CheckTx the state transition function is only applied to the checkTxState and should return -before any expensive state transitions are run (this is up to each developer). It also needs to return the estimated -gas cost. -During DeliverTx the state transition function is applied to the blockchain state and the transactions -need to be fully executed. - -BaseApp is responsible for managing the context passed into handlers - -it makes the block header available and provides the right stores for CheckTx and DeliverTx. - -BaseApp is completely agnostic to serialization formats. - -## Basecoin - -Basecoin is the first complete application in the stack. -Complete applications require extensions to the core modules of the SDK to actually implement handler functionality. -The native extensions of the SDK, useful for building Cosmos Zones, live under `x`. -Basecoin implements a `BaseApp` state machine using the `x/auth` and `x/bank` extensions, -which define how transaction signers are authenticated and how coins are transferred. -It should also use `x/ibc` and probably a simple staking extension. - -Basecoin and the native `x` extensions use go-amino for all serialization needs, -including for transactions and accounts. - -## Your Cosmos App - -Your Cosmos App is a fork of Basecoin - copy the `examples/basecoin` directory and modify it to your needs. -You might want to: - -- add fields to accounts -- copy and modify handlers -- add new handlers for new transaction types -- add new stores for better isolation across handlers - -The Cosmos Hub takes Basecoin and adds more stores and extensions to handle additional -transaction types and logic, like the advanced staking logic and the governance process. - -## Ethermint - -Ethermint is a new implementation of `BaseApp` that does not depend on Basecoin. -Instead of `cosmos-sdk/x/` it has its own `ethermint/x` based on `go-ethereum`. - -Ethermint uses a Patricia store for its accounts, and an IAVL store for IBC. -It has `x/ante`, which is quite similar to Basecoin's but uses RLP instead of go-amino. -Instead of `x/bank`, it has `x/eth`, which defines the single Ethereum transaction type -and all the semantics of the Ethereum state machine. - -Within `x/eth`, transactions sent to particular addresses can be handled in unique ways, -for instance to handle IBC and staking. diff --git a/docs/guides/sdk/install.md b/docs/guides/sdk/install.md index bafdfc4bd..9b72e7a96 100644 --- a/docs/guides/sdk/install.md +++ b/docs/guides/sdk/install.md @@ -1,59 +1 @@ -# Install - -The fastest and easiest way to install the Cosmos SDK binaries -is to run [this script](https://github.com/cosmos/cosmos-sdk/blob/develop/scripts/install_sdk_ubuntu.sh) on a fresh Ubuntu instance. Similarly, you can run [this script](https://github.com/cosmos/cosmos-sdk/blob/develop/scripts/install_sdk_bsd.sh) on a fresh FreeBSD instance. Read the scripts before running them to ensure no untrusted connection is being made, for example we're making curl requests to download golang. Also read the comments / instructions carefully (i.e., reset your terminal after running the script). - -Cosmos SDK can be installed to -`$GOPATH/src/github.com/cosmos/cosmos-sdk` like a normal Go program: - -``` -go get github.com/cosmos/cosmos-sdk -``` - -If the dependencies have been updated with breaking changes, or if -another branch is required, `dep` is used for dependency management. -Thus, assuming you've already run `go get` or otherwise cloned the repo, -the correct way to install is: - -``` -cd $GOPATH/src/github.com/cosmos/cosmos-sdk -make get_tools -make get_vendor_deps -make install -make install_examples -``` - -This will install `gaiad` and `gaiacli` and four example binaries: -`basecoind`, `basecli`, `democoind`, and `democli`. - -Verify that everything is OK by running: - -``` -gaiad version -``` - -you should see: - -``` -0.17.3-a5a78eb -``` - -then with: - -``` -gaiacli version -``` -you should see the same version (or a later one for both). - -## Update - -Get latest code (you can also `git fetch` only the version desired), -ensure the dependencies are up to date, then recompile. - -``` -cd $GOPATH/src/github.com/cosmos/cosmos-sdk -git fetch -a origin -git checkout VERSION -make get_vendor_deps -make install -``` +[Moved](/docs/sdk/install.md) diff --git a/docs/guides/sdk/key-management.md b/docs/guides/sdk/key-management.md index 1474989b9..3620760f7 100644 --- a/docs/guides/sdk/key-management.md +++ b/docs/guides/sdk/key-management.md @@ -1,7 +1 @@ -# Key Management - -Here we cover many aspects of handling keys within the Cosmos SDK -framework. - -// TODO add relevant key discussion -(related https://github.com/tendermint/tendermint/blob/master/docs/spec/blockchain/encoding.md#public-key-cryptography) +[Moved](/docs/sdk/clients/key-management.md) diff --git a/docs/guides/sdk/lcd-rest-api.yaml b/docs/guides/sdk/lcd-rest-api.yaml index a39b7bf08..5af0fa249 100644 --- a/docs/guides/sdk/lcd-rest-api.yaml +++ b/docs/guides/sdk/lcd-rest-api.yaml @@ -1,781 +1 @@ -swagger: '2.0' -info: - version: '1.1.0' - title: Light client daemon to interface with Cosmos baseserver via REST - description: Specification for the LCD provided by `gaiacli advanced rest-server` - - -securityDefinitions: - kms: - type: basic - -paths: - /version: - get: - summary: Version of the light client daemon - description: Get the version of the LCD running locally to compare against expected - responses: - 200: - description: Plaintext version i.e. "v0.5.0" - /node_version: - get: - summary: Version of the connected node - description: Get the version of the SDK running on the connected node to compare against expected - responses: - 200: - description: Plaintext version i.e. "v0.5.0" - /node_info: - get: - description: Only the node info. Block information can be queried via /block/latest - summary: The propertied of the connected node - produces: - - application/json - responses: - 200: - description: Node status - schema: - type: object - properties: - pub_key: - $ref: '#/definitions/PubKey' - moniker: - type: string - example: 159.89.198.221 - network: - type: string - example: gaia-2 - remote_addr: - type: string - listen_addr: - type: string - example: 192.168.56.1:26656 - version: - description: Tendermint version - type: string - example: 0.15.0 - other: - description: more information on versions - type: array - items: - type: string - /syncing: - get: - summary: Syncing state of node - description: Get if the node is currently syning with other nodes - responses: - 200: - description: '"true" or "false"' - - /keys: - get: - summary: List of accounts stored locally - produces: - - application/json - responses: - 200: - description: Array of accounts - schema: - type: array - items: - $ref: '#/definitions/Account' - post: - summary: Create a new account locally - consumes: - - application/json - parameters: - - in: body - name: account - description: The account to create - schema: - type: object - required: - - name - - password - - seed - properties: - name: - type: string - password: - type: string - seed: - type: string - responses: - 200: - description: Returns address of the account created - /keys/seed: - get: - summary: Create a new seed to create a new account with - produces: - - application/json - responses: - 200: - description: 16 word Seed - schema: - type: string - /keys/{name}: - parameters: - - in: path - name: name - description: Account name - required: true - type: string - get: - summary: Get a certain locally stored account - produces: - - application/json - responses: - 200: - description: Locally stored account - schema: - $ref: "#/definitions/Account" - 404: - description: Account is not available - put: - summary: Update the password for this account in the KMS - consumes: - - application/json - parameters: - - in: body - name: account - description: The new and old password - schema: - type: object - required: - - new_password - - old_password - properties: - new_password: - type: string - old_password: - type: string - responses: - 200: - description: Updated password - 401: - description: Password is wrong - 404: - description: Account is not available - delete: - summary: Remove an account - consumes: - - application/json - parameters: - - in: body - name: account - description: The password of the account to remove from the KMS - schema: - type: object - required: - - password - properties: - password: - type: string - responses: - 200: - description: Removed account - 401: - description: Password is wrong - 404: - description: Account is not available -# /accounts/send: - # post: - # summary: Send coins (build -> sign -> send) - # security: - # - sign: [] - # requestBody: - # content: - # application/json: - # schema: - # type: object - # properties: - # fees: - # $ref: "#/definitions/Coins" - # outputs: - # type: array - # items: - # type: object - # properties: - # pub_key: - # $ref: "#/definitions/PubKey" - # amount: - # type: array - # items: - # $ref: "#/definitions/Coins" - # responses: - # 202: - # description: Tx was send and will probably be added to the next block - # 400: - # description: The Tx was malformated - - /accounts/{address}: - parameters: - - in: path - name: address - description: Account address in bech32 format - required: true - type: string - get: - summary: Get the account balances - produces: - - application/json - responses: - 200: - description: Account balances - schema: - $ref: "#/definitions/Balance" - 204: - description: There is no data for the requested account. This is not a 404 as the account might exist, just does not hold data. - /accounts/{address}/send: - parameters: - - in: path - name: address - description: Account address in bech32 format - required: true - type: string - post: - summary: Send coins (build -> sign -> send) - security: - - kms: [] - consumes: - - application/json - parameters: - - in: body - name: account - description: The password of the account to remove from the KMS - schema: - type: object - properties: - name: - type: string - password: - type: string - amount: - type: array - items: - $ref: "#/definitions/Coins" - chain_id: - type: string - squence: - type: number - responses: - 202: - description: Tx was send and will probably be added to the next block - 400: - description: The Tx was malformated - /blocks/latest: - get: - summary: Get the latest block - produces: - - application/json - responses: - 200: - description: The latest block - schema: - $ref: "#/definitions/Block" - /blocks/{height}: - parameters: - - in: path - name: height - description: Block height - required: true - type: number - get: - summary: Get a block at a certain height - produces: - - application/json - responses: - 200: - description: The block at a specific height - schema: - $ref: "#/definitions/Block" - 404: - description: Block at height is not available - /validatorsets/latest: - get: - summary: Get the latest validator set - produces: - - application/json - responses: - 200: - description: The validator set at the latest block height - schema: - type: object - properties: - block_height: - type: number - validators: - type: array - items: - $ref: "#/definitions/Validator" - /validatorsets/{height}: - parameters: - - in: path - name: height - description: Block height - required: true - type: number - get: - summary: Get a validator set a certain height - produces: - - application/json - responses: - 200: - description: The validator set at a specific block height - schema: - type: object - properties: - block_height: - type: number - validators: - type: array - items: - $ref: "#/definitions/Validator" - 404: - description: Block at height not available - # /txs: - # parameters: - # - in: query - # name: tag - # schema: - # type: string - # example: "coin.sender=EE5F3404034C524501629B56E0DDC38FAD651F04" - # required: true - # - in: query - # name: page - # description: Pagination page - # schema: - # type: number - # default: 0 - # - in: query - # name: size - # description: Pagination size - # schema: - # type: number - # default: 50 - # get: - # summary: Query Tx - # responses: - # 200: - # description: All Tx matching the provided tags - # content: - # application/json: - # schema: - # type: array - # items: - # $ref: "#/definitions/Tx" - # 404: - # description: Pagination is out of bounds - # /txs/sign: - # post: - # summary: Sign a Tx - # description: Sign a Tx providing locally stored account and according password - # security: - # - sign: [] - # requestBody: - # content: - # application/json: - # schema: - # $ref: "#/definitions/TxBuild" - # responses: - # 200: - # description: The signed Tx - # content: - # application/json: - # schema: - # $ref: "#/definitions/TxSigned" - # 401: - # description: Account name and/or password where wrong - # /txs/broadcast: - # post: - # summary: Send signed Tx - # requestBody: - # content: - # application/json: - # schema: - # $ref: "#/definitions/TxSigned" - # responses: - # 202: - # description: Tx was send and will probably be added to the next block - # 400: - # description: The Tx was malformated - /txs/{hash}: - parameters: - - in: path - name: hash - description: Tx hash - required: true - type: string - get: - summary: Get a Tx by hash - produces: - - application/json - responses: - 200: - description: Tx with the provided hash - schema: - $ref: "#/definitions/Tx" - 404: - description: Tx not available for provided hash - # /delegates: - # parameters: - # - in: query - # name: delegator - # description: Query for all delegates a delegator has stake with - # schema: - # $ref: "#/definitions/Address" - # get: - # summary: Get a list of canidates/delegates/validators (optionally filtered by delegator) - # responses: - # 200: - # description: List of delegates, filtered by provided delegator address - # content: - # application/json: - # schema: - # type: array - # items: - # $ref: "#/definitions/Delegate" - # /delegates/bond: - # post: - # summary: Bond atoms (build -> sign -> send) - # security: - # - sign: [] - # requestBody: - # content: - # application/json: - # schema: - # type: array - # items: - # type: object - # properties: - # amount: - # $ref: "#/definitions/Coins" - # pub_key: - # $ref: "#/definitions/PubKey" - # responses: - # 202: - # description: Tx was send and will probably be added to the next block - # 400: - # description: The Tx was malformated - # /delegates/unbond: - # post: - # summary: Unbond atoms (build -> sign -> send) - # security: - # - sign: [] - # requestBody: - # content: - # application/json: - # schema: - # type: array - # items: - # type: object - # properties: - # amount: - # $ref: "#/definitions/Coins" - # pub_key: - # $ref: "#/definitions/PubKey" - # responses: - # 202: - # description: Tx was send and will probably be added to the next block - # 400: - # description: The Tx was malformated - # /delegates/{pubkey}: - # parameters: - # - in: path - # name: pubkey - # description: Pubkey of a delegate - # required: true - # schema: - # type: string - # example: 81B11E717789600CC192B26F452A983DF13B985EE75ABD9DD9E68D7BA007A958 - # get: - # summary: Get a certain canidate/delegate/validator - # responses: - # 200: - # description: Delegate for specified pub_key - # content: - # application/json: - # schema: - # $ref: "#/definitions/Delegate" - # 404: - # description: No delegate found for provided pub_key - # /delegates/{pubkey}/bond: - # parameters: - # - in: path - # name: pubkey - # description: Pubkey of a delegate - # required: true - # schema: - # type: string - # example: 81B11E717789600CC192B26F452A983DF13B985EE75ABD9DD9E68D7BA007A958 - # post: - # summary: Bond atoms (build -> sign -> send) - # security: - # - sign: [] - # requestBody: - # content: - # application/json: - # schema: - # type: object - # properties: - # amount: - # $ref: "#/definitions/Coins" - # responses: - # 202: - # description: Tx was send and will probably be added to the next block - # 400: - # description: The Tx was malformated - # /delegates/{pubkey}/unbond: - # parameters: - # - in: path - # name: pubkey - # description: Pubkey of a delegate - # required: true - # schema: - # type: string - # example: 81B11E717789600CC192B26F452A983DF13B985EE75ABD9DD9E68D7BA007A958 - # post: - # summary: Unbond atoms (build -> sign -> send) - # security: - # - sign: [] - # requestBody: - # content: - # application/json: - # schema: - # type: object - # properties: - # amount: - # $ref: "#/definitions/Coins" - # responses: - # 202: - # description: Tx was send and will probably be added to the next block - # 400: - # description: The Tx was malformated - -definitions: - Address: - type: string - description: bech32 encoded addres - example: cosmosaccaddr:zgnkwr7eyyv643dllwfpdwensmgdtz89yu73zq - ValidatorAddress: - type: string - description: bech32 encoded addres - example: cosmosvaladdr:zgnkwr7eyyv643dllwfpdwensmgdtz89yu73zq - PubKey: - type: string - description: bech32 encoded public key - example: cosmosaccpub:zgnkwr7eyyv643dllwfpdwensmgdtz89yu73zq - ValidatorPubKey: - type: string - description: bech32 encoded public key - example: cosmosvalpub:zgnkwr7eyyv643dllwfpdwensmgdtz89yu73zq - Coins: - type: object - properties: - denom: - type: string - example: steak - amount: - type: number - example: 50 - Hash: - type: string - example: EE5F3404034C524501629B56E0DDC38FAD651F04 - Tx: - type: object - properties: - type: - type: string - enum: - - stake/delegate - data: - type: object - TxChain: - type: object - properties: - type: - type: string - default: chain/tx - data: - type: object - properties: - chain_id: - type: string - example: gaia-2 - expires_at: - type: number - example: 0 - tx: - type: object - properties: - type: - type: string - default: nonce - data: - type: object - properties: - sequence: - type: number - example: 0 - signers: - type: array - items: - type: object - properties: - chain: - type: string - example: '' - app: - type: string - default: sigs - addr: - $ref: "#/definitions/Address" - tx: - $ref: "#/definitions/Tx" - TxBuild: - type: object - properties: - type: - type: string - default: sigs/one - data: - type: object - properties: - tx: - $ref: "#/definitions/Tx" - signature: - type: object - properties: - Sig: - type: string - default: '' - Pubkey: - type: string - default: '' - TxSigned: - type: object - properties: - type: - type: string - default: sigs/one - data: - type: object - properties: - tx: - $ref: "#/definitions/Tx" - signature: - type: object - properties: - Sig: - type: string - example: 81B11E717789600CC192B26F452A983DF13B985EE75ABD9DD9E68D7BA007A958 - Pubkey: - $ref: "#/definitions/PubKey" - Account: - type: object - properties: - name: - type: string - example: Main Account - address: - $ref: "#/definitions/Address" - pub_key: - $ref: "#/definitions/PubKey" - Balance: - type: object - properties: - height: - type: number - example: 123456 - coins: - type: array - items: - $ref: "#/definitions/Coins" - credit: - type: array - items: - type: object - BlockID: - type: object - properties: - hash: - $ref: "#/definitions/Hash" - parts: - type: object - properties: - total: - type: number - example: 0 - hash: - $ref: "#/definitions/Hash" - Block: - type: object - properties: - header: - type: object - properties: - chain_id: - type: string - example: gaia-2 - height: - type: number - example: 1 - time: - type: string - example: '2017-12-30T05:53:09.287+01:00' - num_txs: - type: number - example: 0 - last_block_id: - $ref: "#/definitions/BlockID" - total_txs: - type: number - example: 35 - last_commit_hash: - $ref: "#/definitions/Hash" - data_hash: - $ref: "#/definitions/Hash" - validators_hash: - $ref: "#/definitions/Hash" - consensus_hash: - $ref: "#/definitions/Hash" - app_hash: - $ref: "#/definitions/Hash" - last_results_hash: - $ref: "#/definitions/Hash" - evidence_hash: - $ref: "#/definitions/Hash" - txs: - type: array - items: - $ref: "#/definitions/Tx" - evidence: - type: array - items: - type: object - last_commit: - type: object - properties: - blockID: - $ref: "#/definitions/BlockID" - precommits: - type: array - items: - type: object - Validator: - type: object - properties: - address: - $ref: '#/definitions/ValidatorAddress' - pub_key: - $ref: "#/definitions/ValidatorPubKey" - power: - type: number - example: 1000 - accum: - type: number - example: 1000 -# Added by API Auto Mocking Plugin -host: virtserver.swaggerhub.com -basePath: /faboweb1/Cosmos-LCD-2/1.0.0 -schemes: - - https +[Moved](/docs/sdk/clients/lcd-rest-api.yaml) diff --git a/docs/guides/sdk/overview.rst b/docs/guides/sdk/overview.rst index 0cb7e7304..c7a9adc6d 100644 --- a/docs/guides/sdk/overview.rst +++ b/docs/guides/sdk/overview.rst @@ -1,420 +1 @@ -Overview -======== - -The SDK design optimizes flexibility and security. The -framework is designed around a modular execution stack which allows -applications to mix and match elements as desired. In addition, -all modules are sandboxed for greater application security. - -Framework Overview ------------------- - -Object-Capability Model -~~~~~~~~~~~~~~~~~~~~~~~ - -When thinking about security, it's good to start with a specific threat model. Our threat model is the following: - -:: - - We assume that a thriving ecosystem of Cosmos-SDK modules that are easy to compose into a blockchain application will contain faulty or malicious modules. - -The Cosmos-SDK is designed to address this threat by being the foundation of an object capability system. - -:: - - The structural properties of object capability systems favor - modularity in code design and ensure reliable encapsulation in - code implementation. - - These structural properties facilitate the analysis of some - security properties of an object-capability program or operating - system. Some of these — in particular, information flow properties - — can be analyzed at the level of object references and - connectivity, independent of any knowledge or analysis of the code - that determines the behavior of the objects. As a consequence, - these security properties can be established and maintained in the - presence of new objects that contain unknown and possibly - malicious code. - - These structural properties stem from the two rules governing - access to existing objects: - - 1) An object A can send a message to B only if object A holds a - reference to B. - - 2) An object A can obtain a reference to C only - if object A receives a message containing a reference to C. As a - consequence of these two rules, an object can obtain a reference - to another object only through a preexisting chain of references. - In short, "Only connectivity begets connectivity." - -See the `wikipedia article `__ for more information. - -Strictly speaking, Golang does not implement object capabilities completely, because of several issues: - -* pervasive ability to import primitive modules (e.g. "unsafe", "os") -* pervasive ability to override module vars https://github.com/golang/go/issues/23161 -* data-race vulnerability where 2+ goroutines can create illegal interface values - -The first is easy to catch by auditing imports and using a proper dependency version control system like Dep. The second and third are unfortunate but it can be audited with some cost. - -Perhaps `Go2 will implement the object capability model `__. - -What does it look like? -^^^^^^^^^^^^^^^^^^^^^^^ - -Only reveal what is necessary to get the work done. - -For example, the following code snippet violates the object capabilities principle: - -:: - - type AppAccount struct {...} - var account := &AppAccount{ - Address: pub.Address(), - Coins: sdk.Coins{{"ATM", 100}}, - } - var sumValue := externalModule.ComputeSumValue(account) - -The method "ComputeSumValue" implies a pure function, yet the implied capability of accepting a pointer value is the capability to modify that value. The preferred method signature should take a copy instead. - -:: - - var sumValue := externalModule.ComputeSumValue(*account) - -In the Cosmos SDK, you can see the application of this principle in the basecoin examples folder. - -:: - - // File: cosmos-sdk/examples/basecoin/app/init_handlers.go - package app - - import ( - "github.com/cosmos/cosmos-sdk/x/bank" - "github.com/cosmos/cosmos-sdk/x/sketchy" - ) - - func (app *BasecoinApp) initRouterHandlers() { - - // All handlers must be added here. - // The order matters. - app.router.AddRoute("bank", bank.NewHandler(app.accountMapper)) - app.router.AddRoute("sketchy", sketchy.NewHandler()) - } - -In the Basecoin example, the sketchy handler isn't provided an account mapper, which does provide the bank handler with the capability (in conjunction with the context of a transaction run). - -Security Overview ------------------ - -For examples, see the `examples `__ directory. - -Design Goals -~~~~~~~~~~~~ - -The design of the Cosmos SDK is based on the principles of "capabilities systems". - -Capabilities systems -~~~~~~~~~~~~~~~~~~~~ - -TODO: - -* Need for module isolation -* Capability is implied permission -* Link to thesis - -Tx & Msg -~~~~~~~~ - -The SDK distinguishes between transactions (Tx) and messages -(Msg). A Tx is a Msg wrapped with authentication and fee data. - -Messages -^^^^^^^^ - -Users can create messages containing arbitrary information by -implementing the ``Msg`` interface: - -:: - - type Msg interface { - - // Return the message type. - // Must be alphanumeric or empty. - Type() string - - // Get the canonical byte representation of the Msg. - GetSignBytes() []byte - - // ValidateBasic does a simple validation check that - // doesn't require access to any other information. - ValidateBasic() error - - // Signers returns the addrs of signers that must sign. - // CONTRACT: All signatures must be present to be valid. - // CONTRACT: Returns addrs in some deterministic order. - GetSigners() []Address - } - -Messages must specify their type via the ``Type()`` method. The type should -correspond to the messages handler, so there can be many messages with the same -type. - -Messages must also specify how they are to be authenticated. The ``GetSigners()`` -method return a list of addresses that must sign the message, while the -``GetSignBytes()`` method returns the bytes that must be signed for a signature -to be valid. - -Addresses in the SDK are arbitrary byte arrays that are hex-encoded when -displayed as a string or rendered in JSON. - -Messages can specify basic self-consistency checks using the ``ValidateBasic()`` -method to enforce that message contents are well formed before any actual logic -begins. - -For instance, the ``Basecoin`` message types are defined in ``x/bank/tx.go``: - -:: - - type SendMsg struct { - Inputs []Input `json:"inputs"` - Outputs []Output `json:"outputs"` - } - - type IssueMsg struct { - Banker sdk.Address `json:"banker"` - Outputs []Output `json:"outputs"` - } - -Each specifies the addresses that must sign the message: - -:: - - func (msg SendMsg) GetSigners() []sdk.Address { - addrs := make([]sdk.Address, len(msg.Inputs)) - for i, in := range msg.Inputs { - addrs[i] = in.Address - } - return addrs - } - - func (msg IssueMsg) GetSigners() []sdk.Address { - return []sdk.Address{msg.Banker} - } - -Transactions -^^^^^^^^^^^^ - -A transaction is a message with additional information for authentication: - -:: - - type Tx interface { - - GetMsg() Msg - - // Signatures returns the signature of signers who signed the Msg. - // CONTRACT: Length returned is same as length of - // pubkeys returned from MsgKeySigners, and the order - // matches. - // CONTRACT: If the signature is missing (ie the Msg is - // invalid), then the corresponding signature is - // .Empty(). - GetSignatures() []StdSignature - } - -The ``tx.GetSignatures()`` method returns a list of signatures, which must match -the list of addresses returned by ``tx.Msg.GetSigners()``. The signatures come in -a standard form: - -:: - - type StdSignature struct { - crypto.PubKey // optional - crypto.Signature - AccountNumber int64 - Sequence int64 - } - -It contains the signature itself, as well as the corresponding account's account and -sequence numbers. The sequence number is expected to increment every time a -message is signed by a given account. The account number stays the same and is assigned -when the account is first generated. These prevent "replay attacks", where -the same message could be executed over and over again. - -The ``StdSignature`` can also optionally include the public key for verifying the -signature. An application can store the public key for each address it knows -about, making it optional to include the public key in the transaction. In the -case of Basecoin, the public key only needs to be included in the first -transaction send by a given account - after that, the public key is forever -stored by the application and can be left out of transactions. - -The standard way to create a transaction from a message is to use the ``StdTx``: - -:: - - type StdTx struct { - Msg - Signatures []StdSignature - } - -Encoding and Decoding Transactions -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Messages and transactions are designed to be generic enough for developers to -specify their own encoding schemes. This enables the SDK to be used as the -framwork for constructing already specified cryptocurrency state machines, for -instance Ethereum. - -When initializing an application, a developer must specify a ``TxDecoder`` -function which determines how an arbitrary byte array should be unmarshalled -into a ``Tx``: - -:: - - type TxDecoder func(txBytes []byte) (Tx, error) - -In ``Basecoin``, we use the Tendermint wire format and the ``go-amino`` library for -encoding and decoding all message types. The ``go-amino`` library has the nice -property that it can unmarshal into interface types, but it requires the -relevant types to be registered ahead of type. Registration happens on a -``Codec`` object, so as not to taint the global name space. - -For instance, in ``Basecoin``, we wish to register the ``SendMsg`` and ``IssueMsg`` -types: - -:: - - cdc.RegisterInterface((*sdk.Msg)(nil), nil) - cdc.RegisterConcrete(bank.SendMsg{}, "cosmos-sdk/SendMsg", nil) - cdc.RegisterConcrete(bank.IssueMsg{}, "cosmos-sdk/IssueMsg", nil) - -Note how each concrete type is given a name - these name determine the type's -unique "prefix bytes" during encoding. A registered type will always use the -same prefix-bytes, regardless of what interface it is satisfying. For more -details, see the `go-amino documentation `__. - - -MultiStore -~~~~~~~~~~ - -MultiStore is like a filesystem -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -Mounting an IAVLStore -^^^^^^^^^^^^^^^^^^^^^ - -TODO: - -* IAVLStore: Fast balanced dynamic Merkle store. - - * supports iteration. - -* MultiStore: multiple Merkle tree backends in a single store - - * allows using Ethereum Patricia Trie and Tendermint IAVL in same app - -* Provide caching for intermediate state during execution of blocks and transactions (including for iteration) -* Historical state pruning and snapshotting. -* Query proofs (existence, absence, range, etc.) on current and retained historical state. - -Context -------- - -The SDK uses a ``Context`` to propogate common information across functions. The -``Context`` is modelled after the Golang ``context.Context`` object, which has -become ubiquitous in networking middleware and routing applications as a means -to easily propogate request context through handler functions. - -The main information stored in the ``Context`` includes the application -MultiStore (see below), the last block header, and the transaction bytes. -Effectively, the context contains all data that may be necessary for processing -a transaction. - -Many methods on SDK objects receive a context as the first argument. - -Handler -------- - -Transaction processing in the SDK is defined through ``Handler`` functions: - -:: - - type Handler func(ctx Context, tx Tx) Result - -A handler takes a context and a transaction and returns a result. All -information necessary for processing a transaction should be available in the -context. - -While the context holds the entire application state (all referenced from the -root MultiStore), a particular handler only needs a particular kind of access -to a particular store (or two or more). Access to stores is managed using -capabilities keys and mappers. When a handler is initialized, it is passed a -key or mapper that gives it access to the relevant stores. - -:: - - // File: cosmos-sdk/examples/basecoin/app/init_stores.go - app.BaseApp.MountStore(app.capKeyMainStore, sdk.StoreTypeIAVL) - app.accountMapper = auth.NewAccountMapper( - app.capKeyMainStore, // target store - &types.AppAccount{}, // prototype - ) - - // File: cosmos-sdk/examples/basecoin/app/init_handlers.go - app.router.AddRoute("bank", bank.NewHandler(app.accountMapper)) - - // File: cosmos-sdk/x/bank/handler.go - // NOTE: Technically, NewHandler only needs a CoinMapper - func NewHandler(am sdk.AccountMapper) sdk.Handler { - return func(ctx sdk.Context, msg sdk.Msg) sdk.Result { - cm := CoinMapper{am} - ... - } - } - -AnteHandler ------------ - -Handling Fee payment -~~~~~~~~~~~~~~~~~~~~ - -Handling Authentication -~~~~~~~~~~~~~~~~~~~~~~~ - -Accounts and x/auth -------------------- - -sdk.Account -~~~~~~~~~~~ - -auth.BaseAccount -~~~~~~~~~~~~~~~~ - -auth.AccountMapper -~~~~~~~~~~~~~~~~~~ - -Wire codec ----------- - -Why another codec? -~~~~~~~~~~~~~~~~~~ - -vs encoding/json -~~~~~~~~~~~~~~~~ - -vs protobuf -~~~~~~~~~~~ - -KVStore example ---------------- - -Basecoin example ----------------- - -The quintessential SDK application is Basecoin - a simple -multi-asset cryptocurrency. Basecoin consists of a set of -accounts stored in a Merkle tree, where each account may have -many coins. There are two message types: SendMsg and IssueMsg. -SendMsg allows coins to be sent around, while IssueMsg allows a -set of predefined users to issue new coins. +[Moved](/docs/sdk)