之前说过前些天有疑似龙卷风吹折了很多路边的树枝,然后我在书房也听到狂风刮过,大汽车驶过一样轰隆隆的声音。
我以为就是狂风挂起垃圾桶啊,树枝啊,还有一些垃圾之类的,没想到几天前无意中往我的后花园一看,发现竟然多了一张大床垫。
我晕,这也是狂风刮来的吗?当然我觉得肯定不是从很遥远的地方刮过来的,也不是从谁家房间里刮出来的,肯定是哪个邻居放后阳台然后被狂风卷走。
这算是大自然的馈赠吗?然而我并不需要啊。要是刮过来点金银珠宝,该有多好啊,然而搜遍了整个后花园,并没有发现哪怕一丁点金银。
让物业帮忙问了一下,哪家邻居床垫丢了,然后物业问过后说没有哪家表示床垫飞走了。于是我只好将其搬运到垃圾桶去了。
顺便把后花园的枯枝败叶清理一下,一把火点燃,化成草木灰会变成其它草木的营养,这才是大自然的馈赠吧。
好在这次点火,外边风不大,也没有物业的安全员过来提示我,等到火彻底熄灭,并浇了一些水之后,我才放心离开。
This page is synchronized from the post: ‘大自然的“馈赠”?’
熬夜到凌晨三四点,所以早晨想多赖在床上一会,咋说的来着,不是我不想起床,而是我被封印到床上了,床不让我起来。
(图源 :pixabay)
然而正做美梦呢,被电话铃声吵醒,一看是一个上海的座机号,想也不想就挂了,一定是什么放贷款的或者什么POS机售后的。
结果过了一个电话孜孜不倦地响起,只好接起来了,竟然是华信证券打来的,说我新股申购中了俩签,让我别忘记缴款。
额,竟然又中签了,之前的每次中签都让我小赚一笔,当然邮储银行除外,不过邮储银行有那个什么绿鞋(好像叫这个名字)保护,也没赔钱。
登录券商APP,果然提示我中签了,还是中了两只股票:
账户里还差9500多元资金:
另外券商也发了N条短信提醒我不要弃购:
【华信证券】尊敬的投资者,您账户中有新股中签需要缴款,目前账户资金不足,请注意今日(4月13日)16:00前在账户中留存足够的资金以免发生弃购。400-820-5999竭诚为您服务!回TD退订
赶紧充值,哈哈:
懒得去查这两个股票对应的公司都是干啥的,但愿能帮我赚点钱吧,最近赔得太惨了。/(ㄒoㄒ)/~~
(图源 :pixabay)
另外新股申购还得检查啊,动动手指,没准就中奖了呢!
This page is synchronized from the post: ‘新股中签啦,一下中俩签’
昨天的文章中介绍了一个序列化(serialized)transaction取巧的办法,就是不在本地进行,而且丢给API节点,让它们去帮忙序列化。虽然序列化的结果肯定是正确的,但是还是要想办法验证一下。
(图源 :pixabay)
因为我们选取的是已经在STEEM/HIVE网络上存在的transaction,那么验证似乎有两个思路可以走,一是对序列化的结果进行签名并对比;二是通过序列化的内容获取摘要,然后从签名中恢复出公钥。
首先,我们来分析签名并对比是否可行?我们知道,如果使用的是ecdsa签名,那么一般会调用如下函数:
def sign_digest(self, digest, entropy=None, sigencode=sigencode_string, k=None)
其中k
是作为nonce的一个随机量,这样相同的密钥相同的信息每次签名出来的结果都不相同,防御了一些猜测私钥的攻击。
尽管我们之前的文章中,用相同的私钥对相同的摘要每次都生成了相同的签名,但是那是为了方便对比将k
设置成了固定的值,而实际生产系统中是不会这样设置的(可能会被计算出私钥)。
因为k
是随机量,所以每次签名得到的字符串都不相同,是没法对比的。
既然对比签名不可行,我们就要用别的方法验证一下序列化的结果是否正确。
我们知道序列化的结果是生成被签名HASH的输入之一,而我们通过被签名的HASH以及签名是可以恢复出公钥的,那么一旦我们恢复出来的公钥和签名用公钥一致,说明序列化这个步骤的结果是正确的。
我们昨天的代码获取了相应transaction的如下序列化结果:
并且transtion中已有签名部分:
'signatures': ['206cdc148d6535899fb43c452656989611c1a01bc84da7e08002bbabcdd7f583091c2b9e3aa3cc0a05c417b4dce4ce8979972b61a218b595f88c0a013bd4bafb95']
接下来我们就用这两部分内容来尝试恢复公钥。
首先,用于生成签名hash的内容就是序列化后的结果吗?答案是否定的,用于生成签名hash的内容是chain_id和序列化结果链接到一起。
STEEEM/HIVE的chain_id定义如下(其实就是256个二进制0):
chain_id = "0" * int(256 / 4)
那么理论上,hash前的内容就是(str_hex
是get_transaction_hex
返回结果):
msg = chain_id + str_hex
然而这样做的结果并不正确,研究了好久发现是get_transaction_hex
返回的内容结尾多了两个0
,所以正确内容应为:
msg = chain_id + str_hex[0:-2]
(关于多出来的00
,详情可以参考,@abit 在bitshares 提交的一个issue)
然后生成摘要:
digest = hashlib.sha256(unhexlify(msg)).digest()
接下来用我们以前文章中恢复公钥的方法/代码来恢复公钥就可以啦。
代码参考我之前文章内的代码就可以,就不浪费篇幅啦。
除了利用从签名恢复公钥来验证序列化结果外,还可以用公钥来验证签名的方式来判断序列化结果的正确与否。
这个方式同样要链接chain_id,代码同样可以参考我以前文章内的代码,同样不多写啦。
用get_transaction_hex
可以获取transaction的序列化后(serialized)的结果,不过要去掉尾巴上的00
才可以。
这算BUG还是算feature?我有些晕,不过好用就好。
signatures
field #1013This page is synchronized from the post: ‘每天进步一点点:验证用get_transaction_hex 获取的HEX’
之前的文章中介绍了,STEEM/HIVE中的签名是对消息Hash的签名,STEEM/HIVE中的消息就是transaction,但是由于transaction中的条目位置不是固定的,所以仅仅是把消息转化成字符串并签名是行不通的。
(图源 :pixabay)
解决这个问题的办法就是对消息当中的内容进行序列化(serialized),无论transtion中内容位置如何变化,并不影响最终生成的二进制串的结果。
然而序列化(serialized)是一个很麻烦的事情,玩STEEM已经三四年了,我还没有把这块搞清楚。不过学习EOS和BTS相关内容的时候,知道两者都可以通过RPC API获取transtion序列化的结果。
好在,STEEM/HIVE当中也有类似的API,那就是:
condenser_api.get_transaction_hex
Returns a hexdump of the serialized binary form of a transaction.
或者使用database_api.get_transaction_hex
两者本质是一样的,只是暴露在不同的API接口中。
这个API的使用方法和其它的并无什么本质区别,所以按着我们以往使用方法使用即可。
同样以之前我们示例中的以transaction为例:
在获取这个tx,我们得到类似如下的数据:
因为block_num、transaction_id、transaction_num以及signatures内容本身并不参与序列化,所以我们可以把他们去掉(其实不去掉也无所谓,服务器端会帮我清理):
然后我们得出如下json数据:
{"jsonrpc": "2.0", "method": "condenser_api.get_transaction_hex", "params": [{"ref_block_num": 21449, "ref_block_prefix": 4231435724, "expiration": "2020-04-08T09:44:27", "operations": [["vote", {"voter": "oflyhigh", "author": "deanliu", "permlink": "9fdbg", "weight": 10000}]], "extensions": [], "signatures": []}], "id": 1}
向RPC节点POST上述数据:
curl -s --data '{"jsonrpc": "2.0", "method": "condenser_api.get_transaction_hex", "params": [{"ref_block_num": 21449, "ref_block_prefix": 4231435724, "expiration": "2020-04-08T09:44:27", "operations": [["vote", {"voter": "oflyhigh", "author": "deanliu", "permlink": "9fdbg", "weight": 10000}]], "extensions": [], "signatures": []}], "id": 1}' https://api.hive.blog
格式化后的返回结果为:
其中c953cc9536fcfb9c8d5e0100086f666c7968696768076465616e6c697505396664626710270000
就是我们要的序列化结果啦。
如何验证这个序列化结果是争取的呢?下篇文章我们再做分析。
使用这个RPC API会大幅减轻我们客户端程序的编码工作量。
不过这个东西有两个弊端,一个是效率问题,多增加一次网络访问;另外一个就是安全问题,恶意的API节点可以替换内容,发起攻击。
This page is synchronized from the post: ‘每天进步一点点:用get_transaction_hex 序列化transaction’
半夜11点的时候,刚刚关闭电脑,熄灯准备入睡,可是困意刚起就听到耳旁有蚊子嗡嗡嗡煽动翅膀的声音,顿觉毛骨悚然。
(图源 :pixabay)
你可能会说,用毛骨悚然有些夸张了吧?不过是一只小小的蚊子而已。不过还真不是夸张,一只小小的蚊子往往可以让我一晚无法安睡。
经常有这样的经历,刚迷蝴听到蚊子嗡嗡声,然后起床开灯找蚊子,找了半天没有找到,熄灯睡觉,然后嗡嗡声又在耳边想起。
更悲惨的是,有时候,明明找到了蚊子,或者在空中飞行,或者停到墙壁上,然后果断一击,明明觉得自己已经成功,然而没有发现被击落的残骸,过一会嗡嗡声又来。
还有的时候,眼看就要成功击毙蚊子,结果丫飞到床底下、办公桌后边、衣柜和墙壁的缝隙里,无论如何呼唤也不肯探头,徒呼奈何。
有时候想想,舍出自己的鲜血吧,当年佛祖割肉饲鹰,我难道连一两滴血也舍弃不了吗?这样想想,打算蒙头大睡。
然而蚊子并不会因此而感激,只要手脚什么露出来,他就会在诸如指关节部位饱餐一顿,然后再脚心部位饱餐一顿,弄个身上好几个包,奇痒无比。
话说,你就餐就不能好好就餐吗?在一个部位难道还不能让你吃饱?非要不停的换地方,这让我如何保持佛祖淡定的心态。
于是只能抗争,哪里有压迫,哪里就有反抗,被一个小小蚊子欺负成这样,也是醉了。不过好在我有了大规模杀伤武器——电蚊拍。
找来找去,终于发现蚊子的踪迹了,电蚊拍一挥,啪的一声,耶成功!
(图源 :pixabay)
为了防止蚊子死得不彻底,继续按电蚊拍工作按钮,啪啪啪,电火花闪耀,一种蛋白质燃烧特有的焦糊味出来,啊,呼吸着空气中的焦糊味,睡的会更加安稳和香甜。
This page is synchronized from the post: ‘灭蚊记’
Update your browser to view this website correctly. Update my browser now
咋玩呀,哈哈 This page is synchronized from the post: 咋玩? document.querySelectorAll('.not-gallery-item') .forEach(el => { if (!el.dataset.src) { return; } c
十几年前,因为工作的缘故接触Linux系统。 作为Windows盗版系统的“受益者”,除了学校《操作系统》课程接触的ls、cd、dir、pwd等几个有限的命令,实在是想不起再多的内容了。IBM社区上有一些很经典的Linux系统教程,不得不说从中受益匪浅。然而,工作需要,系统的了解和学习依旧迫在眉睫。
Almost all of the articles are illustrated on Steemit.So I try to figure out how to insert pictures in steemit articles? Then I found two ways: (Maybe
当年错失参与比特币的大好时机,时也命也! 往者不可谏,来者犹可追。按照X网几位比特币和区块链技术的布道者,steemit.com有望成为新的一轮革命。 作为一枚懒散的宅男,是拒绝接受新事物的(其实本质是懒)但是眼见着铺天盖地的讨论,各种前景展望,内心无法保持波澜不惊了。 对赚钱的期望有,但不是那么强
作为一个社交媒体平台,内容毫无疑问是最重要的元素。想象如果这个平台充斥着广告、水贴、色情与暴力等垃圾信息,那么想必离死亡非常接近了。 作为去中心化的平台,尽管顶贴(点赞)等机制会尽量筛选出优质内容呈现在我们眼前,但作为参与的每一个个体,都应当尽量去生产有价值的内容。如果参与者不但会从发文、点赞等行为