cosmos-sdk/docs/staking/intro.rst

403 lines
11 KiB
ReStructuredText

Using The Staking Module
========================
This project is a demonstration of the Cosmos Hub staking functionality; it is
designed to get validator acquianted with staking concepts and procedures.
Potential validators will be declaring their candidacy, after which users can
delegate and, if they so wish, unbond. This can be practiced using a local or
public testnet.
This example covers initial setup of a two-node testnet between a server in the cloud and a local machine. Begin this tutorial from a cloud machine that you've ``ssh``'d into.
Install
-------
The ``gaiad`` and ``gaiacli`` binaries:
::
go get github.com/cosmos/cosmos-sdk
cd $GOPATH/src/github.com/cosmos/cosmos-sdk
make get_vendor_deps
make install
Let's jump right into it. First, we initialize some default files:
::
gaiad init
which will output:
::
I[03-30|11:20:13.365] Found private validator module=main path=/root/.gaiad/config/priv_validator.json
I[03-30|11:20:13.365] Found genesis file module=main path=/root/.gaiad/config/genesis.json
Secret phrase to access coins:
citizen hungry tennis noise park hire glory exercise link glow dolphin labor design grit apple abandon
This tell us we have a ``priv_validator.json`` and ``genesis.json`` in the ``~/.gaiad/config`` directory. A ``config.toml`` was also created in the same directory. It is a good idea to get familiar with those files. Write down the seed.
The next thing we'll need to is add the key from ``priv_validator.json`` to the ``gaiacli`` key manager. For this we need a seed and a password:
::
gaiacli keys add alice --recover
which will give you three prompts:
::
Enter a passphrase for your key:
Repeat the passphrase:
Enter your recovery seed phrase:
create a password and copy in your seed phrase. The name and address of the key will be output:
::
NAME: ADDRESS: PUBKEY:
alice 67997DD03D527EB439B7193F2B813B05B219CC02 1624DE6220BB89786C1D597050438C728202436552C6226AB67453CDB2A4D2703402FB52B6
You can see all available keys with:
::
gaiacli keys list
Setup Testnet
-------------
Next, we start the daemon (do this in another window):
::
gaiad start
and you'll see blocks start streaming through.
For this example, we're doing the above on a cloud machine. The next steps should be done on your local machine or another server in the cloud, which will join the running testnet then bond/unbond.
Accounts
--------
We have:
- ``alice`` the initial validator (in the cloud)
- ``bob`` receives tokens from ``alice`` then declares candidacy (from local machine)
- ``charlie`` will bond and unbond to ``bob`` (from local machine)
Remember that ``alice`` was already created. On your second machine, install the binaries and create two new keys:
::
gaiacli keys add bob
gaiacli keys add charlie
both of which will prompt you for a password. Now we need to copy the ``genesis.json`` and ``config.toml`` from the first machine (with ``alice``) to the second machine. This is a good time to look at both these files.
The ``genesis.json`` should look something like:
::
{
"app_state": {
"accounts": [
{
"address": "1D9B2356CAADF46D3EE3488E3CCE3028B4283DEE",
"coins": [
{
"denom": "steak",
"amount": 100000
}
]
}
],
"stake": {
"pool": {
"total_supply": 0,
"bonded_shares": {
"num": 0,
"denom": 1
},
"unbonded_shares": {
"num": 0,
"denom": 1
},
"bonded_pool": 0,
"unbonded_pool": 0,
"inflation_last_time": 0,
"inflation": {
"num": 7,
"denom": 100
}
},
"params": {
"inflation_rate_change": {
"num": 13,
"denom": 100
},
"inflation_max": {
"num": 20,
"denom": 100
},
"inflation_min": {
"num": 7,
"denom": 100
},
"goal_bonded": {
"num": 67,
"denom": 100
},
"max_validators": 100,
"bond_denom": "steak"
}
}
},
"validators": [
{
"pub_key": {
"type": "AC26791624DE60",
"value": "rgpc/ctVld6RpSfwN5yxGBF17R1PwMTdhQ9gKVUZp5g="
},
"power": 10,
"name": ""
}
],
"app_hash": "",
"genesis_time": "0001-01-01T00:00:00Z",
"chain_id": "test-chain-Uv1EVU"
}
To notice is that the ``accounts`` field has a an address and a whole bunch of "mycoin". This is ``alice``'s address (todo: dbl check). Under ``validators`` we see the ``pub_key.data`` field, which will match the same field in the ``priv_validator.json`` file.
The ``config.toml`` is long so let's focus on one field:
::
# Comma separated list of seed nodes to connect to
seeds = ""
On the ``alice`` cloud machine, we don't need to do anything here. Instead, we need its IP address. After copying this file (and the ``genesis.json`` to your local machine, you'll want to put the IP in the ``seeds = "138.197.161.74"`` field, in this case, we have a made-up IP. For joining testnets with many nodes, you can add more comma-seperated IPs to the list.
Now that your files are all setup, it's time to join the network. On your local machine, run:
::
gaiad start
and your new node will connect to the running validator (``alice``).
Sending Tokens
--------------
We'll have ``alice`` send some ``mycoin`` to ``bob``, who has now joined the network:
::
gaiacli send --amount=1000mycoin --sequence=0 --name=alice --to=5A35E4CC7B7DC0A5CB49CEA91763213A9AE92AD6 --chain-id=test-chain-Uv1EVU
where the ``--sequence`` flag is to be incremented for each transaction, the ``--name`` flag is the sender (alice), and the ``--to`` flag takes ``bob``'s address. You'll see something like:
::
Please enter passphrase for alice:
{
"check_tx": {
"gas": 30
},
"deliver_tx": {
"tags": [
{
"key": "height",
"value_type": 1,
"value_int": 2963
},
{
"key": "coin.sender",
"value_string": "5D93A6059B6592833CBC8FA3DA90EE0382198985"
},
{
"key": "coin.receiver",
"value_string": "5A35E4CC7B7DC0A5CB49CEA91763213A9AE92AD6"
}
]
},
"hash": "423BD7EA3C4B36AF8AFCCA381C0771F8A698BA77",
"height": 2963
}
TODO: check the above with current actual output.
Check out ``bob``'s account, which should now have 1000 mycoin:
::
gaiacli account 5A35E4CC7B7DC0A5CB49CEA91763213A9AE92AD6
Adding a Second Validator
-------------------------
**This section is wrong/needs to be updated**
Next, let's add the second node as a validator.
First, we need the pub_key data:
** need to make bob a priv_Val above?
::
cat $HOME/.gaia2/priv_validator.json
the first part will look like:
::
{"address":"7B78527942C831E16907F10C3263D5ED933F7E99","pub_key":{"type":"ed25519","data":"96864CE7085B2E342B0F96F2E92B54B18C6CC700186238810D5AA7DFDAFDD3B2"},
and you want the ``pub_key`` ``data`` that starts with ``96864CE``.
Now ``bob`` can declare candidacy to that pubkey:
::
gaiacli declare-candidacy --amount=10mycoin --name=bob --pubkey=<pub_key data> --moniker=bobby
with an output like:
::
Please enter passphrase for bob:
{
"check_tx": {
"gas": 30
},
"deliver_tx": {},
"hash": "2A2A61FFBA1D7A59138E0068C82CC830E5103799",
"height": 4075
}
We should see ``bob``'s account balance decrease by 10 mycoin:
::
gaiacli account 5D93A6059B6592833CBC8FA3DA90EE0382198985
To confirm for certain the new validator is active, ask the tendermint node:
::
curl localhost:46657/validators
If you now kill either node, blocks will stop streaming in, because
there aren't enough validators online. Turn it back on and they will
start streaming again.
Now that ``bob`` has declared candidacy, which essentially bonded 10 mycoin and made him a validator, we're going to get ``charlie`` to delegate some coins to ``bob``.
Delegating
----------
First let's have ``alice`` send some coins to ``charlie``:
::
gaiacli tx --amount=1000mycoin --sequence=2 --name=alice --to=48F74F48281C89E5E4BE9092F735EA519768E8EF
Then ``charlie`` will delegate some mycoin to ``bob``:
::
gaiacli tx delegate --amount=10mycoin --name=charlie --pubkey=<pub_key data>
You'll see output like:
::
Please enter passphrase for charlie:
{
"check_tx": {
"gas": 30
},
"deliver_tx": {},
"hash": "C3443BA30FCCC1F6E3A3D6AAAEE885244F8554F0",
"height": 51585
}
And that's it. You can query ``charlie``'s account to see the decrease in mycoin.
To get more information about the candidate, try:
::
gaiacli query candidate --pubkey=<pub_key data>
and you'll see output similar to:
::
{
"height": 51899,
"data": {
"pub_key": {
"type": "ed25519",
"data": "52D6FCD8C92A97F7CCB01205ADF310A18411EA8FDCC10E65BF2FCDB05AD1689B"
},
"owner": {
"chain": "",
"app": "sigs",
"addr": "5A35E4CC7B7DC0A5CB49CEA91763213A9AE92AD6"
},
"shares": 20,
"voting_power": 20,
"description": {
"moniker": "bobby",
"identity": "",
"website": "",
"details": ""
}
}
}
It's also possible the query the delegator's bond like so:
::
gaiacli query delegator-bond --delegator-address 48F74F48281C89E5E4BE9092F735EA519768E8EF --pubkey 52D6FCD8C92A97F7CCB01205ADF310A18411EA8FDCC10E65BF2FCDB05AD1689B
with an output similar to:
::
{
"height": 325782,
"data": {
"PubKey": {
"type": "ed25519",
"data": "52D6FCD8C92A97F7CCB01205ADF310A18411EA8FDCC10E65BF2FCDB05AD1689B"
},
"Shares": 20
}
}
where the ``--delegator-address`` is ``charlie``'s address and the ``-pubkey`` is the same as we've been using.
Unbonding
---------
Finally, to relinquish your voting power, unbond some coins. You should see
your VotingPower reduce and your account balance increase.
::
gaiacli unbond --amount=5mycoin --name=charlie --pubkey=<pub_key data>
gaiacli account 48F74F48281C89E5E4BE9092F735EA519768E8EF
See the bond decrease with ``gaiacli query delegator-bond`` like above.