Cosmos学习日记(一)
Cosmos官网:https://cosmos.network/
一、Cosmos的工作环境配置
操作系统: Ubuntu 24.04.1 LTS
Docker安装
- 更新系统软件包
sudo apt update && sudo apt upgrade -y
- 安装必要依赖
sudo apt install -y apt-transport-https ca-certificates curl software-properties-common
- 添加Docker的官方GPG秘钥
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
- 添加Docker的APT软件源
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
- 更新软件包并安装Docker
sudo apt update sudo apt install -y docker-ce docker-ce-cli containerd.io
- 验证Docker安装
sudo docker --version
Go安装
由于apt无法安装Go最新版本,因此采取从官网下载解压的方式安装Go。
- 下载Go的最新版本:前往前往Go 官方下载页面 获取最新版本的下载链接,然后使用 wget 下载。
wget https://go.dev/dl/go1.xx.x.linux-amd64.tar.gz
- 解压并安装
sudo tar -C /usr/local -xzf go1.xx.x.linux-amd64.tar.gz
- 配置环境变量
编辑 ~/.bashrc 文件(或~./zshrc,根据使用的shell),添加以下内容:
然后运行以下命令使配置生效:export PATH=$PATH:/usr/local/go/bin
source ~/.bashrc
- 验证安装
检查Go是否安装成功以及版本信息go version
- Node.js安装
- 添加Node.js官方源
根据需要的Node.js版本(长期支持版LTS或当前版本),添加相应的Node.js官方PPA(个人包档案):curl -fsSL https://deb.nodesource.com/setup_xx.x | sudo -E bash -
- 安装Node.js
sudo apt install -y nodejs
- 验证安装
检查安装的Node.js和npm(Node包管理器)版本:node -v npm -v
Rust安装
- 安装rustup
运行以下命令来安装Rust和Rust工具链管理器rustup:curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
- 配置环境变量
安装完成后,运行以下命令将Rust的二进制路径添加到系统路径中:
可以将上述明亮添加到 ~/.bashrc 或 ~/.zshrc 中,使其在每次启动终端时生效:source $HOME/.cargo/env
echo 'source $HOME/.cargo/env' >> ~/.bashrc source ~/.bashrc
- 验证安装
检查Rust和Cargo(Rust包管理工具)是否成功安装:rustc --version cargo --version
- 更新Rust
使用rustup可以更新Rust到最新版本:rustup update
二、运行节点,API和CLI
编译simapp
- 首先在工作路径下,创建一个cosmos的目录,并将cosmos-sdk源代码clone到本地。
$ mkdir cosmos $ cd cosmos $ git clone https://github.com/cosmos/cosmos-sdk $ cd cosmos-sdk
- 修改版本
$ git checkout v0.45.4
- 编译simapp
$ make build
- 编译成功后,检查simapp版本,二进制文件名称为simd
返回 0.45.4 表示编译版本正确。$ ./build/simd version
初始化simapp
- 首先删除隐藏文件夹中 .simapp 文件
$ rm -rf ./private/.simapp
- 初始化过程创建一个创世区块,初始化链状态,并且为区块链选择一个链ID
创建成功后会返回app_message的相关信息$ ./build/simd init demo \ --home ./private/.simapp \ --chain-id learning-chain-1
{"app_message":{"auth":{"accounts":[],"params":{"max_memo_characters":"256","sig_verify_cost_ed25519":"590","sig_verify_cost_secp256k1":"1000","tx_sig_limit":"7","tx_size_cost_per_byte":"10"}},"authz":{"authorization":[]},"bank":{"balances":[],"denom_metadata":[],"params":{"default_send_enabled":true,"send_enabled":[]},"supply":[]},"capability":{"index":"1","owners":[]},"crisis":{"constant_fee":{"amount":"1000","denom":"stake"}},"distribution":{"delegator_starting_infos":[],"delegator_withdraw_infos":[],"fee_pool":{"community_pool":[]},"outstanding_rewards":[],"params":{"base_proposer_reward":"0.010000000000000000","bonus_proposer_reward":"0.040000000000000000","community_tax":"0.020000000000000000","withdraw_addr_enabled":true},"previous_proposer":"","validator_accumulated_commissions":[],"validator_current_rewards":[],"validator_historical_rewards":[],"validator_slash_events":[]},"evidence":{"evidence":[]},"feegrant":{"allowances":[]},"genutil":{"gen_txs":[]},"gov":{"deposit_params":{"max_deposit_period":"172800s","min_deposit":[{"amount":"10000000","denom":"stake"}]},"deposits":[],"proposals":[],"starting_proposal_id":"1","tally_params":{"quorum":"0.334000000000000000","threshold":"0.500000000000000000","veto_threshold":"0.334000000000000000"},"votes":[],"voting_params":{"voting_period":"172800s"}},"mint":{"minter":{"annual_provisions":"0.000000000000000000","inflation":"0.130000000000000000"},"params":{"blocks_per_year":"6311520","goal_bonded":"0.670000000000000000","inflation_max":"0.200000000000000000","inflation_min":"0.070000000000000000","inflation_rate_change":"0.130000000000000000","mint_denom":"stake"}},"params":null,"slashing":{"missed_blocks":[],"params":{"downtime_jail_duration":"600s","min_signed_per_window":"0.500000000000000000","signed_blocks_window":"100","slash_fraction_double_sign":"0.050000000000000000","slash_fraction_downtime":"0.010000000000000000"},"signing_infos":[]},"staking":{"delegations":[],"exported":false,"last_total_power":"0","last_validator_powers":[],"params":{"bond_denom":"stake","historical_entries":10000,"max_entries":7,"max_validators":100,"unbonding_time":"1814400s"},"redelegations":[],"unbonding_delegations":[],"validators":[]},"upgrade":{},"vesting":{}},"chain_id":"learning-chain-1","gentxs_dir":"","moniker":"demo","node_id":"4f9021a015e696912f452532d53ac849d71cb750"}
- 可以查看 ./private/.simapp/config/genesis.json 文件查看创世区块的配置
$ cat ./private/.simapp/config/genesis.json
准备一个账户
- 检查秘钥环
由于目前还没有添加账户,因此返回结果应该为空。$ ./build/simd keys list \ --home ./private/.simapp \ --keyring-backend test
- 添加一个新的秘钥
为alice添加一个秘钥
创建成功后,会显示alice的秘钥信息以及相应的助记词$ ./build/simd keys add alice \ --home ./private/.simapp \ --keyring-backend test
- name: alice type: local address: cosmos1nw793j9xvdzl2uc9ly8fas5tcfwfetercpdfqq pubkey: '{"@type":"/cosmos.crypto.secp256k1.PubKey","key":"A6TrsRO/OH91fAEFLohw7RwFB832NRsRWhQvE2t8cfLK"}' mnemonic: "" **Important:** write this mnemonic phrase in a safe place. It is the only way to recover your account if you ever forget your password. ivory uniform actual spot floor vessel monster rose yellow noise smile odor veteran human reason miss stadium phrase assault puzzle sentence approve coral apology
- 可以检查秘钥是否被成功添加
也可以只看alice的秘钥信息$ ./build/simd keys list \ --home ./private/.simapp \ --keyring-backend test
$ ./build/simd keys show alice \ --home ./private/.simapp \ --keyring-bakcend test
使自己成为一个验证器( proper validator)
在初始化成功一个未启动的链之后,需要一个创世账户和一个验证者(cosmos SDK区块链依赖已识别的验证者来生成区块)进行接下来的工作
- 向创世账户分配足够的stake
$ ./build/simd add-genesis-account alice 100000000stake \ --home ./private/.simapp \ keyring-backend test
- 质押70000000stake使alice成为验证器
确认操作$ ./build/simd gentx alice 70000000stake \ --home ./private/.simapp \ --keyring-backend test \ --chain-id learning-chain-1
Genesis transaction written to "/Users/alice/cosmos/cosmos-sdk/private/.simapp/config/gentx/gentx-cf6bff39bb84da39d214138ebba8bcba4ccb848d.json"
- 在自己的文件中创建此创世交易后,收集所有创世交易,并将collect-gentxs包含在创世文件中
返回创世文件信息$ ./build/simd collect-gentxs \ --home ./private/.simapp
{"app_message":{"auth":{"accounts":[{"@type":"/cosmos.auth.v1beta1.BaseAccount","account_number":"0","address":"cosmos1nw793j9xvdzl2uc9ly8fas5tcfwfetercpdfqq","pub_key":null,"sequence":"0"}],"params":{"max_memo_characters":"256","sig_verify_cost_ed25519":"590","sig_verify_cost_secp256k1":"1000","tx_sig_limit":"7","tx_size_cost_per_byte":"10"}},"authz":{"authorization":[]},"bank":{"balances":[{"address":"cosmos1nw793j9xvdzl2uc9ly8fas5tcfwfetercpdfqq","coins":[{"amount":"100000000","denom":"stake"}]}],"denom_metadata":[],"params":{"default_send_enabled":true,"send_enabled":[]},"supply":[{"amount":"100000000","denom":"stake"}]},"capability":{"index":"1","owners":[]},"crisis":{"constant_fee":{"amount":"1000","denom":"stake"}},"distribution":{"delegator_starting_infos":[],"delegator_withdraw_infos":[],"fee_pool":{"community_pool":[]},"outstanding_rewards":[],"params":{"base_proposer_reward":"0.010000000000000000","bonus_proposer_reward":"0.040000000000000000","community_tax":"0.020000000000000000","withdraw_addr_enabled":true},"previous_proposer":"","validator_accumulated_commissions":[],"validator_current_rewards":[],"validator_historical_rewards":[],"validator_slash_events":[]},"evidence":{"evidence":[]},"feegrant":{"allowances":[]},"genutil":{"gen_txs":[{"auth_info":{"fee":{"amount":[],"gas_limit":"200000","granter":"","payer":""},"signer_infos":[{"mode_info":{"single":{"mode":"SIGN_MODE_DIRECT"}},"public_key":{"@type":"/cosmos.crypto.secp256k1.PubKey","key":"A6TrsRO/OH91fAEFLohw7RwFB832NRsRWhQvE2t8cfLK"},"sequence":"0"}],"tip":null},"body":{"extension_options":[],"memo":"cf6bff39bb84da39d214138ebba8bcba4ccb848d@192.168.1.7:26656","messages":[{"@type":"/cosmos.staking.v1beta1.MsgCreateValidator","commission":{"max_change_rate":"0.010000000000000000","max_rate":"0.200000000000000000","rate":"0.100000000000000000"},"delegator_address":"cosmos1nw793j9xvdzl2uc9ly8fas5tcfwfetercpdfqq","description":{"details":"","identity":"","moniker":"demo","security_contact":"","website":""},"min_self_delegation":"1","pubkey":{"@type":"/cosmos.crypto.ed25519.PubKey","key":"0wnjKoRtWjv9NOLEPS6UrlwFurQAmsJIXFsmhtbigF8="},"validator_address":"cosmosvaloper1nw793j9xvdzl2uc9ly8fas5tcfwfetera4euvn","value":{"amount":"70000000","denom":"stake"}}],"non_critical_extension_options":[],"timeout_height":"0"},"signatures":["NA23q62Vhfm1z3E1XafPeSDEVDkcPuTWXZmQr9QAZuN5wY2V6UFSRBO0w8Z255OxxZV4j47SJo1HOYWvcH4qvw=="]}]},"gov":{"deposit_params":{"max_deposit_period":"172800s","min_deposit":[{"amount":"10000000","denom":"stake"}]},"deposits":[],"proposals":[],"starting_proposal_id":"1","tally_params":{"quorum":"0.334000000000000000","threshold":"0.500000000000000000","veto_threshold":"0.334000000000000000"},"votes":[],"voting_params":{"voting_period":"172800s"}},"mint":{"minter":{"annual_provisions":"0.000000000000000000","inflation":"0.130000000000000000"},"params":{"blocks_per_year":"6311520","goal_bonded":"0.670000000000000000","inflation_max":"0.200000000000000000","inflation_min":"0.070000000000000000","inflation_rate_change":"0.130000000000000000","mint_denom":"stake"}},"params":null,"slashing":{"missed_blocks":[],"params":{"downtime_jail_duration":"600s","min_signed_per_window":"0.500000000000000000","signed_blocks_window":"100","slash_fraction_double_sign":"0.050000000000000000","slash_fraction_downtime":"0.010000000000000000"},"signing_infos":[]},"staking":{"delegations":[],"exported":false,"last_total_power":"0","last_validator_powers":[],"params":{"bond_denom":"stake","historical_entries":10000,"max_entries":7,"max_validators":100,"unbonding_time":"1814400s"},"redelegations":[],"unbonding_delegations":[],"validators":[]},"upgrade":{},"vesting":{}},"chain_id":"learning-chain-1","gentxs_dir":"/Users/muratoener/.simapp/config/gentx","moniker":"demo","node_id":"cf6bff39bb84da39d214138ebba8bcba4ccb848d"}
创建区块
- 启动单节点区块链
在终端将返回服务信息$ ./build/simd start --home ./private/.simapp
6:23PM INF starting ABCI with Tendermint 6:23PM INF Starting multiAppConn service impl=multiAppConn module=proxy 6:23PM INF Starting localClient service connection=query impl=localClient module=abci-client 6:23PM INF Starting localClient service connection=snapshot impl=localClient module=abci-client 6:23PM INF Starting localClient service connection=mempool impl=localClient module=abci-client 6:23PM INF Starting localClient service connection=consensus impl=localClient module=abci-client
- 新建一个终端,检查余额信息
- 首先获取alice的地址值
$ export alice=$(./build/simd keys show alice --address \ --home ./private/.simapp \ --keyring-backend test)
- 检查alice的余额
$ ./build/simd query bank balances $alice
- 返回打印结果
balances: - amount: "30000000" denom: stake pagination: next_key: null total: "0"
发送一笔交易
- 首先为bob分配一个地址
export bob=cosmos1ytt4z085fwxwnj0xdckk43ek4c9znuy00cghtq
- 查询该地址的余额
返回查询结果$ ./build/simd query bank balances $bob
balances: [] pagination: next_key: null total: "0"
- 实现alice向bob转账10stake
收到如下返回信息$ ./build/simd tx bank send $alice $bob 10stake \ --home ./private/.simapp \ --keyring-backend test \ --chain-id learning-chain-1
{"body":{"messages":[{"@type":"/cosmos.bank.v1beta1.MsgSend","from_address":"cosmos1nw793j9xvdzl2uc9ly8fas5tcfwfetercpdfqq","to_address":"cosmos1m95dh3uc2s7fkn4w6v3ueux3sya96dhdudwa24","amount":[{"denom":"stake","amount":"10"}]}],"memo":"","timeout_height":"0","extension_options":[],"non_critical_extension_options":[]},"auth_info":{"signer_infos":[],"fee":{"amount":[],"gas_limit":"200000","payer":"","granter":""},"tip":null},"signatures":[]} confirm transaction before signing and broadcasting [y/N]: y code: 0 codespace: "" data: "" gas_used: "0" gas_wanted: "0" height: "0" info: "" logs: [] raw_log: "" timestamp: "" tx: null txhash: D2CCFD91452F8C144BB1E7B54B9723EE3ED85925EE2C8AD843392721D072B895
- 保存交易哈希
使用如下命令查询交易export txhash=D2CCFD91452F8C144BB1E7B54B9723EE3ED85925EE2C8AD843392721D072B895
$ ./build/simd query tx $txhash
- 检查bob的账户余额
显示打印结果$ ./build/simd query bank balances $bob
balances: - amount: "10" denom: stake pagination: next_key: null total: "0"