大自然的“馈赠”?

之前说过前些天有疑似龙卷风吹折了很多路边的树枝,然后我在书房也听到狂风刮过,大汽车驶过一样轰隆隆的声音。

我以为就是狂风挂起垃圾桶啊,树枝啊,还有一些垃圾之类的,没想到几天前无意中往我的后花园一看,发现竟然多了一张大床垫。

我晕,这也是狂风刮来的吗?当然我觉得肯定不是从很遥远的地方刮过来的,也不是从谁家房间里刮出来的,肯定是哪个邻居放后阳台然后被狂风卷走。

image.png

这算是大自然的馈赠吗?然而我并不需要啊。要是刮过来点金银珠宝,该有多好啊,然而搜遍了整个后花园,并没有发现哪怕一丁点金银。

让物业帮忙问了一下,哪家邻居床垫丢了,然后物业问过后说没有哪家表示床垫飞走了。于是我只好将其搬运到垃圾桶去了。

image.png

顺便把后花园的枯枝败叶清理一下,一把火点燃,化成草木灰会变成其它草木的营养,这才是大自然的馈赠吧。

好在这次点火,外边风不大,也没有物业的安全员过来提示我,等到火彻底熄灭,并浇了一些水之后,我才放心离开。

image.png


This page is synchronized from the post: ‘大自然的“馈赠”?’

新股中签啦,一下中俩签

熬夜到凌晨三四点,所以早晨想多赖在床上一会,咋说的来着,不是我不想起床,而是我被封印到床上了,床不让我起来。


(图源 :pixabay)

然而正做美梦呢,被电话铃声吵醒,一看是一个上海的座机号,想也不想就挂了,一定是什么放贷款的或者什么POS机售后的。

结果过了一个电话孜孜不倦地响起,只好接起来了,竟然是华信证券打来的,说我新股申购中了俩签,让我别忘记缴款。

额,竟然又中签了,之前的每次中签都让我小赚一笔,当然邮储银行除外,不过邮储银行有那个什么绿鞋(好像叫这个名字)保护,也没赔钱。

登录券商APP,果然提示我中签了,还是中了两只股票:

image.png

账户里还差9500多元资金:

image.png

另外券商也发了N条短信提醒我不要弃购:

【华信证券】尊敬的投资者,您账户中有新股中签需要缴款,目前账户资金不足,请注意今日(4月13日)16:00前在账户中留存足够的资金以免发生弃购。400-820-5999竭诚为您服务!回TD退订

赶紧充值,哈哈:

image.png

懒得去查这两个股票对应的公司都是干啥的,但愿能帮我赚点钱吧,最近赔得太惨了。/(ㄒoㄒ)/~~


(图源 :pixabay)

另外新股申购还得检查啊,动动手指,没准就中奖了呢!


This page is synchronized from the post: ‘新股中签啦,一下中俩签’

每天进步一点点:验证用get_transaction_hex 获取的HEX

昨天的文章中介绍了一个序列化(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的如下序列化结果:

image.png

并且transtion中已有签名部分:

'signatures': ['206cdc148d6535899fb43c452656989611c1a01bc84da7e08002bbabcdd7f583091c2b9e3aa3cc0a05c417b4dce4ce8979972b61a218b595f88c0a013bd4bafb95']

接下来我们就用这两部分内容来尝试恢复公钥。

首先,用于生成签名hash的内容就是序列化后的结果吗?答案是否定的,用于生成签名hash的内容是chain_id和序列化结果链接到一起。

STEEEM/HIVE的chain_id定义如下(其实就是256个二进制0):

chain_id = "0" * int(256 / 4)

那么理论上,hash前的内容就是(str_hexget_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?我有些晕,不过好用就好。

相关链接


This page is synchronized from the post: ‘每天进步一点点:验证用get_transaction_hex 获取的HEX’

小猫的日常

image.png

小区的一家小花园里有好几只流浪猫,虽然是流浪猫但是热心的邻居给准备了猫窝和猫粮,又可以在小花园里玩耍,过得相当滋润呢。

拍了一些小猫的日常照片,有思考猫生的,有挠树的,有细嗅蔷薇(树叶)的,有匍匐前进捉蝴蝶的……

image.png

image.png

image.png

image.png

image.png

image.png

image.png

image.png

image.png

image.png

image.png

好想养一只这样的小猫,不过想想弄到家里养着,和它们自由自在在户外生存玩耍,好像后者更好一些呢。


This page is synchronized from the post: ‘小猫的日常’

每天进步一点点:用get_transaction_hex 序列化transaction

之前的文章中介绍了,STEEM/HIVE中的签名是对消息Hash的签名,STEEM/HIVE中的消息就是transaction,但是由于transaction中的条目位置不是固定的,所以仅仅是把消息转化成字符串并签名是行不通的。


(图源 :pixabay)

解决这个问题的办法就是对消息当中的内容进行序列化(serialized),无论transtion中内容位置如何变化,并不影响最终生成的二进制串的结果。

然而序列化(serialized)是一个很麻烦的事情,玩STEEM已经三四年了,我还没有把这块搞清楚。不过学习EOS和BTS相关内容的时候,知道两者都可以通过RPC API获取transtion序列化的结果。

get_transaction_hex

好在,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为例:

image.png

在获取这个tx,我们得到类似如下的数据:

image.png

因为block_num、transaction_id、transaction_num以及signatures内容本身并不参与序列化,所以我们可以把他们去掉(其实不去掉也无所谓,服务器端会帮我清理):

image.png

然后我们得出如下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

格式化后的返回结果为:

image.png

其中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: ‘灭蚊记’

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×