验证交易时出错。输入总和小于输出总和。比特核

时间:2018-12-13 23:42:14

标签: node.js webhooks bitcoin bitcore blockcypher

当用户在我的Web应用程序上注册时,将生成一个高清钱包,并在blockcypher API上实例化一个Webhook,以侦听未确认的交易和单个确认交易。当检测到未确认的交易,并且事件从加密货币网站发送到我的快速应用程序上的路由时,会通知用户已收到他们的交易。当交易得到一个确认时,我试图将钱从他们的钱包转移到主要的热钱包。但是,当我尝试广播原始tx时出现错误。

ERR When broadcasting the TX

这是我的代码。 此错误是什么意思,我该如何解决。 另外,是否存在实现相同结果的替代方法。将非常乐于聆听/尝试。

这是侦听并签署交易的代码。

    // UNCONFIRMED TRANSACTION
    api.post('/callbacks/new-tx', async function(req, res) {
    console.log('POST: Callback received from blockcypher');
    console.log(req.body);
    fs.appendFile('Deposits.txt', 'Unconfirmed Deposit\n' + JSON.stringify(req.body) + '\n');

    // FIND OWNER OF ADDRESS
    User.findOne({'keyPairs.address': req.body.addresses[0]}, function(err, user) {
        // UPDATE BALANCE OF USER
        // user.balance += req.body.outputs[0].value;

        // CREATE TRANSACTION MODEL OF EVENT (RECORD OF TRANSACTION TO DB)
        var transaction = new Transaction({
            to: req.body.addresses[0],
            from: req.body.addresses[1],
            change: req.body.addresses[2],
            amount: req.body.outputs[0].value,
            time: moment().format('MMMM Do YYYY, h:mm:ss a'),
        });

        transaction.save((err) => {
            // HANDLE ERROR
            if (err) {return 'rest in pieces'}

            io.emit('notify', {
                user_id: user._id, 
                title: 'Deposit Received',
                message: 'We\'ve recieved your deposit of ' + req.body.outputs.value + 'BTC. Your balance will be updated after 1 confirmation.',
                color: 'success',
            })
        })
    });


    // RESPOND TO API 
    res.status(200).send('ok');
});

// 1 CONFIRMATION
api.post('/callbacks/confirmed', async function(req, res) {
    console.log('confirmed blockcypher api');
    console.log(req.body);
    fs.appendFile('Deposits.txt', 'Confirmed Deposit\n' + JSON.stringify(req.body) + '\n');
    // NEED TO CHECK STRUCTURE OF CALLBACK RESPONSE

    let webhook_id;
    let address = req.body.addresses[1];

    User.findOne({'keyPairs.address' : address}, async function(err, user) {
        var keypair = await WalletService.createKeyPair(user.accountIndex);
        user.btc_address = keypair.address;
        user.btc_s = keypair.secret;

        // SEND COINS TO MAIN WALLET
        async function send() {
            let max; 
            let main_wallet = config.master_address;
            let transaction = new bitcore.Transaction();

            WalletService.getAddressUtxo(address).then(utxo => {
                for(let i=0; i<utxo.length; i++) {
                    transaction.from(utxo[i])
                }

            // set full wallet balance
            WalletService.getAddressBalance(address)
                .then(balance => {
                    max = balance.final_balance;

                    transaction.to(main_wallet, max);
                    transaction.change(keypair.address);

                    let priv_key = new Promise((resolve, reject) => {
                        user.keyPairs.forEach(kp => {
                            if (kp.address == address) {
                                resolve(kp);
                            }
                        })
                    })

                    priv_key.then(kp => {
                        axios.get('https://bitcoinfees.earn.com/api/v1/fees/recommended')
                            .then(fee => {
                                var f = fee.data; 
                                var finalFee = (transaction.toString().length / 2) * f.hourFee;

                                transaction.to(main_wallet, max-finalFee);
                                transaction.fee(finalFee);
                                transaction.sign(kp.secret);

                                // EMIT TRANSACTION!!!!!!!!!
                                axios.post('https://api.blockcypher.com/v1/btc/test3/txs/push', JSON.stringify({
                                    tx: transaction.toString(),
                                })).then(res => {
                                    console.log('Transaction Successfully Sent');
                                    console.log('Response: ');
                                    console.log(res.data);
                                })

                                /*
                                    NOTICE!
                                    Remember that when a user deposits to their HD wallet, they pay fee to send.
                                    Once balance is confirmed, we need to move money to our main wallet.
                                    Moving this money will incur another fee. So add the full amount to users
                                    balance and send the amount MINUS the fee to our big daddy wallet. 
                                */

                                // on success
                                user.balance += bitcore.Unit.fromSatoshis(max).toMilis();

                                io.emit('increase-balance', {
                                    id: user._id,
                                    amount: bitcore.Unit.fromSatoshis(max).toMilis(),
                                });

                                io.emit('notify', {
                                    user_id: user._id,
                                    color: 'success',
                                    message: 'Deposit has been confirmed. Your balance has been updated'
                                });
                                // ======================================
                            })
                    })
                })
            })
        } await send(); 
        // ========================

        user.save((err) => {
            console.log('new keypair generated and saved for' + user.username);

            // unconfirmed hook
            var unconfirmed_hook = {
                "event": "unconfirmed-tx",
                "address": address, 
                "url": config.callback_address + "/new-tx" 
            }

            // confirmed hook
            var confirmed_hook = {
                "event": "confirmed-tx",
                "address": address, 
                "url": config.callback_address + "/confirmed" 
            }

            // delete old webhook
            axios({
                method: 'DELETE',
                url: 'https://api.blockcypher.com/v1/btc/test3/hooks/' + webhook_id,
            });

            // create new webhooks

            // create unconfirmed_hook
            axios({
                method: 'POST', 
                url: 'https://api.blockcypher.com/v1/btc/test3/hooks?token=' + config.blockcypher_token, 
                data: JSON.stringify(unconfirmed_hook)
            }).then(res => {
                console.log('*NEW* Webhook Unconfirmed Webhook Created')
            })

            axios({
                method: 'POST', 
                url: 'https://api.blockcypher.com/v1/btc/test3/hooks?token=' + config.blockcypher_token, 
                data: JSON.stringify(confirmed_hook),
            }).then(res => {
                console.log('*NEW* Webhook Confirmed Webhook Created')
            })
        });
    });
});

pls帮助。 谢谢。

1 个答案:

答案 0 :(得分:1)

输出中两次包含收件人。