cloud-cli

cloud-cli(简称cldi)是CITA-Cloud命令行工具。它封装了CITA-Cloud构建的链提供的gRPC接口,并提供了一些辅助功能,方便用户与链进行交互。

$ cldi help
cldi 0.4.0
Rivtower Technologies <contact@rivtower.com>
The command line interface to interact with CITA-Cloud

USAGE:
    cldi [OPTIONS] [SUBCOMMAND]

OPTIONS:
    -c, --context <context>       context setting
    -r <controller-addr>          controller address
    -e <executor-addr>            executor address
    -u <account-name>             account name
    -p <password>                 password to unlock the account
        --crypto <crypto-type>    The crypto type of the target chain [possible values: SM, ETH]
    -h, --help                    Print help information
    -V, --version                 Print version information

SUBCOMMANDS:
    get            Get data from chain
    send           Send transaction
    call           Call executor
    create         create an EVM contract
    context        Context commands
    account        Account commands
    admin          The admin commands for managing chain
    rpc            Other RPC commands
    ethabi         Ethereum ABI coder.
    bench          Simple benchmarks
    watch          Watch blocks
    completions    Generate completions for current shell. Add the output script to `.profile`
                   or `.bashrc` etc. to make it effective.
    help           Print this message or the help of the given subcommand(s)

安装

有几种不同的安装方法。

直接下载预编译的二进制文件

cldi有预编译好的二进制可执行文件,可以根据使用环境下载对应的文件。 https://github.com/whfuyn/cloud-cli/releases

如果你不知道如何选择,那么一般来说:

  • cldi-x86_64-pc-windows-msvc.zip,如果你是在Windows下
  • cldi-x86_64-unknown-linux-gnu.tar.gz,如果你是在Linux下
  • cldi-x86_64-apple-darwin.tar.gz,如果你是在MacOS下(非M1)
  • cldi-aarch64-apple-darwin.tar.gz,如果你是在MacOS下(M1)

如果出现libc相关问题,可以使用musl版。

如果在ARM上,使用aarch64版。

从源码编译

1. 安装Rust

如果你没有Rust环境,可以执行以下命令,通过rustup安装。

curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

2. 编译并安装cloud-cli

更新Rust版本。

# cloud-cli requires rust 1.58 or above
$ rustup update

可以通过GitHub安装。

$ cargo install --git https://github.com/whfuyn/cloud-cli --branch main

也可以先把项目clone到本地。

$ git clone https://github.com/cita-cloud/cloud-cli
$ cargo install --path cloud-cli

验证安装

$ cldi --version
cldi 0.4.0

快速入门

配置

1. controller和executor的地址

想要与链交互,首先要知道如何访问链。

CITA-Cloud有两个rpc地址,分别是controller和executor微服务。

假设controller的地址为"localhost:50004", executor的地址为"localhost:50002"。

那么我们可以通过-r-e来告诉cldi如何访问链:

# 注意-r和-e必须在子命令之前
$ cldi -r localhost:50004 -e localhost:50002 get block-number

2. 账户名称

发送交易的命令需要对交易进行签名,我们需要指定签名所使用的账户。 cldi在第一次使用的时候会创建一个名为default的默认账户,用户可以通过-u来指定账户:

# 同样地,-u必须在子命令之前
$ cldi -u Alice send --to <to> --value <value> --data <data>

创建和导入账户相关的命令请参见account

使用Context管理配置

每次都指定微服务的访问地址和使用的账户名称不太方便,我们可以通过context命令来管理这些配置。

# 创建一个Context
$ cldi -r localhost:50004 -e localhost:50002 -u Alice context save Wonderland
# 将这个Context设为默认
$ cldi context default Wonderland
# 也可以使用-c来切换Context,-c也必须在子命令之前
$ cldi -c Wonderland get block-number
# 列出当前Context信息和已保存的Context
$ cldi context list

交互模式

cldi提供了命令行模式和交互模式,在未传入子命令的时候cldi会进入交互模式。

交互模式与命令行模式的命令是等价的,例如:

$ cldi get block-number

等价于

$ cldi
cldi> get block-number

在交互模式下,用户可以通过-c, -r -e来改变当前会话的Context配置。

