当使用像 Steem 这样的去中心化平台时,重要的是要预期偶尔的故障——网络问题、API 限制或暂时的停机。这就是为什么你构建的任何集成、机器人或工具都应该能够优雅地失败并智能地恢复。
在这篇文章中,我将带你了解一个简单而强大的 Steem 区块链见证人(也就是STEEM上的矿工)投票检查工具:
第一版:检查是否由某个见证人投票
这是一个实用的 Node.js 函数,用于检查一个 Steem 用户是否投票支持了某个特定的 见证人——无论是直接投票还是通过代理。
1 2 3 4 5 6 7 8 9 10 | function is_voted_by(witness, id) { return new Promise((resolve, reject) => { steem.api.getAccounts([id], function(err, response) { if (err) reject(err); if (typeof response == "undefined") reject("undefined"); const data = response[0]; resolve((data.proxy === witness) || data.witness_votes.includes(witness)); }); }); } |
function is_voted_by(witness, id) { return new Promise((resolve, reject) => { steem.api.getAccounts([id], function(err, response) { if (err) reject(err); if (typeof response == "undefined") reject("undefined"); const data = response[0]; resolve((data.proxy === witness) || data.witness_votes.includes(witness)); }); }); }
它获取给定 id 的账户数据,然后检查该用户是否设置了匹配目标见证人的投票代理,或者该见证人是否在他们的直接投票列表中。
启用重试的 Steem 见证人投票检查器
这是更新版的函数,包含简单的重试机制(最多重试 3 次,每次重试间隔 1 秒)。以下的代码加入了重试功能:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | function is_voted_by(witness, id, retries = 3) { return new Promise((resolve, reject) => { const attempt = (remaining) => { steem.api.getAccounts([id], function(err, response) { if (err || typeof response === "undefined") { if (remaining > 0) { setTimeout(() => attempt(remaining - 1), 1000); // 重试 1 秒后 } else { reject(err || "undefined response"); } return; } const data = response[0]; resolve((data.proxy === witness) || data.witness_votes.includes(witness)); }); }; attempt(retries); }); } |
function is_voted_by(witness, id, retries = 3) { return new Promise((resolve, reject) => { const attempt = (remaining) => { steem.api.getAccounts([id], function(err, response) { if (err || typeof response === "undefined") { if (remaining > 0) { setTimeout(() => attempt(remaining - 1), 1000); // 重试 1 秒后 } else { reject(err || "undefined response"); } return; } const data = response[0]; resolve((data.proxy === witness) || data.witness_votes.includes(witness)); }); }; attempt(retries); }); }
此版本在 Steem API 调用失败或返回 undefined 时最多进行 3 次重试,帮助处理不稳定的网络状况或临时的 API 问题。功能保持不变:检查直接的见证人投票或代理委托/Proxy。
重试的指数退避机制
使用指数退避机制/Exponential backoff来避免过度请求 API,并记录每次尝试以便于调试和更好的可视化。
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 | module.exports.is_voted_by = function(witness, id, retries = 3, delay = 1000) { return new Promise((resolve, reject) => { const attempt = (remaining, currentDelay) => { console.log(`Checking vote for "${id}" against witness "${witness}"... (${retries - remaining + 1}/${retries})`); steem.api.getAccounts([id], function(err, response) { if (err || typeof response === "undefined") { console.warn(`Attempt failed: ${err || 'undefined response'}`); if (remaining > 0) { console.log(`Retrying in ${currentDelay}ms...`); setTimeout(() => attempt(remaining - 1, currentDelay * 2), currentDelay); // 指数退避 } else { reject(err || "undefined response after retries"); } return; } const data = response[0]; const voted = (data.proxy === witness) || data.witness_votes.includes(witness); console.log(`Vote check result: ${voted}`); resolve(voted); }); }; attempt(retries, delay); }); }; |
module.exports.is_voted_by = function(witness, id, retries = 3, delay = 1000) { return new Promise((resolve, reject) => { const attempt = (remaining, currentDelay) => { console.log(`Checking vote for "${id}" against witness "${witness}"... (${retries - remaining + 1}/${retries})`); steem.api.getAccounts([id], function(err, response) { if (err || typeof response === "undefined") { console.warn(`Attempt failed: ${err || 'undefined response'}`); if (remaining > 0) { console.log(`Retrying in ${currentDelay}ms...`); setTimeout(() => attempt(remaining - 1, currentDelay * 2), currentDelay); // 指数退避 } else { reject(err || "undefined response after retries"); } return; } const data = response[0]; const voted = (data.proxy === witness) || data.witness_votes.includes(witness); console.log(`Vote check result: ${voted}`); resolve(voted); }); }; attempt(retries, delay); }); };
该函数:
- 调用 Steem API 获取给定 id 的账户信息。
- 检查用户是否投票支持某个特定的见证人,检查方式包括:直接投票(即 witness_votes 中包含该见证人),或通过代理投票(即 proxy === witness)。
如果 API 调用失败或返回 undefined,它将:
- 等待一段时间,
- 重试(最多重试 retries 次),
- 并且每次的等待时间按指数方式增加(1秒、2秒、4秒等)。
为什么要使用指数退避?
指数退避是网络编程中的经典策略——如果服务暂时不可用,快速连续请求只会让问题更加严重。通过在重试之间增加延迟,可以让系统有时间恢复,并且对 API 更加友好。
1 2 3 4 5 6 7 8 9 10 11 | is_voted_by('witness-name', 'username') .then(voted => { if (voted) { console.log("User supports the witness!"); } else { console.log("User has not voted for the witness."); } }) .catch(err => { console.error("Error checking vote:", err); }); |
is_voted_by('witness-name', 'username') .then(voted => { if (voted) { console.log("User supports the witness!"); } else { console.log("User has not voted for the witness."); } }) .catch(err => { console.error("Error checking vote:", err); });
最后的思考
在构建与区块链交互的工具时,弹性至关重要。适当的重试逻辑能大大提高你的应用程序的稳定性和用户友好性——即使在底层基础设施出现问题时也能保持正常运行。
Steem/Steemit区块链
- 如何构建一个具有重试机制的 Steem 区块链见证人投票检查器
- STEEM区块链上帐号等级80并且超100万SP - 终于成为了大户(大鲸鱼)
- STEEM兑换ETH以太网工具上线两个月一共兑换了10个ETH!
- 怎么样计算STEEM区块链的上线率(UpTime)和宕机时间(DownTime)
- 系统设计: Steem区块链ChatGPT机器人
- 《steem 指南》- 查看踩人与被踩的记录
- SteemIt Finally Reputation = 70! 盼星星盼月亮, 总算盼来70级!
- STEEMIT cn区最低保障系统 上线了! Introduction to the CN Wechat Group Voting Robot @justyy
- SteemIt 好友微信群排行榜 支持显示数据统计和API了!
- 数据初步分析系列 STEEM中文微信群排行榜单 - 中位数, 平均, 和标准方差
- 大家好才是真的好, YY银行足球队, 你还有啥理由不加入银行?
- YY 银行开启互抱大腿模式 (mutually-beneficial voting scheme)
- 哇哈哈, 我已经是 utopian-io 的 moderator 团队的一员了!
- 返璞归真, 重新成为小鱼 - 祭奠逝去的1万SP
英文:
- Building a Reliable Witness Vote Checker for the Steem Blockchain (with Retry & Exponential Backoff)
- Javascript (NodeJS) Function to Check if a Witness Has been Voted by or Proxied By on Steem Blockchain
强烈推荐
- 英国代购-畅购英伦
- TopCashBack 返现 (英国购物必备, 积少成多, 我2年来一共得了3000多英镑)
- Quidco 返现 (也是很不错的英国返现网站, 返现率高)
- 注册就送10美元, 免费使用2个月的 DigitalOcean 云主机(性价比超高, 每月只需5美元)
- 注册就送10美元, 免费使用4个月的 Vultr 云主机(性价比超高, 每月只需2.5美元)
- 注册就送10美元, 免费使用2个月的 阿里 云主机(性价比超高, 每月只需4.5美元)
- 注册就送20美元, 免费使用4个月的 Linode 云主机(性价比超高, 每月只需5美元) (折扣码: PodCastInit2022)
- PlusNet 英国光纤(超快, 超划算! 用户名 doctorlai)
- 刷了美国运通信用卡一年得到的积分 换了 485英镑
- 注册就送50英镑 – 英国最便宜最划算的电气提供商
- 能把比特币莱特币变现的银行卡! 不需要手续费就可以把虚拟货币法币兑换
微信公众号: 小赖子的英国生活和资讯 JustYYUK