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

Javascript 从私有以太坊区块链在浏览器中实时更新用户余额,javascript,node.js,express,ethereum,web3,Javascript,Node.js,Express,Ethereum,Web3,问题 我希望有一个网站能够通过私有以太坊区块链实时更新用户的财富 当前解决方案(已损坏) 我打开了一个websocket到一个正在挖掘的私有以太坊区块链,我想更新前端的coinbase余额。我的代码如下: const express = require("express"); const Web3 = require("web3"); var app = express(); app.get("/", (req, res) => res.send("hello w

问题

我希望有一个网站能够通过私有以太坊区块链实时更新用户的财富

当前解决方案(已损坏)

我打开了一个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"));
很明显,这并不是在前端实时更新,即使最内部的回调不断触发,我可以在控制台上确认这一点。我想要三样东西:

  • 我应该如何更改此代码,以便前端具有coinbase余额的实时行情器
  • 一般来说,这段代码带有嵌套承诺的味道。如何重构它,使我不必每次导航到
    /ping以太时都建立websocket连接
  • 欢迎提出任何其他建议。我对node.js非常陌生

  • 未经测试,但类似的方法应该有效:

    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')
    
    });
    
    这是index.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>
    
    
    var socket=io();
    socket.on('message-1',函数(msg){
    控制台日志(msg);
    document.getElementById(“message”).innerHTML=msg;
    });