从私有以太坊区块链在浏览器中实时更新用户余额



我想有一个网站,从私人以太坊区块链实时更新用户的财富。

当前解决方案(已损坏(

我打开了一个正在挖矿的私人以太坊区块链的websocket,我想在前端更新我的Coinbase余额。我的代码如下:

const express    = require("express");
const Web3       = require("web3");

var app  = express();
app.get("/", (req, res) => res.send("hello world from ping ether application"));
app.get("/ping-ether", function(req, res){

    var web3 = new Web3(new Web3.providers.WebsocketProvider('ws://localhost:8546'));
    var event_newBlockHeaders = web3.eth.subscribe("newBlockHeaders", function(err, result){
        if (err){ 
         
            console.log(err) 
        } else {
            let acctPromise = web3.eth.getAccounts().then(function(accts){
                let balance = web3.eth.getBalance(accts[0]).then(function(bal){
                    console.log("user: ", accts[0]);
                    console.log("balance: ", bal);
                    res.end("new balance for user: " + bal)
                });
            });
        }
    });

});

// run the server
app.listen(3000, () => console.log("web app listening on port 3000"));

显然,这不会在前端实时更新,即使我可以在控制台上确认的最内部回调不断触发。我想要三件事:

  1. 我应该如何更改此代码,以便前端具有coinbase余额的实时代码

  2. 一般来说,代码的嵌套承诺闻起来很糟糕。如何重构它,以便我不必在每次导航到/ping-ether时都建立 websocket 连接?

未经测试,但这样的事情应该可以工作:

const express    = require("express");
const Web3       = require("web3");
var app  = express();
var web3 = new Web3(new Web3.providers.WebsocketProvider('ws://localhost:8546'));
var balance = -1;
web3.eth.getAccounts().then(accounts => {
  return web3.eth.subscribe("newBlockHeaders", (err, result) => {
    if (err) {
      console.log(err);
    } else {
      web3.eth.getBalance(accounts[0]).then(bal => {
        console.log("user: ", accounts[0]);
        console.log("balance: ", bal);
        balance = bal;
      });
    }
  })
}).then(() => {
  app.listen(3000, () => console.log("web app listening on port 3000"));
});
app.get("/", (req, res) => res.send("hello world from ping ether application"));
app.get("/ping-ether", function (req, res) {
  res.end("new balance for user: " + balance);
});

主要思想是设置一次 websocket 连接和订阅,然后仅使用当前余额响应传入的 Web 请求。我还尝试通过返回订阅承诺来清理嵌套承诺。

更新:我最终使用了websocket,这是解决方案:

import * as Web3     from 'web3'     ; 
import * as express  from 'express'  ;
import * as socketIO from 'socket.io';
import * as http      from 'http'    ;

const CLIENT_PATH = 'path/to/directory'
var app    = express();
var server = http.Server(app);
var io     = socketIO(server);
var web3   = new Web3(new Web3.providers.WebsocketProvider('ws://localhost:8546'));
app.get('/', (req,res) => {
    res.sendFile(CLIENT_PATH + '/index.html');
});

web3.eth.getAccounts().then(accounts => {
    display_account(accounts)
})
function display_account(accounts){
    var user_0 = accounts[0]
    web3.eth.subscribe('newBlockHeaders', (err, ret) => {
        if (err){ 
            console.log("error: ", err)
        } else {
            web3.eth.getBalance(user_0).then(bal => {
                var msg = 'Balance for user ' + user_0 + ' is ' + bal  
                io.emit('message-1', msg)
                console.log('emitted message: ', msg)
            })
        }
    })
}

// use this instead of app.listen
server.listen(3000, () => {
    console.log('listening on 3000')
});

这是索引.html。

<html>
<head></head>
<body>
  <div id="message"></div>
  <script src="/socket.io/socket.io.js"></script>
  <script>
    var socket = io();
    socket.on('message-1', function(msg){
      console.log(msg);
      document.getElementById("message").innerHTML = msg;
    });
  </script>
</body>
</html>

最新更新