# 修改当前会话的全局配置
cldi> -r localhost:50004
# 仅针对这条命令应用这个配置
cldi> -r localhost:50004 get block-number

Q: How to quit cldi?
A: :q
A: CTRL-D

缩写

cldi提供了很多命令的缩写,这里列举一些:

cldi> get block-number
cldi> get bn

cldi> get system-config
cldi> get sc

cldi> context list
cldi> ctx ls
cldi> ctx l

cldi> account generate --name Alice
cldi> account gen --name Alice
cldi> account g --name Alice
cldi> a g --name Alice

cldi> bench send
cldi> b send

cldi> watch
cldi> w

这些缩写仅为方便用户操作,不作稳定性保证,不建议在脚本中使用。

命令行模式下的补全

cldi completions <shell-name>命令会输出补全脚本,需要添加到, 例如.profile, .bashrc里才能生效。目前支持的shell有:bash, zsh, powershell, fish, elvish

以bash为例,将下列脚本添加到.bashrc里即可。

source <(cldi completions bash)

使用示例

1.生成账户

如果需要更好的安全性,请加上-p <password>为私钥进行加密。 有密码的账户在硬盘上会进行加密存储,并且不会在生成时显示明文私钥。 加密后的账户需要经过-p <password>解密才能使用。

cldi> account generate --name Alice
{
  "crypto_type": "SM",
  "address": "0xb7768b2f989eeb9a1c7315aa38fb5fbd68333b8a",
  "public_key": "0x325ef60c3d8a94dd363a83f8b9a1ecbe3583b41aa204709eb0d2a19e7e323571d6d4015e5a049bfd04d3ff661385c36fe2066f9aaf72c943ff4ad1fc15e03e73",
  "secret_key": "0x9d08b671a8f12141c45edbd59e81eaf282a2534505ad0545bb46bf64d642b071"
}

2.创建环境配置

cldi> -r localhost:50004 -e localhost:50002 -u Alice context save Wonderland
# 设为默认环境
cldi> context default Wonderland

3.查询块高

cldi> get block-number
406030

4.查询系统配置

cldi> get system-config
{
  "admin": "0x29222738252b748e4d20a20073d05cd26e87cc00",
  "admin_pre_hash": "0x000000000000000000000000000000000000000000000000000000000000000000",
  "block_interval": 4,
  "block_interval_pre_hash": "0xe010952e2bf9a2da305af49c2598230e0ecbb37c7ece7dbef55031b775dba64f",
  "chain_id": "0x204c9a3301e7e698c45febb5e177ef35a656bb8feb355b6aca85beef5d248c14",
  "chain_id_pre_hash": "0x000000000000000000000000000000000000000000000000000000000000000000",
  "emergency_brake": false,
  "emergency_brake_pre_hash": "0x000000000000000000000000000000000000000000000000000000000000000000",
  "validators": [
    "0x43a8f6a2abd2782e06506695a19693589a53e38a",
    "0x4025800dc70684abd1e3eb89086d21d94f1dbfd8",
    "0x3b0829e9f547cfecfae7fb3d527e8405d4304222"
  ],
  "validators_pre_hash": "0x000000000000000000000000000000000000000000000000000000000000000000",
  "version": 0,
  "version_pre_hash": "0x000000000000000000000000000000000000000000000000000000000000000000"
}

5.创建合约

我们通过cldi create <data>发送创建合约交易。其中<data>是合约的数据,这里以一个计数器合约为例。返回结果为这个创建合约交易的哈希。

cldi> create 0x608060405234801561001057600080fd5b5060f58061001f6000396000f3006080604052600436106053576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806306661abd1460585780634f2be91f146080578063d826f88f146094575b600080fd5b348015606357600080fd5b50606a60a8565b6040518082815260200191505060405180910390f35b348015608b57600080fd5b50609260ae565b005b348015609f57600080fd5b5060a660c0565b005b60005481565b60016000808282540192505081905550565b600080819055505600a165627a7a72305820faa1d1f51d7b5ca2b200e0f6cdef4f2d7e44ee686209e300beb1146f40d32dee0029
0xbdeabf94a31c503deb4400fc63aee2a89e8f43d6570ed7ad5cd4f6f2898be0a2

