3. 命令行工具

3.1. 简介

cmc是ChainMaker提供的命令行工具,用于和ChainMaker链进行交互以及生成证书等功能。cmc基于go语言编写,通过使用ChainMaker的go语言sdk(使用grpc协议)达到和ChainMaker链进行交互的目的。

3.2. cmc编译

cmc工具的编译方式如下:

$ git clone --recurse-submodules -b v1.1.1 https://git.chainmaker.org.cn/chainmaker/chainmaker-go.git
$ cd chainmaker-go/tools/cmc
$ go mod download
$ go build
# 方式一:使用默认自带的证书,拷贝sdk的配置文件和示例里cmc命令行需要使用的文件
  $ cp -r ../sdk/testdata ./
# 方式二:使用刚生成的证书
  $ mkdir testdata
  $ cp ../sdk/testdata/sdk_config.yml testdata/
  $ cp -r ../../build/crypto-config testdata/

3.3. cmc功能

cmc提供功能如下:

  • 私钥管理:私钥生成功能

  • 证书管理:包括生成ca证书、生成crl列表、生成csr、颁发证书、根据证书获取节点Id等功能

  • 交易功能:主要包括链管理、用户合约发布、升级、吊销、冻结、调用、查询等功能

  • 帮助功能:提供所有命令的帮助查询

