这篇文章我将着重介绍命令行钱包相关操作,以及各种基础错误的意思,同时我还将介绍如何快速搭建钱包服务器,使自己在bitshares交易中,快人一步。
往期文章:
首次启动命令行
启动命令在上一篇文章中已经介绍过了,但是这里为了连贯性,就再重复一遍
./cli_wallet --server-rpc-endpoint=ws://127.0.0.1:8056 --chain-id=baf152712ac44cf347702b32ebaea7674295b7f023ca96f99b5039f1f782279e
启动后会在命令行窗口中发现
Please use the set_password method to initialize a new wallet before continuing
new >>>
这个标志着命令行钱包是第一次启动,或者没有找到启动时所在文件夹下对应的wallet.json(cli钱包文件:里面加密保存了你之前导入过的账户和私钥),接下来我们需要做的就是执行它给出的提示
set_password 123456
#123456 在这里为下次重新进入钱包时候需要输入的密码,cli_wallet这里用这个密码给你的钱包文件中的私钥部分做一次AES加密
命令行提示就会变成这个
lock >>>
一般情况下,密码不是太过复杂的话,直接就会成功,这个返回值是一个null。密码太复杂有时候会报错,这个希望解决的话就只能从源代码层面修复了,不过如果是本地的话,可以设置一个相对简单一点的密码,因为毕竟这个文件不会随便就给别人
unlock 123456
#这一步标志着需要解锁钱包(所有需要私钥的相关操作均需先对钱包进行解锁操作)
如果你的密码没有错误的情况下,解锁基本是成功的,命令行一般会返回如下提示
unlock >>>
现在也就是到钱包的最后一步了,也就是将自己的私钥导入到钱包中
import_key "你的用户名" "你的私钥"
#这里不论用户名是正确还是错误的情况下命令行都会提示你钱包备份
#成功会提示true 失败会提示false或者其他的报错信息
标准启动命令行
这里的标准的意思是,已经设置过密码,并且导入过私钥了,后再次启动命令行钱包
这里只需要做一步操作,就是用首次启动时候的密码解锁钱包就可以了
命令行钱包账户操作
下面包含了许多命令以及对应的解释
- 转账
#转账的参数 依次是 命令 transfer 转账发起者 转账接收者 转账数量 转账币种名称 转账备注(如果没有备注也需要传"") 是否广播
#其中是否广播这个字段一般都需要填true(不广播的意思就是只是在本地中生成这个交易,但是并不将这个交易推送到见证人节点上,也就是说交易并没有生效)
transfer "test" "test1" 100 BTS "" true
- 挂单
个人觉得bitshares区块链这个的命令非常坑,用起来总感觉非常怪
挂单无论买卖统一都是调用一个接口,不同就是买卖的时候传的币种是相反的
#挂单的参数依次是 命令 sell_asset 挂单账户 希望卖出数量 希望卖出币种 最少希望得到数量 最少希望得到币种 超时不成交撤单时间(单位:s) 允不允许多单成交 是否广播
sell_asset test 100 BTS 100 CNY 86400 true true
- 抵押|借入
每个用户只能拥有一次抵押,如果当次做过抵押后,下一次只能更新本次抵押,在本次抵押没有彻底还清之前,所做的抵押只能是更新当前抵押。这个不是很好理解对吧
#借入的参数依次是 命令 borrow_asset 借入账户名称 借入数量 借入币种数量 抵押数量 是否广播
borrow_asset test 100 CNY 100 true
下面我举个栗子🌰:
假如说用户test首次调用该命令
borrow_asset test 100 CNY 111 true
在这次他抵押了111个BTS并且换回了100个CNY
接下来他再次调用该命令
borrow_asset test 100 CNY 111 true
他又抵押了111个BTS然后换回了100个CNY
结合第一次的命令,他拥有的CNY和抵押BTS分别是200个和222个
假如说这阵他想将自己的债务偿还该怎么做呢?
还是调用该命令,只不过是将两个数量传成负数的
borrow_asset test -200 CNY -222 true
这样之后他就没有债务了,债务调整也就是通过传入数值的正负来进行额度的相关调整
- 升级会员
比特股中,几乎所有操作都需要收取手续费,手续费的一定比例会返回给这个账户的注册人,以及推荐人。升级终身会员后,原本要返回的手续费会返还给自己。同时终身会员也是成为理事会成员与见证人的前提条件
升级会员还有一个选项叫季度会员,但这个会员的相关情况我没有进行过什么研究,如果有知道的同学可以跟我说说
#升级终身会员的参数 命令 upgrade_account 需要升级账户名 是否升级成终身会员 是否广播
upgrade_account test true true
- 注册新用户
注册新用户的时候并不需要新用户的私钥,但是需要的是注册人与邀请人必须都是终身会员。同时请注意,注册新用户的时候也是需要花费手续费的,并且注册用户的用户名 包含a e i o u y中的任何一个字符的时候都将收取更多的手续费,具体的手续费数量将由区块链参数决定
#注册新用户的参数 命令 register_account 注册的账户名 账户权限公钥 账户操作权限私钥 注册人 推荐人 注册人与推荐人之间的分成 是否广播
register_account test BTS54Af8hHnJntdL1gnDBzPwmKh4GayHoQyncouBu6fJbAhCLuuwJ BTS54Af8hHnJntdL1gnDBzPwmKh4GayHoQyncouBu6fJbAhCLuuwJ register register 100 true
命令行钱包查询操作
我们作为区块链上的一个用户,很多时候需要查询区块链的相关信息,以方便做出我们的决策。在这里只是将这些操作给出,如果不是必须要通过这些命令查询,请在网页端执行相关操作,网页能带来更详细的数据分析与相对体验。
- 账户历史记录查询
#查询账户历史 命令 get_account_history 需要查询的用户名 查询的条数
get_account_history test 100
调用命令行请求返回的是cli钱包美化过的数据。返回会描述什么时间做过什么操作(如果查询转账备注,则至少需要向cli提前导入交易双方的任意一方私钥)
注:这个查询相对较慢,因为查询所有记录会连带着查询对应的账户信息等等
- 获取借入信息
通过这条命令能查询出当前还存在的借入信息,返回的是json数据,cli并未对这条命令做美化,所以我们通过命令行查看的都是原始数据。
#获取借入信息 命令 get_call_orders 币种名称 查询单数
get_call_orders CNY 100
这里我会展示测试链的数据并大致解释每个字段的含义,我展示的数据不具有任何实际意义
[{
"id": "1.8.6",
"borrower": "1.2.1909",
"collateral": "19999996000000",
"debt": "1000000000000",
"call_price": {
"base": {
"amount": 4999999,
"asset_id": "1.3.0"
},
"quote": {
"amount": 437500,
"asset_id": "1.3.1"
}
}
},{
"id": "1.8.0",
"borrower": "1.2.1019",
"collateral": 33333000,
"debt": 1000000,
"call_price": {
"base": {
"amount": 33333,
"asset_id": "1.3.0"
},
"quote": {
"amount": 1750,
"asset_id": "1.3.1"
}
}
}
]
id:订单编号
borrower:借入发起人
collateral:借入金额(需要除以币种精度位)
debt:抵押金额(需要除以币种精度位)
call_price(借入价格):需要用户自己去做除法进行计算最终真实价格(都需要除以有效精度)
- 获取撮合交易挂单记录
对于自动交易机器人而言,需要最多的就是查询区块链撮合市场信息,以探知区块链市场深度。
#获取撮合交易挂单记录 命令 get_limit_orders 交易币种A 交易币种B 获取单数
get_limit_orders BTS CNY 100
返回字段:
{
"id": "1.7.6475",
"expiration": "2019-07-07T00:39:44",
"seller": "1.2.1626",
"for_sale": "29300000000",
"sell_price": {
"base": {
"amount": "29300000000",
"asset_id": "1.3.0"
},
"quote": {
"amount": "439500000000",
"asset_id": "1.3.1"
}
},
"deferred_fee": 0
}
id:订单编号
expiration:订单到期时间
seller:卖出人
for_sale:卖出金额(需要除以币种精度位)
sell_price(借入价格):需要用户自己去做除法进行计算最终真实价格(都需要除以有效精度,同时买单卖单也需要由用户去分辨,通过比较base和quote的asset_id去判断这个究竟属于什么)
- 获取当前区块链拥有资产
区块链提供了查询资产的一个命令,这个命令对于我们还是很友好的
#获取资产 命令 list_assets 查询全部填(具体意思暂时不明)"" 查询数量(最大100条)
list_assets "" 100
其中中间的那个字符串参数含义暂时不明,需要随后再进行研究
[{
"id": "1.3.2",
"symbol": "BTC",
"precision": 8,
"issuer": "1.2.6",
"options": {
"max_supply": "1000000000000000",
"market_fee_percent": 0,
"max_market_fee": 0,
"issuer_permissions": 463,
"flags": 0,
"core_exchange_rate": {
"base": {
"amount": 280000,
"asset_id": "1.3.0"
},
"quote": {
"amount": 1000,
"asset_id": "1.3.2"
}
},
"whitelist_authorities": [],
"blacklist_authorities": [],
"whitelist_markets": [],
"blacklist_markets": [],
"description": "",
"extensions": []
},
"dynamic_asset_data_id": "2.3.2",
"bitasset_data_id": "2.4.0"
}]
id:资产id
symbol:资产符号
precision:资产有效位数
issuer:资产发行人账户
options:资产相关信息(资产最大供应量,手续费池兑换比例,操作权限)
dynamic_asset_data_id:动态资产标志
bitasset_data_id:这个字段标志着资产是否是智能资产,如果有则说明这个资产是智能,否则就不是
- 查看账户余额
#查看账户余额 命令 list_account_balances 查看账户名 查看币种(最大100条)
list_account_balances test 100
这个的返回值很简单,就不过多赘述
- 查看钱包已导入账户
list_my_accounts
- 查看已导入的账户私钥
dump_private_keys
- 查看区块链信息
这个方法可以说是区块链里的万能方法,几乎可以查询区块链中的一切,只要你想知道
get_object x.x.x
在上面我展示的示例中有许多1.x.x的,所有这一类id在区块链中统一标志为区块链的事物,不论是账户,还是资产,所有的东西都拥有着自己的id,只要通过get_object + 对应id 就可以看到这个id代表的详细意思了。返回值就不多说了,根据区块链信息而做相应返回
钱包服务器启动
命令行钱包就我个人认为更多的是用来帮助我们构建自有机器人的,或者基于它之上构建一些上层app,以及操作一下ui端未提供的底层api
我们在这里可以很轻松的就用命令行钱包启动成一个支持http请求的一个服务器,我们可以用cli自建交易所对接|以及自动化买单卖单机器人
启动它也很简单,只需要在标准cli启动命令中增加一个参数 --rpc-http-endpoint=127.0.0.1:8111 就可以启动一个只对内网开放8111端口的服务器
注:在绝大多数情况下,请不要将钱包服务器端口开放成0.0.0.0因为这个非常危险,相当于将私钥暴露给了一个任何能访问到你的服务器的人。
#备注:如果希望钱包能一直启动在后台,我提供一个新的启动命令
nohup ./cli_wallet --server-rpc-endpoint=ws://你希望连接的节点地址 --chain-id=你希望连接的链id --rpc-http-endpoint=127.0.0.1:8111 &
#其中,nohup + & 标志着希望cli在后台运行
一旦采用后台方式启动cli,则无法再通过命令行方式对钱包进行操作,一切操作cli只能走标准的httpPost请求;如果希望能让cli同时支持前台命令行参数,与后台http请求方式,在这里我给出一个新的方案。linux里有一个软件包叫screen,通过screen启动命令行后即可支持前后台同时运行。(cli命令为串行模式,也就是说在后台的请求接口尚未返回前,前台调用的操作将不会响应)
启动说完了,下一步将会说明如何通过http请求调用cli
首先标准的http协议我就不缀述了,cli支持的协议也是非常标准的http协议。
cli需要用户在post请求的body中传的参数是一个json串,header中添加Content-Type为application/json
上传json基础参数
{
"jsonrpc":"2.0",//固定参数,也可不传此字段
"method":"",//这个字段为命令行中对应操作的参数如查询账户历史记录就是get_account_history
"params":[],//这个字段就是命令行中各个字段的具体参数,为数组类型,将命令行中原有参数依次填入即可,如查看账户历史记录则是["test",100]
"id":1//这个字段标志着cli返回时的具体id
}
区块链的返回也是json
{
"id":1,//上传时候的标志位
"result"://这个里面返回了命令行中未美化过的数据,具体内容由用户传入的参数决定
}
这个需要每个人自己多去尝试,目前作者发现同一时间内的请求最好不要太多,cli支持不了大并发,但是对于批量转账,等等的一些其他的功能,cli支持的还是挺好的
标准异常说明
在操作中,我们总会看见cli返回这样或者那样的错误。在这里,作者总结出一些较为常见的错误,如果你们在交易中发现了相关错误代码,可以在这里用ctrl+f搜索一下关键字
- 缺少相关参数
10 assert_exception: Assert Exception
a0 != e: too few arguments passed to method
这个问题解决起来很容易,一般出现在比如这个操作需要2个参数 比如
list_account_balance test 100
需要两个参数分别是test和100,但是只传了一个参数进去,cli就会报这个错误
解决方案:将参数填齐即可
- 钱包解锁失败
18 aes_exception: AES error
error during aes 256 cbc decrypt final
这个错误一般只出现在unlock中,意思就是unlock的密码和最开始set_password的密码不一样
解决方案:输入正确密码
- 钱包已锁定
10 assert_exception: Assert Exception
!self.is_locked():
报错信息是钱包尚未解锁
解决方案:需要调用unlock
- 找不到用户
10 assert_exception: Assert Exception
rec && rec->name == account_name_or_id:
这个问题发生概率很高,因为有时候人填写命令的时候经常会出错,出现这个问题的原因一定是对应需要填写用户名的地方填写有误。
解决方案:仔细查看对应账户,修改正确即可
- 缺少必要权限
Caught exception while broadcasting tx 0432daa02f98efc2258c40ebf9b538444eaa65e3: 0 exception: unspecified
missing required active authority: Missing Active Authority 1.2.25
这类问题一般都会返回missing required xxx authority:后面+上一个1.2.xx的信息,这种情况一般是import_key出错了,也有一些其他原因,但基本上不会出现于命令行钱包中
解决方法:首先调用get_object 查看对应账户,然后将对应账户私钥导入钱包即可解决大部分的此类问题
- 账户余额不足
Caught exception while broadcasting tx 46778625acf1e03f28bebbec1f976a418251ec01: 0 exception: unspecified
Assert Exception: insufficient_balance: Insufficient Balance: 0 BTS
这个问题出现的原因就是余额不足
解决方案:充钱,充值就好了
文终总结
cli上还有许多东西没有讲解,比如创建资产,以及其他的一些操作。
创建cli服务器的时候一定要注意,尽量==不要对全网公开,危险性极高==
关于错误提示,提示小段文字的时候一般是在cli端校验出错;大段文字基本上就是本地cli校验通过,而区块链见证人节点校验失败
最后,cli只是bitshares官方的一个c++用户端程序,它有很多自身的缺陷。下一篇我会讲一讲如何增加一个自己定义的cli方法
还是上一篇一样,推广一下自己的java库,bitsharesWallet如果有想做bitshares相关的java服务器,可以采用这个试试