简介
本篇我们开始来为后续合约开发做准备了,先来说说EOS内置的系统合约的功能吧,本篇将侧重于合约表数据的查询,这将有利于我们理解EOS的功能,并可以进行必要的数据查询。
系统合约介绍
系统合约的代码也是开源的,我们可以在https://github.com/EOSIO/eosio.contracts获得。
- eosio.bios
这个合约是EOS很多基本action的基础系统,所以要保证这个合约的有效执行。这个合约可以让你能够直接控制资源分配,并且有权限访问API。在公链上,这个合约将管理已募集和待募集token,以储备带宽给CPU、内存以及网络活动使用。
默认钱包default内部包含一个默认主密钥的账户eosio,默认的智能合约eosio.bios已经可以使用。
- eosio.token
eosio.token合约提供了代币的发行、分发和交易的功能。这是EOS的默认发行合约及合约账户。
- eosio.msig
msig的意思是multi-signature,多重签名的意思。这个合约是可以支持多方对同一笔交易进行异步签名,它是一个对用户友好的支持多方同意的异步进行提案、批复以及最终发布交易的合约。
- eosio.system
用户可以质押和赎回CPU、NET,还可以投票给BP节点或者设置投票代理;节点可以注册为产块节点,以便参与投票来获得挖矿奖励;用户可以购买和卖出内存,也可以参与EOS账号名竞拍;用户还可以操作REX资源的使用。
该合约直接部署到eosio账户。
- eosio.wrap
特殊情况下可以让BP节点调用,可代替另一账户执行交易。
查询合约表
通过cleos查询合约表,需要使用cleos get table [OPTIONS] account scope table
命令,命令有几个必须参数。
account 合约账号,也就是部署了该合约的账号名。
table 表名,这合约里定义,name类型,所以服务账户名一样的命名规则。
scope 表范围,将table划分成多个区域,在写入数据时确定,查询也需按照存入时填写scope查询,类型为uint64。因为很多默认类型都可以转成uint64,包括name或者symbol等。
OPTIONS 参数有很多,这里重点关注以下几个:-l,—limit 返回数据最大行数,默认10条。
-L,—lower 使用索引查询时的下限值,默认是第一条。
-U,—upper 使用索引查询时的下限值,默认是最后一条。
—index 索引编号,可用数字1、2、3……也可用英文名称first、secondary……
—key-type 索引的key类型,支持(i64, i128, i256, float64, float128, ripemd160, sha256)
这里要说明一下,合约查询默认使用主键索引,所以OPTIONS的参数都不是必须,如果要使用其他索引,也就是指定—index为1以外的值时,必须要指定改索引的类型,即—key-type。另外,如果你希望精确查询单条数据,一定要同时制定lower和upper,否则查询范围就是半包的,可能返回期望以外的数据。
eosio.token
这个合约是EOS的官方Token合约,也是众多其他Token的示范,使用和该合约一致的表结构和逻辑,就可以使用通用的余额查询等功能,可以说,这个合约使得EOS上的Token发行变得通用而简单。
- stat
stat表是一个汇总表,记录了所有在该合约上发行的Token的基础信息,包括了发行人、流通量和最大发行量。
我们来查一下主网下EOS的信息,account为eosio.token,table为stat,scope就是Token的符号EOS,其他参数都不用指定。
cleos -u http://eospush.tokenpocket.pro get table eosio.token EOS stat
我们看到,只有一条数据,其实同一个合约其实也可以发行多个Token,只要Symbol(包括符号和小数位)不同。
supply 当前流通量。
max_supply 最大发行量。
issuer 发行账号。
- accounts
那么我们想知道用户持有EOS的情况怎么办呢?直接查询accounts表就行了,这张表的字段只有一个就是balance,表示余额。
我们来查询下b1的余额吧,我们再上一章也查过,这里也再复习一下。account为eosio.token,table为accounts,scope就是账号名,其他参数都不用指定。
cleos -u http://eospush.tokenpocket.pro get table eosio.token b1 accounts
如果我们的合约里发行了多个Token,那么查询时会返回该用户多条Token余额,对应不同的Token。
注意:我们业务中可能经常会用到获取所有用户的余额数据,这个功能在标准Token合约中不能实现,而通过修改合约代码实现可以,也可以通过导出EOS上的节点数据进行查询。
eosio
abihash
我们在发布合约的时候会生成一个abi文件,就是合约的接口文件。而这个abi文件的hash值会存在该表中。
合约内判断账号是否是合约账号
- 背景
去年底火爆一时的eidos合约使得全网资源变得紧缺,网络上就有人开始打其他平台上的合约资源的主意了,他们利用有的合约的某些行为会发起转账的特点,再结合上合约的通知功能,使得一个本来简单的转账操作变成了成百上千次的调用,而消耗的还是平台合约的资源。所以合约内判定转账接收对象是否是合约账号的需求应运而生。
- 使用方法
简单说,就是通过合约内查询eosio账号的abihash表,查询转账用户账号是否有abihash值,只有发布了合约的账号才会有数据。
我们来看看b1是不是个合约账号吧。account为eosio,table为abihash,scope也是eosio,因为我们要精确查询单个账号,所以要设置lower和upper都是账号名b1。
cleos -u http://eospush.tokenpocket.pro get table eosio eosio abihash -L b1 -U b1
没有数据返回,说明b1是个普通账号。
我们再来看看eosio,这个肯定有返回啦。只用修改lower和upper为eosio。
cleos -u http://eospush.tokenpocket.pro get table eosio eosio abihash -L eosio -U eosio
可以看到eosio的hash值了,说明eosio账号是一个合约账号。
userres
我们除了通过账号信息来获取账号的CPU和NET抵押情况,还有账号内存的总量。我们无法直接通过表数据获取到当前账号的资源使用量,因为使用资源是通过设置的窗口期查询数据库表数据得出的,是动态数据,且不存在与合约表中。
我们来查询一下b1的资源使用吧。account为eosio,table为userres,scope就是账号名b1,其他参数都不用指定。
cleos -u http://eospush.tokenpocket.pro get table eosio b1 userres
owner 账号名
net_weight 抵押的Net。
cpu_weight 抵押的CPU。
ram_bytes 购买的内存量。
voters
如果你需要查询账号的投票情况,包括账号都给哪些产块节点投票了,或者设置了那个代理投票账号,都可以通过这个表查询到。
我们来查询下b1都给谁投票了吧。account为eosio,table为voters,scope还是eosio,指定-L和-U都是b1。
cleos -u http://eospush.tokenpocket.pro get table eosio eosio voters -L b1 -U b1
owner 账号名。
proxy 代理账号。
producers 投票的产块节点列表。
staked 已抵押数,投票数。
last_vote_weight 最后一次投票的比重。用于判断账户是否是第一次投票。
proxied_vote_weight 代理投票的比重。
is_proxy 是否是代理账号。
flags1 保留。
reserved2 保留。
reserved3 保留。
producers
我们如果将自己注册成为了产块节点,那么就能在这个表中查到自己了。我们可以通过这个表查询每个注册的产块节点的信息,包括了BP节点和所有备用节点的信息。
但要说最重要的功能,当然是看投票排名了,这个将决定哪些节点是BP节点可以获得出块奖励,以及查看其他节点的排名情况。
我们直接来查一下当前的前10吧。account为eosio,table为producers,scope也是eosio,这里需要指定使用第2索引,通过源码我们可以知道,第2索引是倒序获得激活节点的投票,double类型对应的key-type是float64。
cleos -u http://eospush.tokenpocket.pro get table eosio eosio producers --index 2 --key-type float64
数据太多了,所以我们只默认查询前10条就好了,如果你需要看完整的BP列表,你可以指定--limit 21
或者更大的值。
owner 节点账号名。
total_votes 获得的总投票数。
producer_key 节点公钥。
is_active 是否已激活。
url 节点配置的主页地址。
unpaid_blocks 尚未领取奖励区块数量。
last_claim_time 最后一次领取奖励的时间。领取间隔时间要大于24小时。
location 节点所在地区码。
refunds
refunds表可以查询账号赎回中的资源情况,我们知道CPU和NET的抵押在赎回的时候有3天的赎回期,所以当你发起赎回后,你的赎回信息就会被记录在合约中,等待3天的延时调用触发(存在这样特殊的情况,就是延时操作失败,那只有手动调用一下退款方法了)。
因为这个数据不是随时都有,所以这次我们不查b1了,临时找了个正在赎回的其他人的账号ha3tonbugege。account为eosio,table为refunds,scope就是账号名ha3tonbugege,其他参数都不用指定。
cleos -u http://eospush.tokenpocket.pro get table eosio ha3tonbugege refunds
每个账号只有有一条数据,如果上一次的赎回还没到时间,你又发起一次赎回,那么很不幸的,两次赎回会被合并为一次,且时间已最后一次为准。你又要多等3天了。
owner 账号名。
request_time 赎回发起的时间。
net_amount 赎回中的NET。
cpu_amount 赎回中的CPU。
其他表
cpuloan/netloadn,如果你使用Rex的功能,你可以通过这两个表查询你的租赁及到期。还有五张表都是和Rex有关的,我们会在Rex章节详细讲解这些表的功能。这些就不细说了。