3.3.1. 示例

  • 交易功能

    cmc的交易功能用来发送交易和链进行交互,主要参数说明如下:

    	--admin-key-file-paths:指定admin用户的私钥文件路径
    	--admin-crt-file-paths:指定admin用户的证书文件路径
    	--org-id:指定发送交易的用户所属的组织Id
    	--chain-id:指定链Id
    	--client-crt-file-paths:指定发送交易的用户证书文件路径
    	--client-key-file-paths:指定用户的私钥文件路径
    	--byte-code-path:指定合约的wasm文件路径
    	--contract-name:指定合约名称
    	--method:指定调用的合约方法名称
    	--runtime-type:指定合约执行虚拟机环境,包含:GASM、WASMER、WXVM、NATIVE
    	--sdk-conf-path:指定cmc使用sdk的配置文件路径
    	--version:指定合约的版本号,在发布和升级合约时使用
    	--sync-result:指定是否同步等待交易执行结果,默认为false,如果设置为true,在发送完交易后会主动查询交易执行结果
    	--params:指定发布合约或调用合约时的参数信息
    	--concurrency:指定调用合约并发的go routine,用于压力测试
    	--total-count-per-goroutine:指定单个go routine发送的交易数量,用于压力测试,和--concurrency配合使用
    	--block-height:指定区块高度
    	--tx-id:指定交易Id
    	--with-rw-set:指定获取区块时是否附带读写集,默认是false
    
    • 创建合约

      $ ./cmc client contract user create \
      --contract-name=fact \
      --runtime-type=WASMER \
      --byte-code-path=../../test/wasm/rust-fact-1.1.1.wasm \
      --version=1.0 \
      --sdk-conf-path=./testdata/sdk_config.yml \
      --admin-key-file-paths=./testdata/crypto-config/wx-org1.chainmaker.org/user/admin1/admin1.tls.key \
      --admin-crt-file-paths=./testdata/crypto-config/wx-org1.chainmaker.org/user/admin1/admin1.tls.crt \
      --org-id=wx-org1.chainmaker.org \
      --client-crt-file-paths=./testdata/crypto-config/wx-org1.chainmaker.org/user/client1/client1.tls.crt \
      --client-key-file-paths=./testdata/crypto-config/wx-org1.chainmaker.org/user/client1/client1.tls.key \
      --sync-result=true \
      --params="{}"
      

      如下返回表示成功:

      create contract resp: message:”OK” contract_result:<gas_used:73738 >

      注:智能合约编写及生成wasm文件参见:智能合约开发

    • 调用合约

      $ ./cmc client contract user invoke \
      --contract-name=fact \
      --method=save \
      --sdk-conf-path=./testdata/sdk_config.yml \
      --params="{\"faile_name\":\"name007\",\"file_hash\":\"ab3456df5799b87c77e7f88\",\"time\":\"6543234\"}" \
      --org-id=wx-org1.chainmaker.org \
      --client-crt-file-paths=./testdata/crypto-config/wx-org1.chainmaker.org/user/client1/client1.tls.crt \
      --client-key-file-paths=./testdata/crypto-config/wx-org1.chainmaker.org/user/client1/client1.tls.key \
      --sync-result=true
      

      如下返回表示成功:

      INVOKE contract resp, [code:0]/[msg:OK]/[contractResult:gas_used:13282710 ]

    • 查询合约

        $ ./cmc client contract user get \
        --contract-name=fact \
        --method=find_by_file_hash \
        --sdk-conf-path=./testdata/sdk_config.yml \
        --params="{\"file_hash\":\"ab3456df5799b87c77e7f88\"}" \
        --org-id=wx-org1.chainmaker.org \
        --client-crt-file-paths=./testdata/crypto-config/wx-org1.chainmaker.org/user/client1/client1.tls.crt \
        --client-key-file-paths=./testdata/crypto-config/wx-org1.chainmaker.org/user/client1/client1.tls.key
      

      如下返回表示成功:

      QUERY contract resp: message:”SUCCESS” contract_result:<result:”{”file_hash”:”ab3456df5799b87c77e7f88”,”file_name”:””,”time”:”6543234”}” gas_used:24034881 >

    • 升级合约

      $ ./cmc client contract user upgrade \
      --contract-name=fact \
      --runtime-type=WASMER \
      --byte-code-path=../../test/wasm/rust-fact-1.1.1.wasm \
      --version=2.0 \
      --sdk-conf-path=./testdata/sdk_config.yml \
      --admin-key-file-paths=./testdata/crypto-config/wx-org1.chainmaker.org/user/admin1/admin1.tls.key \
      --admin-crt-file-paths=./testdata/crypto-config/wx-org1.chainmaker.org/user/admin1/admin1.tls.crt \
      --org-id=wx-org1.chainmaker.org \
      --client-crt-file-paths=./testdata/crypto-config/wx-org1.chainmaker.org/user/client1/client1.tls.crt \
      --client-key-file-paths=./testdata/crypto-config/wx-org1.chainmaker.org/user/client1/client1.tls.key \
      --sync-result=true \
      --params="{}"
      

      如下返回表示成功:其中result结果为用户自定义,每个合约可能不一样,也可能没有。

      upgrade contract resp: message:”OK” contract_result:<result:”upgrade ok” gas_used:4787624 >

    • 冻结合约

      $ ./cmc client contract user freeze \
      --contract-name=fact \
      --sdk-conf-path=./testdata/sdk_config.yml \
      --admin-key-file-paths=./testdata/crypto-config/wx-org1.chainmaker.org/user/admin1/admin1.tls.key \
      --admin-crt-file-paths=./testdata/crypto-config/wx-org1.chainmaker.org/user/admin1/admin1.tls.crt \
      --org-id=wx-org1.chainmaker.org \
      --client-crt-file-paths=./testdata/crypto-config/wx-org1.chainmaker.org/user/client1/client1.tls.crt \
      --client-key-file-paths=./testdata/crypto-config/wx-org1.chainmaker.org/user/client1/client1.tls.key \
      --sync-result=true
      

      此时再执行查询、调用合约则会失败:会报如下错误:

      QUERY contract resp: code:CONTRACT_FREEZE_FAILED message:”36, 1, contractName[fact] method[find_by_file_hash] txType[QUERY_USER_CONTRACT], failed to run user contract, fact has been frozen.” contract_result:<code:FAIL message:”failed to run user contract, fact has been frozen.” >

      $ ./cmc client contract user get
      –contract-name=fact
      –method=find_by_file_hash
      –sdk-conf-path=./testdata/sdk_config.yml
      –params=”{”file_hash”:”ab3456df5799b87c77e7f88”}”
      –org-id=wx-org1.chainmaker.org
      –client-crt-file-paths=./testdata/crypto-config/wx-org1.chainmaker.org/user/client1/client1.tls.crt
      –client-key-file-paths=./testdata/crypto-config/wx-org1.chainmaker.org/user/client1/client1.tls.key

    • 解冻合约

      $ ./cmc client contract user unfreeze \
      --contract-name=fact \
      --sdk-conf-path=./testdata/sdk_config.yml \
      --admin-key-file-paths=./testdata/crypto-config/wx-org1.chainmaker.org/user/admin1/admin1.tls.key \
      --admin-crt-file-paths=./testdata/crypto-config/wx-org1.chainmaker.org/user/admin1/admin1.tls.crt \
      --org-id=wx-org1.chainmaker.org \
      --client-crt-file-paths=./testdata/crypto-config/wx-org1.chainmaker.org/user/client1/client1.tls.crt \
      --client-key-file-paths=./testdata/crypto-config/wx-org1.chainmaker.org/user/client1/client1.tls.key \
      --sync-result=true
      

      解冻后的合约可正常使用

    • 吊销合约

      $ ./cmc client contract user revoke \
      --contract-name=fact \
      --sdk-conf-path=./testdata/sdk_config.yml \
      --admin-key-file-paths=./testdata/crypto-config/wx-org1.chainmaker.org/user/admin1/admin1.tls.key \
      --admin-crt-file-paths=./testdata/crypto-config/wx-org1.chainmaker.org/user/admin1/admin1.tls.crt \
      --org-id=wx-org1.chainmaker.org \
      --client-crt-file-paths=./testdata/crypto-config/wx-org1.chainmaker.org/user/client1/client1.tls.crt \
      --client-key-file-paths=./testdata/crypto-config/wx-org1.chainmaker.org/user/client1/client1.tls.key \
      --sync-result=true
      

      吊销合约后,不可恢复,且不能对该合约执行任何操作,包括查询。

  • 私钥管理

    生成私钥

    参数说明

    $ ./cmc key gen -h 
    Private key generate
    Usage:
      cmc key gen [flags]
    
    Flags:
      -a, --algo string   specify key generate algorithm
      -h, --help          help for gen
      -n, --name string   specify storage name
      -p, --path string   specify storage path
    

    示例:

    $ ./cmc key gen -a ECC_P256 -n ca.key -p ./
    
  • 证书管理

    • 生成ca证书

      生成ca证书之前需要先生成ca的私钥文件,然后在生成ca证书时使用-k参数指定生成的私钥文件路径

      参数说明

      $ ./cmc cert ca -h 
      Create certificate authority crtificate
      Usage:
        cmc cert ca [flags]
      
      Flags:
        -c, --cn string         specify common name
        -H, --hash string       specify hash algorithm
        -h, --help              help for ca
        -k, --key-path string   specify key path
        -n, --name string       specify storage name
        -o, --org string        specify organization
        -O, --ou string         specify organizational unit
        -p, --path string       specify storage path
      

      示例

      $ ./cmc cert ca -c wx-org1.chainmaker.org -k ca.key -H sha256 --ou root-ca -n ca.crt -p ./ --org wx-org1
      
    • 生成crl列表

      crl列表用于撤消证书请求,首先将要撤消的证书生成一个crl列表,然后再发送请求到链上

      参数说明

      $ ./cmc cert crl -h  
      create cert crl
      
      Usage:
        cmc cert crl [flags]
      
      Flags:
        -C, --ca-cert-path string   specify certificate authority certificate path
        -K, --ca-key-path string    specify certificate authority key path
            --crl-path string       specify crl file path
            --crt-path string       specify crt file path
        -h, --help                  help for crl
      

      示例

      $ ./cmc cert crl -C ./ca.crt -K ca.key --crl-path=./client1.crl --crt-path=../sdk/testdata/crypto-config/wx-org1.chainmaker.org/user/client1/client1.tls.crt
      
    • 生成csr文件

      参数说明

      $ ./cmc cert csr -h
      Create certificate request
      
      Usage:
        cmc cert csr [flags]
      
      Flags:
        -c, --cn string         specify common name
        -h, --help              help for csr
        -k, --key-path string   specify key path
        -n, --name string       specify storage name
        -o, --org string        specify organization
        -O, --ou string         specify organizational unit
        -p, --path string       specify storage path
      

      示例

      $ ./cmc cert csr -c wx-org1.chainmaker.org -k ../sdk/testdata/crypto-config/wx-org1.chainmaker.org/user/client1/client1.tls.key -n client1.csr -p ./ --ou root-ca -o wx-org1
      
    • 颁发证书

      参数说明

      $ ./cmc cert issue -h
      Issue certificate
      
      Usage:
        cmc cert issue [flags]
      
      Flags:
        -C, --ca-cert-path string   specify certificate authority certificate path
        -K, --ca-key-path string    specify certificate authority key path
        -r, --csr-path string       specify certificate request path
        -H, --hash string           specify hash algorithm
        -h, --help                  help for issue
            --is-ca                 specify is certificate authority
        -n, --name string           specify storage name
        -p, --path string           specify storage path
      

      示例

      $ ./cmc cert issue -C ca.crt -K ca.key -r client1.csr -H sha256 -n client1.crt -p ./
      
    • 根据证书获取节点Id

      参数说明

      $ ./cmc cert nid -h
      Get node id of node cert
      
      Usage:
        cmc cert nid [flags]
      
      Flags:
        -h, --help                    help for nid
            --node-cert-path string   specify node cert path
      

      示例

      $ ./cmc cert nid --node-cert-path=../sdk/testdata/crypto-config/wx-org1.chainmaker.org/node/consensus1/consensus1.tls.crt
      node id : QmcQHCuAXaFkbcsPUj7e37hXXfZ9DdN7bozseo5oX4qiC4
      
  • 查询链配置

    $ ./cmc client chainconfig query \
    --sdk-conf-path=./testdata/sdk_config.yml \
    --org-id=wx-org1.chainmaker.org \
    --client-crt-file-paths=./testdata/crypto-config/wx-org1.chainmaker.org/user/client1/client1.tls.crt \
    --client-key-file-paths=./testdata/crypto-config/wx-org1.chainmaker.org/user/client1/client1.tls.key
    
  • 更新链配置(出块时间间隔)

    $ ./cmc client chainconfig block updateblockinterval \
    --org-id=wx-org1.chainmaker.org \
    --client-crt-file-paths=../sdk/testdata/crypto-config/wx-org1.chainmaker.org/user/client1/client1.tls.crt \
    --client-key-file-paths=../sdk/testdata/crypto-config/wx-org1.chainmaker.org/user/client1/client1.tls.key \
    --sdk-conf-path=../sdk/testdata/sdk_config.yml \
    --admin-crt-file-paths=../sdk/testdata/crypto-config/wx-org1.chainmaker.org/user/admin1/admin1.tls.crt \
    --admin-key-file-paths=../sdk/testdata/crypto-config/wx-org1.chainmaker.org/user/admin1/admin1.tls.key \
    --block-interval 1000