新春大吉! 发祝福,1 SBD点赞红包放送 (共30 SBD) / 活动圆满结束 😀

一转眼从鸡年进入到狗年啦,要说微信上、QQ上最热门的话题是啥?不是年夜饭吃了什么山珍海味,也不是初一凌晨放了多少烟花,而是红包、红包、红包!


(图源 :pixabay)

话说微信群里朋友太能抢了,有一个五百人的群,每次100个红包,都是几秒钟抢完。每次看到红包出现都倍激动,但是打开后都是提示我红包已抢完,失望了无数次以后,我默默的点了退群按钮。

还好有些朋友间的老微信群,就比较正常了,每次十个二十个的红包,基本也能轮到我。昨晚盯着好几个微信群,抢到了几十块钱的红包,当然也发出去不少,最重要的,就是图个热闹嘛。

既然微信群、QQ群都因红包热闹起来,那么就在STEEMIT上也热闹一下,就在STEEMIT上发些点赞红包吧。

活动规则

  • 限华语用户参加
  • 在本贴下回复给大家的祝福语(中文)
  • 符合规则的将会得到我价值 1 SBD(点赞时)的点赞
  • 每个用户可以回复多条,但是只有一条可以收到奖励
  • 限前30名

其它说明

我准备开发给半自动程序帮我计算金额处理点赞,程序还没开工,所以回复可能点的不及时,但是我预计2、3个小时内应该可以写好,大家不要着急😀

程序的思路和部分代码都现成的,就是通过计算奖励池情况以及我的有效SP和Voting Power,据此计算出我当前的一票能顶出多少SBD。然后换算出,一个SBD需要多少百分比的赞。

我以前弄过一个卖赞小鱼,就是这个思路:《也来试试点赞小鱼,仅仅是测试,限时开放[截止当日(7月12日)北京时间22点],快来玩吧》。但是卖赞小鱼处理的是用户给我转款,与这次点赞红包放送方式不一样,嗯,我改成监控我某个id,然后跟点比较好。

1 SBD并不多,大家热闹热闹,图个开心。

在这祝大家新春大吉,万事如意啊。好了,不多说啦,开始啦,我也要去弄程序去啦。


(图源 :pixabay)


This page is synchronized from the post: 新春大吉! 发祝福,1 SBD点赞红包放送 (共30 SBD) / 活动圆满结束 😀

除夕快乐,公众号的BUG改掉了(查询剩余带宽,查询SP Delegations)

早晨有朋友说公众号没法查用户的带宽使用情况了,也没法查SP代理啦。其实呢,这个问题我昨天就发现啦,一直没来得及改,晚上终于抽出来时间解决一下啦。


(图源 :pixabay)

其实呢,公众号没出BUG,但是为啥原本好用的功能不好用了呢,其实这是一个好消息,就是STEEM出0.19.4版本啦。想了解0.19.4版本都有啥变化,可以去看看 @steemitdev 的帖子: AppBase: The next step forward for the Steem blockchain (let the testing begin)

但是这个升级呢,也带来了一些和老版本程序的不兼容,以及一些BUG,恰巧我用的节点被升级到了新版本,所以工作号当然一些功能不好用啦。

这时候其实有个选择就是我用回低版本的节点,但是低版本的节点早晚要升级,要面对这么问题不是嘛,那么就及时勇敢的面对吧。

带宽查询

对于带宽查询问题,我看了一下STEEM的代码,原本一些系统参数,名称类似:STEEMIT_BLOCK_INTERVAL、STEEMIT_BANDWIDTH_PRECISION、STEEMIT_BANDWIDTH_AVERAGE_WINDOW_SECONDS等,现在都改成了STEEM_BLOCK_INTERVAL、STEEM_BANDWIDTH_PRECISION、STEEM_BANDWIDTH_AVERAGE_WINDOW_SECONDS类似这样的样子,后者无疑更为合理,但是原本使用这些参数的程序都要修改啦。

按照这个思路去改带宽计算的程序,改好后一切正常啦。

SP代理查询