等待交易上链后,通过cldi get receipt <tx-hash>获取交易回执,在交易回执中的contract_addr项查看创建出来的合约的地址。这里为0xf064e32407b6cc412fe33f6ba55f578ac413ecdc

cldi> get receipt 0xbdeabf94a31c503deb4400fc63aee2a89e8f43d6570ed7ad5cd4f6f2898be0a2
{
  "block_number": 406069,
  "contract_addr": "0xf064e32407b6cc412fe33f6ba55f578ac413ecdc",
  "cumulative_quota_used": "0x0000000000000000000000000000000000000000000000000000000000018ed3",
  "error_msg": "",
  "legacy_cita_block_hash": "0x265386a6afc6072f0acb5d32e0fe079e101129041dbfed2bee8872a849e8f7a3",
  "logs": [],
  "logs_bloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
  "quota_used": "0x0000000000000000000000000000000000000000000000000000000000018ed3",
  "state_root": "0x96899ff87f9bed55fd880750c2c51661ee24e14f672a1c9d7ac9573536b8c3f0",
  "tx_hash": "0xbdeabf94a31c503deb4400fc63aee2a89e8f43d6570ed7ad5cd4f6f2898be0a2",
  "tx_index": 0
}

6.调用合约

查询合约数据。当前计数器的值为0。

cldi> call 0xf064e32407b6cc412fe33f6ba55f578ac413ecdc 0x06661abd
0x0000000000000000000000000000000000000000000000000000000000000000

发送交易,使得计数器加一。

cldi> send 0xf064e32407b6cc412fe33f6ba55f578ac413ecdc 0x4f2be91f
0x99e57fdfed555059fa143ad0bc4d8ddc8764f8024fb3b28e880a84667414dec5

等待交易上链后,再次查询,可以看到结果为一,符合预期。

cldi> call 0xf064e32407b6cc412fe33f6ba55f578ac413ecdc 0x06661abd
0x0000000000000000000000000000000000000000000000000000000000000001

命令介绍

cldi是对CITA-Cloud协议定义的对外的gRPC接口的封装。

这里列出这些接口以供参考。

controller的接口

controller proto

service RPCService {
    // flag means latest or pending.
    // true means pending, false means latest.
    rpc GetBlockNumber(Flag) returns (BlockNumber);

    rpc SendRawTransaction(blockchain.RawTransaction) returns (common.Hash);

    rpc SendRawTransactions(blockchain.RawTransactions) returns (common.Hashes);

    rpc GetBlockByHash(common.Hash) returns (blockchain.CompactBlock);

    rpc GetBlockByNumber(BlockNumber) returns (blockchain.CompactBlock);

    rpc GetTransaction(common.Hash) returns (blockchain.RawTransaction);

    rpc GetSystemConfig(common.Empty) returns (SystemConfig);

    rpc GetVersion(common.Empty) returns (SoftwareVersion);

    rpc GetBlockHash(BlockNumber) returns (common.Hash);

    rpc GetTransactionBlockNumber(common.Hash) returns (BlockNumber);

    rpc GetTransactionIndex(common.Hash) returns (TransactionIndex);

    rpc GetPeerCount(common.Empty) returns (PeerCount);

    // add new node
    rpc AddNode(common.NodeNetInfo) returns (common.StatusCode);

    // get peers info
    rpc GetPeersInfo(common.Empty) returns (common.TotalNodeInfo);
}

executor的接口

executor proto

其中call的数据格式由具体的executor微服务定义。

service ExecutorService {
    // exec a block return executed_block_hash
    rpc Exec(blockchain.Block) returns (common.HashResponse);

    rpc Call(CallRequest) returns (CallResponse);
}

executor_evm的接口

executor_evm proto

service RPCService {
  rpc GetTransactionReceipt(common.Hash) returns (Receipt);

  rpc GetCode(common.Address) returns (ByteCode);

  rpc GetBalance(common.Address) returns (Balance);

  rpc GetTransactionCount(common.Address) returns (Nonce);

  rpc GetAbi(common.Address) returns (ByteAbi);
}

get

