Published: 26 Aug 2025 › Updated: 26 Aug 2025
Hive社区: Hive blockchain开发指南
在开发喵星时重新应用了下hivejs的各个功能,把一些常用的应用场景都趟了一遍,也算有些心得。总结总结,给Hive社区的小伙伴们做些参考。
Hive dev
- 下载与资源
- 公共节点
- 安装与使用
- dhive
- Auth权限
- 获取帐户数据
- Hive登录逻辑
- 发布文章
- json_metadata
- 一篇文章的结构
- 点赞某篇文章
- 获取粉丝列表
- 获取关注列表
- 获取文章的函数们
- 获取作者的最近文章列表
- 获取所有文章并保存在本地
- 获取用户关注作者的文章列表
- 获取某篇文章的回复
- 获取某篇文章的所有回复
- 获取作者对别人的留言
- 获取对作者的评论
- 转帐HIVE或HBD
- 获取某位作者某篇文章的点赞
- 创建新用户
- HP代理
- 查询代理
下载与资源
公共节点
https://api.hive.blog @blocktrades
https://api.openhive.network @gtg
https://rpc.mahdiyari.info @mahdiyari
https://techcoderx.com @techcoderx
https://api.deathwing.me @deathwing
https://hive-api.arcange.eu @arcange
安装与使用
yarn add @hiveio/hive-js //^2.0.8
// npm install @hiveio/hive-js --save
//
import hive from '@hiveio/hive-js'
//初始化hive节点
const hiveConNode = 'https://api.openhive.network'
// const hiveConNode = 'https://api.hive.blog'
hive.api.setOptions({ url: hiveConNode})
dhive
npm install @hiveio/dhive --save
var dhive = require("@hiveio/dhive")
var client = new dhive.Client(["https://api.hive.blog", "https://api.hivekings.com", "https://api.openhive.network"])
var key = dhive.PrivateKey.fromLogin("username", "password", "posting")
Auth权限
//认证
hive.auth.verify(name, password, auths)
eg:
let username = 'epexa'
let password = 'P5...' // 用户密码
let auths = {
posting: [['STM6...']],
}
hive.auth.verify(username, password, auths) //return true or false
// Generate Keys 生成公钥对
hive.auth.generateKeys(name, password, roles)
let publicKeys = hive.auth.generateKeys(newAccountName, newAccountPassword, ['owner', 'active', 'posting', 'memo'])
//返回数据
{
owner: 'STM5sxKw1uEdryNmCj3xAxxxxxx',
active: 'STM5iEkPwjNPw6WecgeDxxxxx',
posting: 'STM7dKMMke2aiPTCnExxxx',
memo: 'STM8KxMKW5t9QkweXBogdxxxxxx'
}
// Get Private Keys 从用户名和密码得到对应的公私钥
hive.auth.getPrivateKeys(name, password, roles)
let roles = ['owner', 'active', 'posting', 'memo']
let res = hive.auth.getPrivateKeys(name, password, roles)
//返回数据
{
owner: '5JDZPwykhCb6ZmmvSUFcTsxxxxxxxx',
ownerPubkey: 'STM5sxKw1uEdryNmCxxxxxx',
active: '5JSxdtFeCNGSRt18u7WDxxxxxxxx',
activePubkey: 'STM5iEkPwjNPw6Wecxxxxx',
posting: '5KE3ET6DD6X47VWDUCXxxxxxxxx',
postingPubkey: 'STM7dKMMke2aixxxxxxxx',
memo: '5JgW5NNxT7VJAQMxjtCbDmFxxxxxxxx',
memoPubkey: 'STM8KxMKW5t9QkweXBoxxxxxx'
}
// Is Wif //判断是否是私钥,返回 true 或 false
hive.auth.isWif(privWif)
let privWif = "5JfxkpNEBFDxxxvxxxxxxxx"
let res = hive.auth.isWif(privWif) //true
// To Wif 从用户名和密码得到对应的私钥
hive.toWif(name, password, role)
let role = ["active"]
let res = hive.auth.toWif(name, password, role)
//返回数据
"5Jv9NHkL8TrdvJNue2EKZHQDbxxxxxxx"
// Wif Is Valid 验证公私钥对是否匹配,返回true 或 false
hive.auth.wifIsValid(privWif, pubWif)
let privWif = "5Jv9NHkL8TrdvJNubXxxxxxx"
let pubWif = "STM5f2H2rbSmVoEzrPxxxxxxxx"
let res = hive.auth.wifIsValid(privWif, pubWif) //true
// Wif To Public 从私钥得到对应的公钥
hive.auth.wifToPublic(privWif)
let privWif = "5Jv9NHkL8TrdvJNue2qxxxxxxx"
let res = hive.auth.wifToPublic(privWif)
// Sign Transaction
hive.auth.signTransaction(trx, keys)
获取帐户数据
帐户数据几乎都在这里了,包括创建的时间,余额,点赞能量等等。
let result = await hive.api.getAccountsAsync([account])
console.log(256, result, result.length === 0) //length为0表示帐户不存在
Hive登录逻辑
let account = "lucky"
let privWif = "5tikkkxxxxxx"
let result = await hive.api.getAccountsAsync([account])
if(result.length === 0){
return ('用户不存在!')
}
//判断是否私钥
let hiveres = hive.auth.isWif(privWif)
let postWif = privWif
if(hiveres !== true){
//获取发贴私钥(从密码)
let role = ["posting"]
postWif = hive.auth.toWif(account, privWif, role)
}
//公私钥是否配对
let pubWif = result[0].posting.key_auths[0][0]
let isvalid3 = hive.auth.wifIsValid(postWif, pubWif)
if(isvalid3 === true){
return ({
username: account,
wif: postWif,
avatar: `https://images.hive.blog/u/${account}/avatar`
})
} else {
return ('密钥错误!')
}
发布文章
发贴或评论都是用的同一个函数,只是发帖的parent_author为空。
hive.broadcast.comment(wif, parentAuthor, parentPermlink, author, permlink, title, body, jsonMetadata, function(err, result) {
console.log(err, result)
}) //commentAsync
//函数讲解
hive.broadcast.comment (
wif, //发帖密钥
parentAuthor, // 如果是发帖则为空,如果是评论则为父帖作者
parentPermlink, // 如果是发帖则为主标签,如果是评论则为父帖地址
author, // 作者
permlink, // URL地址
title, // 标题 ,如果是评论则为空
body, // 内容
jsonMetadata // json
)
eg:
let wif = '5pfffff'
let parentAuthor = ''
let parentPermlink = 'cn'
let author = 'lemooljiang'
let permlink = 'kdk54gf'
let title = '这是标题'
let body = '这是正文'
let tags = ['cn', 'miao', 'bitcoin']
let jsonMetadata = {"tags": tags, "dapp": "miao", "format": "markdown"}
hive.broadcast.comment(wif, parentAuthor, parentPermlink, author, permlink, title, body, jsonMetadata, function(err, result) {
console.log(1234, err, result)
})
// 另一种Async写法:
let res = await hive.broadcast.commentAsync(wif, parentAuthor, parentPermlink, author, permlink, title, body, jsonMetadata)
console.log(126, res)
/*
{ id: '1bea63265fd12d5bf725e1d1e7083eecb6444ff5', 22:17:06
ref_block_num: 4735,
ref_block_prefix: 588181965,
expiration: '2025-08-04T14:27:06',
operations: [ [ 'comment', [Object] ] ],
extensions: [],
signatures:
[ '2076f2e87b1d976804eexxxxxxxx' ] }
*/
json_metadata
post.json_metadata还可以按需求写入其它的数据,有点类似MongoDB。这样的话易于对文章进行过滤,也可保存一些特殊的数据。
json_metadata: "{"tags":["cn","network-institute","markdown","html"],"app":"miao","format":"markdown"}"
eg:
let jsonMetadata = {"tags": tags, "dapp": "miao", "format": "markdown", "cover": hash, "text": text}
JSON.stringify(jsonMetadata)
一篇文章的结构
{
author: 'lemooljiang',
permlink: 'tfdhqbvp',
category: 'hive-105017',
title: '洞庭南路离奇车祸,数人伤亡',
body: '昨晚的车祸由于发生在身边,不由感到阵阵后怕。车祸也是让人感到匪夷所思......',
json_metadata: '{"tags":["cn","cn-reader","yueyang","caraccident"],"dapp":"larkBlog","format":"markdown"}',
created: '2025-08-07T04:13:57',
last_update: '2025-08-07T04:13:57',
depth: 0,
children: 0,
last_payout: '1969-12-31T23:59:59',
cashout_time: '2025-08-14T04:13:57',
total_payout_value: '0.000 HBD',
curator_payout_value: '0.000 HBD',
pending_payout_value: '4.143 HBD',
promoted: '0.000 HBD',
replies: [],
body_length: 403,
author_reputation: 439510683431084,
parent_author: '',
parent_permlink: 'hive-105017',
url: '/hive-105017/@lemooljiang/tfdhqbvp',
root_title: '洞庭南路离奇车祸,数人伤亡',
beneficiaries: [],
max_accepted_payout: '1000000.000 HBD',
percent_hbd: 10000,
id: 144763251,
author_rewards: 0,
max_cashout_time: '1969-12-31T23:59:59',
reward_weight: 10000,
root_author: 'lemooljiang',
root_permlink: 'tfdhqbvp',
allow_replies: true,
allow_votes: true,
allow_curation_rewards: true,
reblogged_by: [],
net_votes: 37,
children_abs_rshares: 0,
total_pending_payout_value: '0.000 HBD',
total_vote_weight: 13801670934098,
vote_rshares: 13801670934098,
net_rshares: 13801670934098,
abs_rshares: 13801670934098,
active_votes: [{
percent: 7000,
reputation: 3100979937647200,
rshares: 5785001502757,
time: '2025-08-07T04:17:45',
voter: 'deanliu',
weight: 5785001502757
},......]
}
点赞某篇文章
hive.broadcast.vote(wif, voter, author, permlink, weight, function(err, result) {
console.log(err, result)
})
//函数讲解
hive.broadcast.vote (
wif, //发帖密钥
voter, //点赞人
author, //作者
permlink, // URL地址
weight //点赞比重,100*100
)
eg:
hive.broadcast.vote(
"5KRSmEMffffff",
"lemooljiang",
"starnote",
'6ekczn-2019',
10000,
function(err, result) {
console.log(8888, err, result)
})
获取粉丝列表
hive.api.getFollowers('lemooljiang', '', 'blog', 10, function(err, result) {
console.log(111, err, result)
})
获取关注列表
hive.api.getFollowing('lemooljiang', '', 'blog', 10, function(err, result) {
console.log(222, err, result)
})
获取文章的函数们
getDiscussionsByXXX
//query的参数结构
string tag;
uint32_t limit = 0;
set<string> filter_tags;
set<string> select_authors;
set<string> select_tags;
uint32_t truncate_body = 0;
optional<string> start_author;
optional<string> start_permlink;
optional<string> parent_author;
optional<string> parent_permlink;
// 获取热门文章
hive.api.getDiscussionsByHot(query, function(err, result) {
console.log(err, result)
})
eg:
hive.api.getDiscussionsByHot({tag: 'photography', limit: 1}, function(err, result) {
console.log(err, result)
})
//获取某标签的趁势热贴(只有7天的)
hive.api.getDiscussionsByTrending({tag: 'photography', limit: 1}, function(err, result) {
console.log(err, result)
});
eg:
getTrending(){
let query = { tag: "cn", limit : 20 }
hive.api.getDiscussionsByTrending(query, function(err, data) {
//取到最后一篇文章的author和Permlink,做为下一次查询的起始点
author.value = data[data.length - 1].author
permlink.value = data[data.length - 1].permlink
})
}
//获取新帖(所有日期的)
hive.api.getDiscussionsByCreated({tag: 'photography', limit: 1}, function(err, result) {
console.log(err, result)
})
获取作者的最近文章列表
//获取最新文章
hive.api.getDiscussionsByAuthorBeforeDate(author, startPermlink, beforeDate, limit, function(err, result) {
console.log(err, result)
})
let author = username
let beforeDate = new Date().toISOString().split('.')[0]
let startPermlink = null
let result = await hive.api.getDiscussionsByAuthorBeforeDateAsync(author, startPermlink, beforeDate, 10)
// console.log(655,result) 一次最多能取100篇
获取所有文章并保存在本地
import hive from '@hiveio/hive-js'
import fs from "fs"
//初始化hive节点
const hiveConNode = 'https://api.openhive.network'
// const hiveConNode = 'https://api.hive.blog'
hive.api.setOptions({ url: hiveConNode})
const waiting = async() => {
return new Promise(resolve => {
setTimeout(resolve, 6000) //6秒
})
}
async function getArticles(author, startPermlink, beforeDate, limit){
let posts = []
while(true){
let result = await hive.api.getDiscussionsByAuthorBeforeDateAsync(author, startPermlink, beforeDate, limit)
console.log(655,"result:",result.length)
//如果查询数组为空,则已查询完,可以终止查询了 result: 0
if(result.length == 0){
console.log(8888, posts.length) //从新到旧的数组
break
}
//做一次遍历去掉重复的文章
result.forEach(post => {
if (post.permlink != startPermlink) {
//把数据规整
let newPost = {
"title": post.title,
"author": post.author,
"category": post.parent_permlink,
"permlink": post.permlink,
"body": post.body,
"created": post.created,
"tags": JSON.parse(post.json_metadata).tags //"tags":["cn-reader","cn"]
}
// posts.push(post)
posts.push(newPost)
}
})
//取到最后一篇文章的Permlink,做为下一次查询的起始点
startPermlink = result[result.length - 1].permlink
await waiting() //主要是因为节点的限制
}
console.log(5598, "posts", posts.length, posts[posts.length - 1].title, posts[posts.length - 1].created)
//保存为md文件
let path = './2025.md'
fs.writeFileSync(path, JSON.stringify(posts))
console.log(666, "save ok!")
return posts
}
let author = 'lemooljiang' //改成自己的名字
let beforeDate = new Date().toISOString().split('.')[0]
getArticles(author, null, beforeDate, 80) //传入要查询的作者名,初始标签,初始时间,一次查询的条数(最多是100)
获取用户关注作者的文章列表
let query = {tag: body.tag, limit: body.limit, start_author: body.author, start_permlink: body.permlink}
let result = await hive.api.getDiscussionsByFeedAsync(query)
eg:
let query = {tag: "lemooljiang", limit: 10, start_author: "nie", start_permlink: "sskxiik"}
let result = await hive.api.getDiscussionsByFeedAsync(query)
获取某篇文章的回复
hive.api.getContentReplies(author, permlink, function(err, result) {
console.log(err, result)
})
eg:
hive.api.getContentReplies('lemooljiang', 'hivejs-41', function(err, result) {
console.log(err, result)
})
获取某篇文章的所有回复
使用递归的方法获取
async function getAllReplies(author, permlink, res=[]) {
let replies = await hive.api.getContentRepliesAsync(author, permlink)
let children = []
replies.forEach(item => {
res.push(item)
if(item.children > 0){
//把得到的子数据塞进 .child 中
children.push(getAllReplies(item.author, item.permlink, item.child=[]))
}
})
await Promise.all(children)
return res
}
获取作者对别人的留言
let author = "lucky"
let query = { limit : 30, start_author: author, start_permlink: ""}
hive.api.getDiscussionsByComments(query, function(err, result) {
console.log(265, err, result)
}
获取对作者的评论
从帐户历史中遍历获取
async function getToAuthorReplies(author, limit){
//获取对作者的最新评论
let replies = []
let res = await hive.api.getAccountHistoryAsync(author, -1, limit)
res.forEach(item => {
if(item[1].op[0] == "comment" & item[1].op[1].parent_author == author){
replies.push(item)
}
})
return replies
}
转帐HIVE或HBD
hive.broadcast.transfer(wif, from, to, amount, memo, function(err, result) {
console.log(err, result)
})
// wif, from, to, amount, memo
// 转账私钥,发起转帐地址,转给谁, 金额, 备注
transfer("wif", "lemool", "lucky", "0.001 HBD", "You are awesome ! take some tokens")
eg:
async hiveTransfer(){
let from = "lemooljiang"
let to = "lucky"
let wif = "5KNxxxxxxxxxxxxxxxx"
// let ss = parseFloat(hivevalue).toFixed(3)
// let amount = ss+' HIVE'
let amount = "100.200 HIVE" //必须是3位小数且带上单位的格式,
let memo = "测试"
await hive.broadcast.transferAsync(wif, from, to, amount, memo)
}
获取某位作者某篇文章的点赞
let author = "lemooljiang"
let permlink = "pvw4dotxg"
let res = await hive.api.getActiveVotesAsync(author, permlink)
console.log(566, res)
创建新用户
hive.auth.generateKeys 用于生成4组密钥(owner, active, posting, memo),
hvie.broadcast.accountCreate 用于创建账号
register() {
let newAccountName = "betty" //新帐户
let newAccountPassword = "FDDjjjRxxxxxxxx" //新帐户密码
let publicKeys = this.steem.auth.generateKeys(newAccountName, newAccountPassword, ['owner', 'active', 'posting', 'memo'])
let owner = { weight_threshold: 1, account_auths: [], key_auths: [[publicKeys.owner, 1]] }
let active = { weight_threshold: 1, account_auths: [], key_auths: [[publicKeys.active, 1]] }
let posting = { weight_threshold: 1, account_auths: [], key_auths: [[publicKeys.posting, 1]] }
let memoKey = publicKeys.memo
let creator = "lemooljiang" //创建者
let creatorWif = "5Jbfffxxxxx" //创建者的资金密钥
let fee = "3.000 HIVE" //费用
let jsonMetadata = ""
hvie.broadcast.accountCreate(
creatorWif,
fee,
creator,
newAccountName,
owner,
active,
posting,
memoKey,
jsonMetadata,
(err, result) => {
if(err){
console.log(444, '创建失败!', err)
}else{
console.log(666, '创建成功!', result)
}
})
}
HP代理
HP代理是以VESTS来计算的
hive.broadcast.delegateVestingShares(wif, delegator, delegatee, vesting_shares, function(err, result) {
console.log(err, result)
})
wif - 资金私钥
delegator - 代理人
delegatee - 被代理人
vesting_shares - hp要转换成vests
//VESTS和HP换算关系
async function main() {
let s = await hive.api.getDynamicGlobalPropertiesAsync()
console.log(11, s)
console.log(12, s.total_vesting_shares)
console.log(13, s.total_vesting_fund_hive)
console.log(14, "hp_to_vests", parseFloat(s.total_vesting_shares) / parseFloat(s.total_vesting_fund_hive))
}
main()
//
12 313254970159.720284 VESTS
13 188674228.477 HIVE
当前 1 HP = 1660.295487 VESTS
eg:
async delegate(){
let wif = '5KNxxxxxxxxxxxxxxx'
let delegator = 'lemool'
let delegatee = "lucky"
let a = await hive.api.getDynamicGlobalPropertiesAsync()
let hp_to_vests = parseFloat(a.total_vesting_shares) / parseFloat(a.total_vesting_fund_hive)
let b = '1.8' * hp_to_vests //代理1.8个HP
let c = b.toFixed(6) //6位小数
let vests = c+' VESTS' //换算成VESTS
await hive.broadcast.delegateVestingSharesAsync(wif, delegator, delegatee, vests)
}
////执行结果:
operations: Array(1)
0: Array(2)
0: "delegate_vesting_shares"
1:
delegatee: "tsteem.test"
delegator: "timool"
vesting_shares: "3483.359523 VESTS"
__proto__: Object
length: 2
注意: 最小代理量不能小于1HP,要取消代理直接把代理量设为0即可,取消代理要有7天才能回到原有帐户。
查询代理
hive.api.getVestingDelegations('ned', '', 2, function(err, result) {
console.log(err, result)
}) //null []
eg:
async getDelegateHP(){
let user = 'lemooljiang'
let res = await hive.api.getVestingDelegationsAsync(user, '', 2)
if(res.length == 0){
return 0
} else{
return parseFloat(res[0].vesting_shares)
}
}
Leave Hive社区: Hive blockchain开发指南 to:
Read more #cn posts
Best Posts From lemooljiang
We have not curated any of lemooljiang's posts yet. But you can encourage our curation team to review posts by visiting them regularly and by referring other readers. Because we give priority to frequently read content.
More Posts From lemooljiang
- 炒股投资要从娃娃抓起之特朗普账户
- Nextjs初体验,和Nuxt的异同
- DeepTutor:AI个性化辅导平台 / ai #57
- ComfyUI:可编程和自动化的PS / ai #56
- 将Neo4j封装进Agent / ai #55
- 闲鱼省钱大法:极限0.5折!
- 对Neo4j批量导入结构化数据 / ai #54
- langchain对neo4j进行交互,写入和查询数据 / ai #53
- 知识图谱和图数据库Neo4j的作用和使用场景 / ai #52
- SpaceX、美股和比特币
- 又是币圈血洗日!
- 链股合流,当币安也开始卖股票啰
- 天涯社区重启,爷青回?
- 诺基亚在AI时代重新杀回来啦
- 《2049:未来10000天的可能》书中的镜像世界为什么不叫元宇宙
- 今天适合吃披萨
- 开通即被封,别再给Claude送人头了!
- 两根内存条引发的“官司”
- AI·Joe V12更新, 更新GPT-5.5和DeepSeek V4 等
- 中医进校园活动反响热烈