SP代理的程序并没有出错,但是公众号却返回超时,这是怎么一回事呢?经过我对比,这应该是0.19.4的一个BUG,0.19.4版本的node,get_vesting_delegations返回无关的内容

说明如下:

JSON数据

{"jsonrpc": "2.0", "method": "call", "params": ["database_api", "get_vesting_delegations", ["oflyhigh", "", 10]], "id": 1}

返回结果

0.19.2 版本的节点
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
{'id': 1,
'result': [{'delegatee': 'eval',
'delegator': 'oflyhigh',
'id': 46459,
'min_delegation_time': '2017-06-11T10:43:03',
'vesting_shares': '41420.217668 VESTS'},
{'delegatee': 'exec',
'delegator': 'oflyhigh',
'id': 46453,
'min_delegation_time': '2017-06-11T09:59:36',
'vesting_shares': '4142028.451502 VESTS'},
{'delegatee': 'oflyhigh.test',
'delegator': 'oflyhigh',
'id': 189549,
'min_delegation_time': '2017-09-12T09:21:12',
'vesting_shares': '59859.310443 VESTS'},
{'delegatee': 'wuyueling',
'delegator': 'oflyhigh',
'id': 465434,
'min_delegation_time': '2018-01-07T08:26:03',
'vesting_shares': '4097.079325 VESTS'}]}

这组数据是正确的。

0.19.4 版本的节点
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
{'id': 1,
'jsonrpc': '2.0',
'result': [{'delegatee': 'eval',
'delegator': 'oflyhigh',
'id': 46459,
'min_delegation_time': '2017-06-11T10:43:03',
'vesting_shares': '41420.217668 VESTS'},
{'delegatee': 'exec',
'delegator': 'oflyhigh',
'id': 46453,
'min_delegation_time': '2017-06-11T09:59:36',
'vesting_shares': '4142028.451502 VESTS'},
{'delegatee': 'oflyhigh.test',
'delegator': 'oflyhigh',
'id': 189549,
'min_delegation_time': '2017-09-12T09:21:12',
'vesting_shares': '59859.310443 VESTS'},
{'delegatee': 'wuyueling',
'delegator': 'oflyhigh',
'id': 465434,
'min_delegation_time': '2018-01-07T08:26:03',
'vesting_shares': '4097.079325 VESTS'},
{'delegatee': 'tard',
'delegator': 'ofrantis',
'id': 603426,
'min_delegation_time': '2018-02-03T03:20:06',
'vesting_shares': '8204.635745 VESTS'},
{'delegatee': 'estonia',
'delegator': 'og-kush',
'id': 44536,
'min_delegation_time': '2017-06-08T11:51:36',
'vesting_shares': '81534.993119 VESTS'},
{'delegatee': 'tard',
'delegator': 'oganenova',
'id': 603427,
'min_delegation_time': '2018-02-03T03:20:09',
'vesting_shares': '2553.358430 VESTS'},
{'delegatee': 'tard',
'delegator': 'ogolor',
'id': 603428,
'min_delegation_time': '2018-02-03T03:20:12',
'vesting_shares': '2047.233971 VESTS'},
{'delegatee': 'tard',
'delegator': 'ogradnov',
'id': 603429,
'min_delegation_time': '2018-02-03T03:20:15',
'vesting_shares': '34107.722623 VESTS'},
{'delegatee': 'otobot',
'delegator': 'oguzhangazi',
'id': 661076,
'min_delegation_time': '2018-02-14T12:47:09',
'vesting_shares': '51200.000000 VESTS'}]}

我们不难发现,0.19.4版本的节点返回了一些无关的数据(错误数据),而程序中把这些数据当成正常的处理,就会造成公众号返回的数据量太大,导致超时

解决方法

一方面我去steem 那边提交的bug报告,另一方面我在公众号的程序中对数据进行二次筛选,目前是可以返回正确结果的。

除夕快乐

总算把公众号的问题解决掉了,不然就要把这个问题留到狗年解决啦,终于可以松口气啦。

在这顺便祝大家除夕快乐吧,今晚都安排了什么节目呢?