获取链上数据相关的命令。

$ cldi help get
cldi-get
Get data from chain

USAGE:
    cldi get <SUBCOMMAND>

OPTIONS:
    -h, --help    Print help information

SUBCOMMANDS:
    abi              Get the specific contract ABI
    balance          Get balance by account address
    block            Get block by block height or hash(0x)
    code             Get code by contract address
    tx               Get transaction data by tx_hash
    peer-count       Get peer count
    peers-info       Get peers info
    nonce            Get the nonce of this account
    receipt          Get EVM execution receipt by tx_hash
    version          Get version
    system-config    Get system config
    block-hash       Get block hash by block height
    block-number     Get block number
    help             Print this message or the help of the given subcommand(s)

blcok-number

获取节点当前已确认的块高。

cldi> get block-number
cldi> g bn

获取尚未确认的块高。

cldi> get block-number -p

receipt

获取EVM执行后的交易回执,注意它和get-tx不同,get-tx获取的是交易数据。

cldi> get receipt 0x8efa5acafdb1a48de23231444d7f28c64d22ebe17a5889a08aeeb3bdd7303197
cldi> g r 0x8efa5acafdb1a48de23231444d7f28c64d22ebe17a5889a08aeeb3bdd7303197

send

发送交易。

注意和cita-cli不同,<to>是必传参数,如果想要创建合约,请使用create命令。

$ cldi help send
cldi-send
Send transaction

USAGE:
    cldi send [OPTIONS] <to> [data]

ARGS:
    <to>      the target address of this tx
    <data>    the data of this tx [default: 0x]

OPTIONS:
    -v, --value <value>                the value of this tx [default: 0x0]
    -q, --quota <quota>                the quota of this tx [default: 3000000]
        --until <valid-until-block>    this tx is valid until the given block height. `+h` means
                                       `<current-height> + h` [default: +95]
    -h, --help                         Print help information

valid_until_block用来限制交易的有效范围,即在多少高度之前可以被打包,可以指定一个确定的高度(例如100),也可以指定为当前高度加多少(例如+95)。

示例

cldi> send 0xf064e32407b6cc412fe33f6ba55f578ac413ecdc 0x4f2be91f

call

调用executor提供的call。

这里用到的<data>是经过ethabi编码的数据。

$ cldi help call
cldi-call
Call executor

USAGE:
    cldi call [OPTIONS] <to> <data>

ARGS:
    <to>      the target contract address
    <data>    the data of this call request

OPTIONS:
    -f, --from <from>    default to use current account address
    -h, --help           Print help information

示例

cldi> call 0xf064e32407b6cc412fe33f6ba55f578ac413ecdc 0x06661abd

create

发送交易创建EVM上的合约。合约地址可以在交易的receipt里的contract_addr中查看。

$ cldi help create
cldi-create
create an EVM contract

USAGE:
    cldi create [OPTIONS] <data>

ARGS:
    <data>    the data of this tx

OPTIONS:
    -v, --value <value>                the value of this tx [default: 0x0]
    -q, --quota <quota>                the quota of this tx [default: 3000000]
        --until <valid-until-block>    this tx is valid until the given block height. `+h` means
                                       `<current-height> + h` [default: +95]
    -h, --help                         Print help information

示例

cldi> create 0x608060405234801561001057600080fd5b5060f58061001f6000396000f3006080604052600436106053576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806306661abd1460585780634f2be91f146080578063d826f88f146094575b600080fd5b348015606357600080fd5b50606a60a8565b6040518082815260200191505060405180910390f35b348015608b57600080fd5b50609260ae565b005b348015609f57600080fd5b5060a660c0565b005b60005481565b60016000808282540192505081905550565b600080819055505600a165627a7a72305820faa1d1f51d7b5ca2b200e0f6cdef4f2d7e44ee686209e300beb1146f40d32dee0029
``

account

account相关命令。

警告:设置了密码的账户在硬盘上是经过加密后存储的,虽然加密算法本身可靠,但在加密算法之外可能存在其它安全漏洞(例如account delete没有安全覆写原明文私钥),代码未经安全审计,作者亦非安全专家,不能保证安全性,使用者风险自负(Use at your own risk)。

