【问题标题】:Webhooks in Bitcoin Transactions - How to Apply Business Logics?比特币交易中的 Webhook - 如何应用业务逻辑?
【发布时间】:2018-10-04 23:07:29
【问题描述】:

我想开始在我的网站上接受比特币。

为了做到这一点,我编写了以下代码,但我真的很难理解在事务完成后如何实现正确的业务逻辑。

代码如下:

<html>

<head>

    <title>Pay with Bitcoin</title>

    <script>

            //Gets the URL of the Webpage and gets the price value of this transaction in USD.
            //For simplicity Here the Value is passed in the URL.
            //However in production you wanna use POST instead of GET.

            const myUrl = window.location.href;
            const url = new URL(myUrl);
            const usdPrice = url.searchParams.get("price");

            //This is the function where all the magin happens

            const showQR = () => {

                    //URL of the api which will provide us with current BTC exchange rate

                    const apiUrl = "https://blockchain.info/ticker";

                    const hr = new XMLHttpRequest();

                    hr.open('GET', apiUrl, true);

                    hr.onreadystatechange = function(){

                    //Make sure the API sent a valid response

                        if(hr.readyState == 4){

                            let ticker = JSON.parse(hr.responseText);

                            //Get last BTC/USD exchange value from the API , then convert Price from USD to BTC 

                            let BTCprice = ticker.USD.last;

                            let btcToPay = usdPrice / BTCprice;

                            //Make sure you have just 8 decimal points in your BTC price!!

                            btcToPay = btcToPay.toFixed(8);

                            //Use google API (or other...) to create the QR code. Pass on your btc public address and 
                            //the amount (btc price) dynamically created. Message and label parameters can be dynamic too.

                            let qrurl = "https://chart.googleapis.com/chart?chs=250x250&cht=qr&chl=bitcoin:1BAnkZn1qW42uRTyG2sCRN9F5kgtfb5Bci?amount="+btcToPay+"%26label=CarRental%26message=BookingID123456";

                            //Populate the 'btc' DIV with QR code and other info...
                            document.getElementById('btc').innerHTML = "<img src=" +qrurl+"><br> <span class = 'greenMoney'>" + usdPrice + " usd / " + btcToPay + " BTC </span>";

                            }

                    }

                hr.send();

            };

    </script>

</head>

<body onload = "showQR()">

    <h1>Pay with BitCoin</h1>

    <div id = "btc">

    </div>

</body>

</html>

此代码执行以下操作:

  1. 使用区块链 API 获取当前 USD/BTC 汇率。

  2. 获取 URL 的美元价格并将其转换为 BTC

  3. 使用 google API 生成二维码。

  4. 将价格、标签和信息嵌入二维码

  5. 在 DIV 中呈现二维码

我还设置了一个网络挂钩服务,它将监听指定钱包地址中发生的新交易。然后通过 POST 请求对我的服务器进行回调。

问题是:传递给二维码的标签和消息参数不会写入区块链。

它们只是客户方便的参考,以提醒他该特定交易支付的费用。

因此,对我的服务器的回调实际上是无用的。

事实上,回调不会返回任何预订 ID 或任何其他可以帮助我了解谁支付了哪些信息的信息。不用说,在这种情况下,业务逻辑是不可能的:我无法更新我的数据库中的订单状态,我无法向正确的客户发送确认电子邮件。

如何将相关信息(例如预订 ID)嵌入到 BTC 支付中,最好是通过二维码?

如果可能的话,我以后如何在我的服务器收到回调通知我有新的付款到我的 BTC 钱包时检索此信息?

