在之前的一篇文章中,我学习了ref_block_num
以及ref_block_prefix
两个transaction中需要设置的内容,而且这个两个内容还有个学名叫:TaPos(Transaction as Proof of Stake)。
(图源 :pixabay)
在学习这个内容的之前,我用一个取巧的方法来设置这两个值:
取最近的一个块中的一个transaction,然后取出其中的
ref_block_num
以及ref_block_prefix
来设置我的transaction。
大部分情况,这个操作就是好用的,但是偶尔会出现错误,为什么有的好用有的就会出错呢?
另外,我还曾设想,既然TaPos,引用的是之前的一个块,那么是否我的程序中可以一直用固定的ref_block_num
以及ref_block_prefix
值呢?
在学习了相关内容之后,我知道为什么我取巧的方法时灵时不灵,我也知道了我用固定的ref_block_*
值的想法有多么可笑。
这一切都可以用如下代码来解释:
也就是说ref_block_num
的类型是uint16_t
,也就是说两个字节长度的无符号整数,取值范围为0
到0xFFFF
,换句话说,只能引用最近65536个块
,超出这个范围,hash值ref_block_prefix
就会对不上了。
我们来做一下测试,取出当前head_block_number,然后减去0xFFFF
后,用对应的块做为输入来生成ref_block_num
以及ref_block_prefix
两个参数,然后设置测试用的transaction并进行广播。
我会发现这样计算出来的结果时而成功时而不成功,之所以有时候不成功,我猜测是当我广播时头块已经又前进了一个,所以,实际我们引用的已经是65536个块之外的块了。
如果引用dgp["head_block_number"] - 0xFFFF + 1
,则每次广播都是成功的:
反之,如果引用dgp["head_block_number"] - 0xFFFF - 1
,则每次广播都是失败的,部分错误信息如下:
其中关键的信息就是:
‘message’: ‘transaction tapos exception’
所以引用别人的transaction中的ref_block_*
数据以及使用固定的ref_block_*
数据都是不靠谱的想法。
那么时间上,我们到底可以引用多久之前的块呢?我们知道HIVE/STEEM出块周期是3秒一个,0xFFFF
个块换算成时间是0xFFFF*3/3600/24
大概是2.28天,大概54个小时多一些。
EOS上才用差不多的机制,但是EOS是0.5秒出块周期,那么换成成时间的话就是约0.37天,9个小时多一些。
所以还是老实地使用head块或者最近不可逆块来生成TaPos信息吧,或者学steem-python,用head块再往前数三个,也不错。
相关链接
This page is synchronized from the post: ‘每天进步一点点:TaPos 以及我们可以引用多久之前的块?’