$ cldi help account
cldi-account
Account commands

USAGE:
    cldi account <SUBCOMMAND>

OPTIONS:
    -h, --help    Print help information

SUBCOMMANDS:
    generate    generate a new account
    list        list accounts
    import      import account
    export      export account
    unlock      unlock account in keystore
    lock        lock account in keystore
    delete      delete account
    help        Print this message or the help of the given subcommand(s)

当前使用的账户可以在context list展示的的current setting中查看。

如果需要安全地删除账户,可以在$HOME/.cloud-cli/accounts下找到账户名对应的toml文件,使用带有防止恢复功能的删除工具删除(粉碎文件)。

带密码的账户需要在cldi命令下传入-p <password>解锁,用法与-c, -r等命令相似。

带密码的账号

创建一个带密码的账户root,这个账户root在当前交互会话下可用,无需再输入密码

$ cldi
cldi> account generate --name root --password root
{
  "crypto_type": "SM",
  "address": "0xb293c14d8fc8ff4b24db3926118388b562593d99",
  "public_key": "0x411b418b10005ec32aacf6412a097e87680b29795f723844f6c90e2e850b9d618640ad0fa3011dd67bb667f31656476eb13fdef63329c4756ebd44d3ca265c08",
  "encrypted_sk": "0x36aa2663fa3c2626d7acf051f6a49a81280d7422b49551bcaf9c187d14af2b0d"
}

按CTRL-D退出交互模式,重新进入。注意这里可以在进入时直接选中这个账号root

$ cldi -u root
cldi>

尝试在不输入密码的情况下使用这个账号,可以看到报错

cldi> send 0xb293c14d8fc8ff4b24db3926118388b562593d99
cannot get current account `root`

Caused by:
    account is locked, please unlock it first(e.g. `cldi -p <password> [subcommand]`)

输入密码,与其它命令相似,不带子命令是为当前会话解锁账户,带了子命令则只针对这条子命令。

cldi> -p root
cldi> send 0xb293c14d8fc8ff4b24db3926118388b562593d99

context

context相关命令。

$ cldi help context
cldi-context
Context commands

USAGE:
    cldi context <SUBCOMMAND>

OPTIONS:
    -h, --help    Print help information

SUBCOMMANDS:
    save       save context
    list       list contexts
    delete     delete context
    default    set a context as default and switch current context to it
    help       Print this message or the help of the given subcommand(s)

context list

列出环境配置信息。

cldi> context list
cldi> ctx ls
cldi> ctx l
{
  // 当前保存的所有环境配置
  "contexts": {
    // 环境配置的名字
    "default": {
       // 这个配置所用的账户名
      "account_name": "default",
       // controller地址
      "controller_addr": "localhost:50004",
       // 使用的密码学算法集
      "crypto_type": "SM",
       // executor地址
      "executor_addr": "localhost:50002"
    },
  },
  // 当前会话的环境配置
  "current_context": {
    "account_name": "default",
    "controller_addr": "localhost:50004",
    "crypto_type": "SM",
    "executor_addr": "localhost:50004"
  },
  // 启动时默认使用的环境配置的名字
  "default_context": "default"
}

context save

保存当前会话的环境配置。

cldi context save <context-name>

示例

将当前环境配置保存成一个名为new的环境配置。

cldi> context save new

以test这个环境配置为基础,controller地址localhost:50004,executor地址localhost:50002,账号名为admin,保存一个名为admin的环境配置。

cldi> -c test -r localhost:50004 -e localhost:50002 -u admin context save admin

admin

admin相关命令,用于管理链的配置。

$ cldi help admin
cldi-admin
The admin commands for managing chain

USAGE:
    cldi admin <SUBCOMMAND>

OPTIONS:
    -h, --help    Print help information

SUBCOMMANDS:
    update-admin          Update admin of the chain
    update-validators     Update validators of the chain
    set-block-interval    Set block interval
    emergency-brake       Send emergency brake cmd to chain
    help                  Print this message or the help of the given subcommand(s)

这些命令必须以链的管理员账号发送,否则链上会返回错误。具体来说,当前账户的地址必须和链配置的管理员地址一致。