相关链接


This page is synchronized from the post: 除夕快乐,公众号的BUG改掉了(查询剩余带宽,查询SP Delegations)

O哥闲扯淡: 硬叉19与平等

8个月以前硬叉19发布的前夜,我发表了文章:非正式翻译:硬叉19 “平等”即将到来,线性奖励 / Informal translation:HF19 “Equality” Coming Soon: Linear Rewards!

这也是我在STEEMIT上最荣耀的时刻,这篇文章一度占领STEEMIT榜首,获得1,620.84 SBD的收益,这真是荣光无限,要名有名要利有利。以前我曾感慨一些作者整天霸榜,相当不平等了,现在我成了榜首,终于盼来了平等,硬叉19,无愧于它的代号:Equality


(图源 :pixabay)

看到这里,我自己都忍不住要骂上两句,我呸,别人上榜就不平等了,你上榜就平等了。没错,人就是这样,古今中外,莫不如此。对自己有利的,要夸夸其谈,对自己不利的,嗯,选择性失明就好。我当然也不能免俗喽。

哇咔咔,跑题了,我们的主题不是吹牛吗硬叉19与平等嘛?很多老用户会体会较深,就是HF19,STEEM整个变化太大太大了。而造成这个变化的无非是HF19中两个主要的修改:线性奖励机制以及投票消耗四倍能量

线性奖励机制

说到线性奖励机制,你可能觉得太过于术语话,其实通俗点解释你一下子就明白了。所谓线性奖励机制就是你有多少有效SP,用对于点贴的话,就可以给帖子增加相应的收益

举例说,假设你有1W SP,在Voting Power保持100%的时候,投出一个100%比例的赞,会给帖子增加了2SBD的收益,那么我有10W SP,同样条件下,就会给帖子增加 20SBD的收益。是不是很简单明了?

同样是因为线性奖励机制,导致了所谓的抱团取暖变成了伪命题,因为无论是抱多大的团,有人受益必然就有人吃亏。HF19之前一些大中小鲸鱼会跟一些热门作者,因为,帖子的收益会有类似乘积的效应,但HF19之后,乘积效应不再,一些热门作者走下了神坛。基于这两点,HF19之后的点赞更趋向于自我点赞,因为这样你占不到别人的便宜,你也吃不了亏。

四倍投票权重

HF19之前,每投一票消耗你投票能量池的0.5%的比例,而投票能量池以每天20%的速度线性恢复(最多100%),这样就意味着每天需要投出40票,才可以把能量池的恢复的部分消耗掉,以免池水溢出,白白浪费。

而HF19之后呢,每票消耗4倍的能量,也就是说,消耗能量池2%的比例,而能量池每日恢复的速度依旧是20%,这就意味着只需10票,就可以把每天增长的投票能量消耗掉

原本大家都在愁怎么把能量消耗掉,毕竟就算100%投,还要投40票,如果再考察帖子质量,25%比重投,那就要160票了,如果阅读和评判一个帖子用5分钟,那么需要13.33小时

而现在好了,10票啊,留给自己还不够呢,哪有精力管别人。什么,发不了十个帖子?发不了帖子可以发回复啊,然后把每个回复都100%顶上去,钱都就到自己腰包。

再说HF19平等

回头再看,无论是线性奖励机制,还是4倍投票权重,都变相助长了人性中自我的一面。所以HF19之后,越来越多的人选择都是利益最大化。所以STEEMIT上有刷帖的,有卖赞的,有各种纷争。

天下熙熙皆为利来,天下攘攘皆为利往,在STEEMIT上体现的淋漓尽致。这就引出一个疑问,这还是HF19所倡导的平等吗?

说到这里,我不禁想起国外一ID,原本是STEEMIT上的斗士,一边自己刷帖刷回复赚钱,一边大棒挥舞(踩)打击那些刷帖赚钱的。然而一段时间之后,他发觉浪费能量去踩有些吃亏,不如专心刷钱的好。