【问题讨论】:

    标签: javascript html blockchain webhooks bitcoin


    【解决方案1】:

    简而言之,你不能。

    在接受付款时,您应该为每张发票提供一个新的 BTC 地址。这样,当您收到收款通知时,您可以检查收款地址以查看正在支付的发票,并将收到的金额与预期金额进行比较。

    注意

    从技术上讲,您可以将订单 ID 等内容嵌入到 OP_RETURN 中。但是,大多数钱包不支持这样的交易,任何想要从交易所账户向你付款的用户都无法遵守。

    【讨论】:

      【解决方案2】:

      @Raghav Sood 感谢您的意见,让我找到了正确的方向。

      在后端使用 NodeJS/Express/MongoDB,我设法实现了一个我想在这里分享的解决方案。

      在开始之前,我想先声明一下:这个解决方案不是唯一的,也不是最好的,不是最快的,也可能不是最优雅的。

      无论如何,此解决方案的优势在于不依赖打包的第三方解决方案。这符合比特币社区整个“无中介”理念的精神。最重要的是,您的 XPub 始终保留在您的服务器中,不与任何外部服务共享,这可能是最明智的方法。

      话虽如此,以下是向客户显示动态唯一 BTC 地址的方法:

      1. 首先,我设置了一个计数器,用于跟踪从我的 HD 钱包中为客户创建的 btc 地址的数量。

      这对于确保您永远不会向客户提供两次相同的地址很重要,这有利于各方的隐私,也有利于在您的应用中实现业务逻辑。

      为了做到这一点,我将一个“计数器值”存储到我的数据库中。每次有人访问 BTC 支付页面时,这个值都会使用“dealCount”函数从 mongo 检索并分配给“serialPay”变量,该变量等于从 Mongo + 1 获得的值。在后端,代码将是像这样:

      `function dealCount(){`
      
              return new Promise(function(resolve, reject){
      
                  Deal.find({_id: "ID_OF_OBJ_WHERE_YOU_STORE_COUNTER"}, function(err, data){
      
                    if(err){
      
                      console.log(err);
      
                    }
      
                      resolve(data[0].serialDeal + 1);
      
                  })
      
              })
      
            };
      

      获得的新值(稍后将再次保存到 Mongo 以跟踪创建的地址)用于为手头的客户生成新的 BTC 公共地址。如果你继续阅读,你会看到如何。

      要动态创建新的公共地址,需要其 HD 钱包的 xPub 密钥。如果一个人在 NodeJS 中编码,那么有几个库(可以导入到服务器中)可以很容易地启用此操作:bitcoinjs-lib 和/或 bitcore-lib。我个人选择了 Bitcore-lib,因为要处理的依赖项更少,而且我发现支持材料更容易消化。

      在代码方面,地址生成过程如下:

              const bitcore = require('bitcore-lib');
      
              app.post("/pay.html", urlencodedParser, function(req, res){
      
              let serialPay = dealCount();
      
              serialPay.then(function(serialPay){
      
                const pub = new bitcore.HDPublicKey('INSERT_HERE_YOUR_XPUB_KEY');
      
                let derivedHdPk = pub.derive('m/0/'+serialPay);
      
                let derivedPk = derivedHdPk.publicKey;
      
                let myDynAddress = new bitcore.Address(derivedPk);
      
                res.render('pay', {myDynAddress: myDynAddress});
      
              });
      
            });
      
      1. 然后,使用 EJS 作为模板引擎,我可以很容易地在前端(/pay.ejs)中使接收比特币地址动态化:

        let myDynAddress = "<%=myDynAddress%>";
        let qrurl = "https://chart.googleapis.com/chart?chs=250x250&cht=qr&chl=bitcoin:"+myDynAddress+"?amount="+btcToPay+"%26label=CarRental";
        

        这将动态生成二维码。在原始问题中,可以看到如何将其呈现到网页中。同时,还应该设置一项功能,将更新的“serialPay”计数器存储回数据库。

      2. 此时应该只开始监控对生成的动态 BTC 地址的传入(未确认)付款。一个简单的方法是使用 blockchain.info websocket API。当付款到达时,事情会按照@Raghav Sood 的建议进行:检查收到的交易,确保客户向正确的地址支付了正确的金额。

      现在你知道谁为什么买单了,各种业务逻辑都可以触发。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-01-22
        • 1970-01-01
        • 1970-01-01
        • 2019-04-05
        • 2021-04-15
        • 2022-07-19
        • 2017-05-31
        • 1970-01-01
        相关资源
        最近更新 更多