admin下的所有命令都是通过向链发送UTXO交易来完成的。请参考相关的RFC

UTXO交易的数据格式是controller内部定义的,最早的参考实现为tools

rpc

未分类的rpc命令。

$ cldi help rpc
cldi-rpc
Other RPC commands

USAGE:
    cldi rpc <SUBCOMMAND>

OPTIONS:
    -h, --help    Print help information

SUBCOMMANDS:
    add-node     call add-node rpc
    store-abi    Store EVM contract ABI
    help         Print this message or the help of the given subcommand(s)

add-node

调用controller的add-node接口,这个接口曾用于让network微服务连接一个新的节点。

$ cldi rpc add-node -h
cldi-rpc-add-node
call add-node rpc

USAGE:
    cldi rpc add-node <host> <port> [tls]

ARGS:
    <host>    the host of the new node
    <port>    the port of the new node
    <tls>     the domain name of the new node

OPTIONS:
    -h, --help    Print help information

store-abi

通过发送交易,在链上保存合约的ABI。

$ cldi rpc store-abi -h
cldi-rpc-store-abi
Store EVM contract ABI

USAGE:
    cldi rpc store-abi [OPTIONS] <addr> <abi>

ARGS:
    <addr>
    <abi>

OPTIONS:
    -q, --quota <quota>                the quota of this tx [default: 3000000]
        --until <valid-until-block>    this tx is valid until the given block height. `+h` means
                                       `<current-height> + h` [default: +95]
    -h, --help                         Print help information

ethabi

这个子命令来自ethabi,请参考官方文档。

$ cldi help ethabi
cldi-ethabi 17.0.0
Parity Technologies <admin@parity.io>
Artem Vorotnikov <artem@vorotnikov.me>
Nicholas Rodrigues Lordello <nlordell@gmail.com>
Ethereum ABI coder.

USAGE:
    cldi ethabi <SUBCOMMAND>

OPTIONS:
    -h, --help       Print help information
    -V, --version    Print version information

SUBCOMMANDS:
    encode    Encode ABI call.
    decode    Decode ABI call result.
    help      Print this message or the help of the given subcommand(s)

bench

简单的性能测试工具。

$ cldi help bench
cldi-bench
Simple benchmarks

USAGE:
    cldi bench <SUBCOMMAND>

OPTIONS:
    -h, --help    Print help information

SUBCOMMANDS:
    send    Send transactions with {-c} workers over {--connections} connections
    call    Call executor with {-c} workers over {--connections} connections
    help    Print this message or the help of the given subcommand(s)

目前支持测试发送交易(send)和executor调用(call)。

通用参数

ARGS:
    <total>    Number of tasks in the benchmark [default: 10000]

OPTIONS:
    -c, --concurrency <concurrency>    Number of request workers to run concurrently. Workers will
                                       be distributed evenly among all the connections. [default:
                                       the same as total]
        --connections <connections>    Number of connections connects to server [default: 1]
        --timeout <timeout>            Timeout for each request (in seconds). 0 means no timeout
                                       [default: 0]
  • 位置参数<total>代表总共发多少个请求,默认请求数为10000。
  • -c--concurrency用来指定并发数,代表同一时刻最多有多少请求在并发进行,默认是所有请求都是并发发出的。
  • --connections是使用的连接数,cldi发起的gRPC请求是会在同一条连接上多路复用的,增加连接数在一定范围内能提高发送速度,默认连接数为1。
  • --timeout是请求的超时时间,单位是秒,默认为0,即不设置超时。

bench-send

$ cldi bench send -h
cldi-bench-send
Send transactions with {-c} workers over {--connections} connections

USAGE:
    cldi bench send [OPTIONS] [total]

ARGS:
    <total>    Number of tasks in the benchmark [default: 10000]

OPTIONS:
    -c, --concurrency <concurrency>    Number of request workers to run concurrently. Workers will
                                       be distributed evenly among all the connections. [default:
                                       the same as total]
        --connections <connections>    Number of connections connects to server [default: 1]
        --timeout <timeout>            Timeout for each request (in seconds). 0 means no timeout
                                       [default: 0]
    -t, --to <to>                      the target address of this tx. Default to random
    -d, --data <data>                  the data of this tx. Default to random 32 bytes
    -v, --value <value>                the value of this tx [default: 0x0]
    -q, --quota <quota>                the quota of this tx [default: 3000000]
        --until <valid-until-block>    this tx is valid until the given block height. `+h` means
                                       `<current-height> + h` [default: +95]
        --disable-watch                don't watch blocks
    -h, --help                         Print help information