所以,回头再看HF19的平等,其实它说的平等是有多少(等效)SP,就有多少平等对话的权利。或许这本就是HF19中平等的真正意义,只不过我们都曲解了罢了。

结尾

写到这里,有点伤感。

为什么要把这么血淋林的真相揭开呢?而在这血淋林的真相后边,自己又扮演着什么样的角色呢?有朋友常说,不忘初心,然而谁能告诉我初心又是什么呢?

有朋友在帖子中感慨STEEMIT就像是个社会,我去回了一条:

STEEM本没有什么原则,只是大家有各种各样的选择,选择的人多了,就变成了原则。

那么,你的选择呢?

安全提示:O哥闲扯淡系列本就是闲扯淡,诸位千万别当真!

相关链接


This page is synchronized from the post: O哥闲扯淡: 硬叉19与平等

每天进步一点点:Python中使用PycURL访问STEEM RPC

在之前的文章中,我们学习在Python中使用Requests访问STEEM RPC以及Python中使用urllib访问STEEM RPC,但是还有PycURL没测试过,这岂能罢休,必须继续折腾一下。


(图源:bing.com

继续拿我们之前的命令为例来学习一下怎么使用PycURL达成:

curl --data '{"jsonrpc": "2.0", "method": "call", "params": ["account_by_key_api", "get_key_references", [["STM6MGdForcZ8HskcguP84QSCb8udgz7W9yUPU5jtsAKQAxth3U16"]]], "id": 1}' https://api.steemit.com

PycURL 安装

如果你的Python还没有安装PycURL库,那么使用之前,你需要先安装它,安装命令如下:

pip install pycurl

但是,在我这出了如下错误:

FileNotFoundError: [Errno 2] No such file or directory: ‘curl-config’

看了一下好想要先装上libcurl-dev

让我试着安装一下:

sudo apt-get update
sudo apt-get upgrade
sudo apt-get libcurl4-openssl-dev

再执行:pip install pycurl,安装成功!

使用PycURL访问STEEM RPC 节点

在参考手册中,一个简单的POST示例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import pycurl
try:
# python 3
from urllib.parse import urlencode
except ImportError:
# python 2
from urllib import urlencode

c = pycurl.Curl()
c.setopt(c.URL, 'https://httpbin.org/post')

post_data = {'field': 'value'}
# Form data must be provided already urlencoded.
postfields = urlencode(post_data)
# Sets request method to POST,
# Content-Type header to application/x-www-form-urlencoded
# and data to send in request body.
c.setopt(c.POSTFIELDS, postfields)

c.perform()
c.close()

我们将其改写一下,让其能与STEEM RPC 节点交互,示例代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import pycurl
import json
from io import BytesIO

payload = {"jsonrpc": "2.0", "method": "call", "params": ["account_by_key_api", "get_key_references", [["STM6MGdForcZ8HskcguP84QSCb8udgz7W9yUPU5jtsAKQAxth3U16"]]], "id": 1}
rpc = "https://api.steemit.com"
buffer = BytesIO()

c = pycurl.Curl()
c.setopt(c.URL, rpc)
postfields = json.dumps(payload)
c.setopt(c.POSTFIELDS, postfields)
c.setopt(c.WRITEDATA, buffer)
c.perform()
c.close()

body = buffer.getvalue()
print(body.decode('ascii'))

执行结果如下:

高级功能

阅读参考手册我们就会发现,PycURL其实就是libcurl的Python封装,比如手册中的介绍就是这么写的

PycURL is a Python interface to libcurl, the multiprotocol file transfer library.

同样是由于这个原因,它比Requests啥的快好几倍,并且具有诸多特色,详情可以参考文末的参考链接。

我们要想把PycURL灵活运用,除了阅读PycURL手册以外,还需要了解libcurl的API 。比如setopt(option, value)其实对应的是libcurl中的curl_easy_setopt

对于我们而言,需求相对简单,对速度和性能啥的没啥过分的要求,没必要使用PycURL。(这是个逃避的好借口啊)

总结

PycURL 比urllib和Requests用起来都要复杂。

虽然据说性能会更好一些,但是在我这种半吊子程序员手中,再强大的东西我也会给它用成小白的。所以我果断决定放弃使用PycURL了。

比较下来,还是Requests舒服,以后就用它玩了。嗯,就这样,不折腾了。

参考链接


This page is synchronized from the post: 每天进步一点点:Python中使用PycURL访问STEEM RPC

O哥闲扯淡: 声望分是果不是因

很多新来的朋友,和我说,哎呀O哥,你的声望分好高啊,好羡慕啊,这样高的声望分,你发帖子一定好多人给你点赞,这样一来,你的声望分就越来越高了,点赞的人就越来越多了,声望分就越来越高了,点赞的人就越来越多了,……(此处省略一万字)


(图源 :pixabay)

故事

其实我也好希望这样,如果真的是这样的话,声望分就是一切,那么我直接拍张图片,丢上来就好了,坐等几百上千的SBD收益。我就不必每天绞尽脑汁想什么话题了,也不用熬到半夜三更只为了调通一行代码。没办法,我总不能总分享我写程序失败的经历吧?有时候一篇文章我边调代码边写,写到最后,发现我调出来的程序,和我整个文章的中心思想完全相悖,也就是说代码证明了我的文章完全是一派胡言,那这时只好果断的清空全部内容😭

有朋友会骂了,你这是得到便宜还卖乖,完全体会不到我们这些声望分25-40的小小鲸的处境,简直是太招人恨了😡。好吧,我承认我得到便宜了,我也承认招人恨,但是这些其实和声望分无关。你若不信,听我慢慢道来。

很久很久以前,我和STEEMIT上一个老前辈抱怨,“你看那些占据STEEMIT首页的用户,声望分都那么高,点赞的人那么多,这样一来,再他们那就形成了一个良性循环,声望分高的人声望分愈来愈高,像我等声望分低的则永无出头之日。” 咦,这段话是不是有点耳熟?

当时这个前辈沉吟许久,然后对我说,“声望分是果不是因”。我当时颇不以为然,什么因果果因的,我又不是和尚,你和我扯这个?而后来当我玩了STEEM好久,当我对STEEM以及声望分的各项机制了解的愈加深入之后,我方理解,前辈说的真的是真理。

我之前的帖子《真理还是谎言: 声望分越高对别人声望分影响越大吗?/ 代码&测试:到底什么影响声望分的增加?》中曾分析过,影响声望数值的唯一因素就是投票产生的rshares,而rshares是什么,是SBD,是钱,是真金白银。也就是说,声望分的增长和你文章的收益成正比,注意,这里说的是增长而不是声望分本身,让我们来看一些数据。

数据

数据来源:SteemSQL

通过分析STEEM上的数据,我们也不难找出例子支持我们下列论点:

  • 声望分高不一定赚得多
  • 声望分少不一定赚得少

以全网声望分最高的账户 @steemsports 为例:

这个收益,相比首页上动辄几百上千SBD的收益,是不是有些少啊?

作为对比,我们列举一下声望分数值<0,最近7天内得钱收益的前十个帖子

以及作者声望分52以下,最近7天内得钱收益的前十个帖子

你可能会问,为啥查声望分52以下的啊,这已经不低了啊。答案是,60以下声望分增长都非常快,所以无论是买赞还是马甲点上去,又或者真的被大户认同,那么声望分会很快串上去的。

通过后两组数据,我们也可以看到声望分低赚得多的几种手段:

  • 自己是大户
  • 有大户给点
  • 买赞
  • 或租或买SP自己赞

结论


(图源 :pixabay)

综上,声望分相当于一个证书,你攀登山峰达到一个高度,给你颁发一个证书,再到达另外一个高度,给你个新证书。但是,这个证书对你继续攀登山峰,起不到丁点作用。当然了这么说过于武断,比如说有些机器人,还是愿意给声望分高的作者更多的点赞权重。

或者换个比方,声望分就好比树上结出的果实,但是我们可以通过精心照料这棵大树,让它开花结果。我们也可以通过给它使劲灌水,花钱给它打激素,让它迅速的结出看起来又大又红的果实。 只是,哪种方式结出的果实好吃,或者哪种方式可以持续得更为长久,就见仁见智了。

哎呀,不小心说了一些真相,这会不会很令人伤感?不过没关系,伤啊伤啊就习惯了~~,还有这文章本就是闲扯淡,不要太当真啊。

链接


This page is synchronized from the post: O哥闲扯淡: 声望分是果不是因

每天进步一点点:Python中使用urllib访问STEEM RPC

在之前的文章中,我们学习过Python中使用Requests访问STEEM RPC。通过学习,我们了解到Requests是一个强大而易用的库,用来实现网络访问功能简直舒服的不得了,一库在手,天下我有。


(图源:bing.com

然而,人生不就是折腾嘛,不折腾到淋漓尽致不痛快,所以我今天又去学了一下使用urllib如何访问STEEM RPC节点。

继续那我们之前的命令为例:

curl --data '{"jsonrpc": "2.0", "method": "call", "params": ["account_by_key_api", "get_key_references", [["STM6MGdForcZ8HskcguP84QSCb8udgz7W9yUPU5jtsAKQAxth3U16"]]], "id": 1}' https://api.steemit.com

urllib访问STEEM RPC节点

使用urllib将如何实现呢?

其实代码也很简单,示例如下:

1
2
3
4
5
6
7
8
9
import urllib.request
import json
rpc = "https://api.steemit.com"

payload = {"jsonrpc": "2.0", "method": "call", "params": ["account_by_key_api", "get_key_references", [["STM6MGdForcZ8HskcguP84QSCb8udgz7W9yUPU5jtsAKQAxth3U16"]]], "id": 1}
data = json.dumps(payload)
data = data.encode('utf-8')
with urllib.request.urlopen(rpc, data) as f:
print(f.read().decode('utf-8'))

运行上述代码段,输出如下:

可见与Requests的输入没有什么大不同。

代码说明

如果我们对比一下 urllib与Requests访问STEEM RPC的代码,就不难发现,urllib代码中多了一句:data = data.encode('utf-8')

如果我们不加上这句,就会出现如下错误:

TypeError: POST data should be bytes, an iterable of bytes, or a file object. It cannot be of type str

另外,在官网的POST示例中,使用如下代码处理POST数据

import urllib.parse
data = urllib.parse.urlencode({'spam': 1, 'eggs': 2, 'bacon': 0})
data = data.encode('ascii')

因为我们只需POST JSON转储的字符串,所以无需也不能使用urlencode对数据进行编码

关于data.encode('utf-8')以及f.read().decode('utf-8')因为我们postreturn的都是ASCII数据,而ASCII数据编码成UTF-8之后,没啥变化,反之亦然,所以此处用asciiutf-8都可以。但是如果是处理其它网页,使用错误的编码就可能导致乱码等问题。

你可能会问,steem上的文章有中文文章,有汉字,那怎么还是ASCII编码呢?答案在于,返回的数据是使用json.dumps转储的,utf-8字符也被处理成ASCII啦。比如我的一篇文章标题,就是这个样子:

"title":"\\u56de\\u5fc6\\u5f55\\u4e4b\\uff1a\\u6587\\u6863\\u683c\\u5f0f\\u7684\\u65e7\\u4e8b"

实际上它应该是这样:回忆录之:文档格式的旧事

高级功能

之前介绍Requests时提到,什么Session啊,keep-alive啊都是直接支持的。在urllib中如何实现呢?

我大致了解了一下,urllib中没提到咋实现keep-alive,倒是在HTTP modules中的http.client可以支持keep-alive,但是这属于另外一个话题了,而且,在http.client的页面写着如下内容:

This module defines classes which implement the client side of the HTTP and HTTPS protocols. It is normally not used directly — the module urllib.request uses it to handle URLs that use HTTP and HTTPS.

我觉得我有点方,如此看来,还是Requests好呀。

参考内容


This page is synchronized from the post: 每天进步一点点:Python中使用urllib访问STEEM RPC

Your browser is out-of-date!

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

×