bench-call

$ cldi bench call -h
cldi-bench-call
Call executor with {-c} workers over {--connections} connections

USAGE:
    cldi bench call [OPTIONS] [total]

ARGS:
    <total>    Number of tasks in the benchmark [default: 10000]

OPTIONS:
    -c, --concurrency <concurrency>    Number of request workers to run concurrently. Workers will
                                       be distributed evenly among all the connections. [default:
                                       the same as total]
        --connections <connections>    Number of connections connects to server [default: 1]
        --timeout <timeout>            Timeout for each request (in seconds). 0 means no timeout
                                       [default: 0]
    -f, --from <from>                  Default to use current account address
    -t, --to <to>                      the target contract address to call. Default to random
    -d, --data <data>                  the data for the call request. Default to random 32 bytes
    -h, --help                         Print help information

watch

观察当前链的出块情况。展示的时间是块头的时间戳,并且会以开始观察的第一个块时间戳为起始时间00:00。

$ cldi help watch
cldi-watch
Watch blocks

USAGE:
    cldi watch [OPTIONS]

OPTIONS:
    -b, --begin <begin>
            the block height starts from. You can use +/- prefix to seek from current height

    -e, --end <end>
            the block height ends at. You can use +/- prefix to seek from current height

    -t, --until <until-finalized-txs>
            stop watching when finalized txs reach the given limit

    -h, --help
            Print help information

示例

# 从当前块开始观察
cldi> watch
# 从当前块开始观察,直到有100笔交易上链
cldi> watch --until 100
# 从块高0到块高10
cldi> watch --begin 0 --end 10
# 从当前块高-10到当前块高+10
cldi> watch --begin -10 --end +10
# 使用缩写
cldi> w --begin -10 --end +10 --until 100

completions

命令行模式下的补全。

$ cldi help completions
cldi-completions
Generate completions for current shell. Add the output script to `.profile` or `.bashrc` etc. to
make it effective.

USAGE:
    cldi completions <shell>

ARGS:
    <shell>    [possible values: bash, zsh, powershell, fish, elvish]

OPTIONS:
    -h, --help    Print help information

这个命令会输出补全脚本,需要添加到例如.profile, .bashrc里才能生效。

以bash为例,将下列脚本添加到.bashrc里即可。

source <(cldi completions bash)

设计架构

TODO: 有生之年

开发指南

参考cloud-cli/src/cmd下的命令实现。

需要异步的话可以从Context里拿到runtime,用这个runtime去block_on即可执行异步任务。

需要client的什么功能,就在Context相应的泛型里加上相应的trait约束。 如果觉得泛型太复杂,也可以把它去掉,把所有泛型都用具体的类型替换掉。

TODO: 有生之年

TODO

  • 把错误处理做好一点,现在用anyhow糊不太好,建议用thiserror做一些具体的类型,然后上层可以做一些判断,打印更有帮助的错误信息。
  • 交互模式下的补全,考虑到clap可以构造一些很复杂的命令,想要做对会比较麻烦。好消息是补全本身的实现有rustyline。
  • mock测试。
  • 给help加个h缩写,可能要绕一下,参考completions的写法。

错误排查

TODO: 欢迎贡献文档

编译失败,提示feature unstable

rust版本不够新,更新即可。

$ rustup update

Connection refused

和链建立连接被拒绝,请检查当前环境配置的controller_addr和executor_addr。

$ cldi ctx ls

Admin Check Error

admin命令需要使用管理员账户,管理员账户是在启链时设置的。

No get receipt

这个是executor_evm返回的报错,一般有两种情况:

  • 交易没有上链
  • 试图获取admin命令发送的UTXO交易的回执。UTXO交易在executor_evm里不处理,没有回执。

Account locked

当前账户带密码,使用-p指定密码。