Можете ли вы использовать Web3. js непосредственно в приложении Rails 6 с помощью Webpacker? - PullRequest
1 голос
/ 21 января 2020

Как вы можете взаимодействовать с локальным блокчейном Truffle Ganache через приложение Rails 6? Я создал прототип приложения FixedSupplyToken в vanilla javascript, и все работает как положено. Далее я пытаюсь переместить его в приложение Rails 6. Я нервничаю по поводу использования драгоценных камней Ruby (ethereum .rb - ищу кого-то, кто возьмет на себя обслуживание, другие кажутся заброшенными). Мне интересно, если вы можете импортировать web3. js непосредственно в Rails 6 с помощью Webpacker? Я создал новое приложение Rails 6 и добавил следующее:

yarn add web3
yarn add truffle-contract

Оба установлены и обнаружены в пакете. json:

{
  "name": "app",
  "private": true,
  "dependencies": {
    "@fortawesome/fontawesome-free": "^5.12.0",
    "@fortawesome/free-brands-svg-icons": "^5.12.0",
    "@fortawesome/free-regular-svg-icons": "^5.12.0",
    "@fortawesome/free-solid-svg-icons": "^5.12.0",
    "@rails/actioncable": "^6.0.0",
    "@rails/actiontext": "^6.0.2-1",
    "@rails/activestorage": "^6.0.0",
    "@rails/ujs": "^6.0.0",
    "@rails/webpacker": "4.2.2",
    "bootstrap": "^4.4.1",
    "bootswatch": "^4.4.1",
    "chart.js": "^2.9.3",
    "chartkick": "^3.2.0",
    "datatables.net-bs4": "^1.10.20",
    "datatables.net-buttons-bs4": "^1.6.1",
    "datatables.net-responsive-bs4": "^2.2.3",
    "datatables.net-select-bs4": "^1.3.1",
    "flatpickr": "^4.6.3",
    "jquery": "^3.4.1",
    "popper.js": "^1.16.0",
    "trix": "^1.0.0",
    "truffle-contract": "^4.0.31",
    "turbolinks": "^5.2.0",
    "vue": "^2.6.11",
    "web3": "^1.2.5-rc.0"
  },
  "version": "0.1.0",
  "devDependencies": {
    "webpack-dev-server": "^3.10.1"
  }
}

Затем я добавил это в приложение / javascript / packs (web3 / index. js):

// Import libraries we need.
import Web3 from 'web3';
import contract from 'truffle-contract';

// Import our contract artifacts and turn them into usable abstractions.
import token_artifacts from './FixedSupplyToken.json';

// TokenContract is our usable abstraction, which we'll use through the code below.
var TokenContract = contract(token_artifacts);

// The following code is to interact with contracts.
var accounts;
var account;

window.App = {
    start: function() {
        var self = this;
        // Bootstrap the TokenContract abstraction for Use.
        TokenContract.setProvider(web3.currentProvider);

        // Get the initial account balance so it can be displayed.
        web3.eth.getAccounts(function (err, accs) {
            if (err != null) {
                alert("There was an error fetching your accounts.");
                return;
            }

            if (accs.length == 0) {
                alert("Couldn't get any accounts! Make sure your Ethereum client is configured correctly.");
                return;
            }

            accounts = accs;
            account = accounts[0];

        });
    },

    initManageToken: function() {
        App.updateTokenBalance();
        App.watchTokenEvents();
    },
    updateTokenBalance: function() {
        var tokenInstance;
        TokenContract.deployed().then(function (instance) {
            tokenInstance = instance;
            return tokenInstance.balanceOf.call(account);
        }).then(function (value) {
            console.log(value);
            var balance_element = document.getElementById("balanceTokenInToken");
            balance_element.innerHTML = value.valueOf();
        }).catch(function (e) {
            console.log(e);
            App.setStatus("Error getting balance; see log.");
        });
    },
    watchTokenEvents: function() {
        var tokenInstance;
        TokenContract.deployed().then(function (instance) {
            tokenInstance = instance;
            tokenInstance.allEvents({}, {fromBlock: 0, toBlock: 'latest'}).watch(function (error, result) {
                var alertbox = document.createElement("div");
                alertbox.setAttribute("class", "alert alert-info  alert-dismissible");
                var closeBtn = document.createElement("button");
                closeBtn.setAttribute("type", "button");
                closeBtn.setAttribute("class", "close");
                closeBtn.setAttribute("data-dismiss", "alert");
                closeBtn.innerHTML = "<span>&times;</span>";
                alertbox.appendChild(closeBtn);

                var eventTitle = document.createElement("div");
                eventTitle.innerHTML = '<strong>New Event: ' + result.event + '</strong>';
                alertbox.appendChild(eventTitle);


                var argsBox = document.createElement("textarea");
                argsBox.setAttribute("class", "form-control");
                argsBox.innerText = JSON.stringify(result.args);
                alertbox.appendChild(argsBox);
                document.getElementById("tokenEvents").appendChild(alertbox);
                //document.getElementById("tokenEvents").innerHTML += '<div class="alert alert-info  alert-dismissible" role="alert"> <button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">&times;</span></button><div></div><div>Args: '+JSON.stringify(result.args) + '</div></div>';

            });
        }).catch(function (e) {
            console.log(e);
            App.setStatus("Error getting balance; see log.");
        });
    },

    sendToken: function() {
        var amount = parseInt(document.getElementById("inputAmountSendToken").value);
        var receiver = document.getElementById("inputBeneficiarySendToken").value;

        App.setStatus("Initiating transaction... (please wait)");

        var tokenInstance;
        return TokenContract.deployed().then(function (instance) {
            tokenInstance = instance;
            return tokenInstance.transfer(receiver, amount, {from: account});
        }).then(function () {
            App.setStatus("Transaction complete!");
            App.updateTokenBalance();
        }).catch(function (e) {
            console.log(e);
            self.setStatus("Error sending coin; see log.");
        });
    },

    allowanceToken: function() {
        var self = this;

        var amount = parseInt(document.getElementById("inputAmountAllowanceToken").value);
        var receiver = document.getElementById("inputBeneficiaryAllowanceToken").value;

        this.setStatus("Initiating transaction... (please wait)");

        var tokenInstance;
        return TokenContract.deployed().then(function (instance) {
            tokenInstance = instance;
            return tokenInstance.approve(receiver, amount, {from: account});
        }).then(function () {
            self.setStatus("Transaction complete!");
            App.updateTokenBalance();
        }).catch(function (e) {
            console.log(e);
            self.setStatus("Error sending coin; see log.");
        });
    }
};

document.addEventListener('load', function() {
    // Checking if Web3 has been injected by the browser (Mist/MetaMask)
    if (typeof web3 !== 'undefined') {
        console.warn("Using web3 detected from external source. If you find that your accounts don't appear or you have 0 MetaCoin, ensure you've configured that source properly. If using MetaMask, see the following link. Feel free to delete this warning. :) http://truffleframework.com/tutorials/truffle-and-metamask")
        // Use Mist/MetaMask's provider
        window.web3 = new Web3(web3.currentProvider);
    } else {
        console.warn("No web3 detected. Falling back to http://localhost:8545. You should remove this fallback when you deploy live, as it's inherently insecure. Consider switching to Metamask for development. More info here: http://truffleframework.com/tutorials/truffle-and-metamask");
        // fallback - use your fallback strategy (local node / hosted node + in-dapp id mgmt / fail)
        window.web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:7545"));
    }
});

Затем, когда я запускаю приложение Rails 6 в контейнере Docker, все выглядит нормально, пока webpack-dev-server не попытается скомпилируйте ресурсы, и он выдаст эту ошибку:

webpack-dev-server    | ℹ 「wdm」: Compiling...
webpack-dev-server    | ✖ 「wdm」: Hash: 8531025c7b3abcc5d778
webpack-dev-server    | Version: webpack 4.41.5
webpack-dev-server    | Time: 1963ms
webpack-dev-server    | Built at: 01/21/2020 4:46:26 PM
webpack-dev-server    |                                                           Asset      Size       Chunks                         Chunk Names
webpack-dev-server    |                          js/application-8df32eacba8ebdbf7444.js  6.49 MiB  application  [emitted] [immutable]  application
webpack-dev-server    |                      js/application-8df32eacba8ebdbf7444.js.map  6.93 MiB  application  [emitted] [dev]        application
webpack-dev-server    |                                                   manifest.json   1.9 KiB               [emitted]
webpack-dev-server    | media/images/Logo_medlarge-e2a09f85c0c6ed39d81ce70b3bd44e51.png   130 KiB
webpack-dev-server    |      media/images/pdf_icon-c00c8db0462b60773a72302f7b9d456b.png  1.36 KiB
webpack-dev-server    |                       media/webfonts/fa-brands-400-088a34f7.eot   129 KiB
webpack-dev-server    |                       media/webfonts/fa-brands-400-273dc9bf.ttf   129 KiB
webpack-dev-server    |                     media/webfonts/fa-brands-400-822d94f1.woff2  74.2 KiB
webpack-dev-server    |                       media/webfonts/fa-brands-400-d7229311.svg   692 KiB
webpack-dev-server    |                      media/webfonts/fa-brands-400-f4920c94.woff    87 KiB
webpack-dev-server    |                      media/webfonts/fa-regular-400-3ac49cb3.eot  33.6 KiB
webpack-dev-server    |                    media/webfonts/fa-regular-400-9efb8697.woff2  13.3 KiB
webpack-dev-server    |                     media/webfonts/fa-regular-400-a57bcf76.woff  16.4 KiB
webpack-dev-server    |                      media/webfonts/fa-regular-400-d2e53334.svg   141 KiB
webpack-dev-server    |                      media/webfonts/fa-regular-400-ece54318.ttf  33.3 KiB
webpack-dev-server    |                        media/webfonts/fa-solid-900-2aa6edf8.ttf   189 KiB
webpack-dev-server    |                        media/webfonts/fa-solid-900-7a5de9b0.svg   829 KiB
webpack-dev-server    |                        media/webfonts/fa-solid-900-7fb1cdd9.eot   190 KiB
webpack-dev-server    |                       media/webfonts/fa-solid-900-93f28454.woff  96.7 KiB
webpack-dev-server    |                      media/webfonts/fa-solid-900-f6121be5.woff2  74.3 KiB
webpack-dev-server    |
webpack-dev-server    | ERROR in ./app/javascript/web3/index.js 126:22-26
webpack-dev-server    | "export 'default' (imported as 'Web3') was not found in 'web3'
webpack-dev-server    |     at HarmonyImportSpecifierDependency._getErrors (/app/node_modules/webpack/lib/dependencies/HarmonyImportSpecifierDependency.js:109:11)
webpack-dev-server    |     at HarmonyImportSpecifierDependency.getErrors (/app/node_modules/webpack/lib/dependencies/HarmonyImportSpecifierDependency.js:68:16)
webpack-dev-server    |     at Compilation.reportDependencyErrorsAndWarnings (/app/node_modules/webpack/lib/Compilation.js:1463:22)
webpack-dev-server    |     at /app/node_modules/webpack/lib/Compilation.js:1258:10
webpack-dev-server    |     at AsyncSeriesHook.eval [as callAsync] (eval at create (/app/node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:15:1)
webpack-dev-server    |     at AsyncSeriesHook.lazyCompileHook (/app/node_modules/tapable/lib/Hook.js:154:20)
webpack-dev-server    |     at Compilation.finish (/app/node_modules/webpack/lib/Compilation.js:1253:28)
webpack-dev-server    |     at /app/node_modules/webpack/lib/Compiler.js:672:17
webpack-dev-server    |     at _done (eval at create (/app/node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:9:1)
webpack-dev-server    |     at eval (eval at create (/app/node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:32:22)
webpack-dev-server    |
webpack-dev-server    | ERROR in ./app/javascript/web3/index.js 130:22-26
webpack-dev-server    | "export 'default' (imported as 'Web3') was not found in 'web3'
webpack-dev-server    |     at HarmonyImportSpecifierDependency._getErrors (/app/node_modules/webpack/lib/dependencies/HarmonyImportSpecifierDependency.js:109:11)
webpack-dev-server    |     at HarmonyImportSpecifierDependency.getErrors (/app/node_modules/webpack/lib/dependencies/HarmonyImportSpecifierDependency.js:68:16)
webpack-dev-server    |     at Compilation.reportDependencyErrorsAndWarnings (/app/node_modules/webpack/lib/Compilation.js:1463:22)
webpack-dev-server    |     at /app/node_modules/webpack/lib/Compilation.js:1258:10
webpack-dev-server    |     at AsyncSeriesHook.eval [as callAsync] (eval at create (/app/node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:15:1)
webpack-dev-server    |     at AsyncSeriesHook.lazyCompileHook (/app/node_modules/tapable/lib/Hook.js:154:20)
webpack-dev-server    |     at Compilation.finish (/app/node_modules/webpack/lib/Compilation.js:1253:28)
webpack-dev-server    |     at /app/node_modules/webpack/lib/Compiler.js:672:17
webpack-dev-server    |     at _done (eval at create (/app/node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:9:1)
webpack-dev-server    |     at eval (eval at create (/app/node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:32:22)
webpack-dev-server    |
webpack-dev-server    | ERROR in ./app/javascript/web3/index.js 130:31-35
webpack-dev-server    | "export 'default' (imported as 'Web3') was not found in 'web3'
webpack-dev-server    |     at HarmonyImportSpecifierDependency._getErrors (/app/node_modules/webpack/lib/dependencies/HarmonyImportSpecifierDependency.js:109:11)
webpack-dev-server    |     at HarmonyImportSpecifierDependency.getErrors (/app/node_modules/webpack/lib/dependencies/HarmonyImportSpecifierDependency.js:68:16)
webpack-dev-server    |     at Compilation.reportDependencyErrorsAndWarnings (/app/node_modules/webpack/lib/Compilation.js:1463:22)
webpack-dev-server    |     at /app/node_modules/webpack/lib/Compilation.js:1258:10
webpack-dev-server    |     at AsyncSeriesHook.eval [as callAsync] (eval at create (/app/node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:15:1)
webpack-dev-server    |     at AsyncSeriesHook.lazyCompileHook (/app/node_modules/tapable/lib/Hook.js:154:20)
webpack-dev-server    |     at Compilation.finish (/app/node_modules/webpack/lib/Compilation.js:1253:28)
webpack-dev-server    |     at /app/node_modules/webpack/lib/Compiler.js:672:17
webpack-dev-server    |     at _done (eval at create (/app/node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:9:1)
webpack-dev-server    |     at eval (eval at create (/app/node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:32:22)
webpack-dev-server    | ℹ 「wdm」: Failed to compile.

Веб-поиски не обнаружили каких-либо возможных решений, и я не нашел ни одного примера использования web3. js с использованием Webpacker в Rails. Является ли это возможным; какие-нибудь решения или примеры там? Спасибо!

1 Ответ

0 голосов
/ 22 января 2020

Я думаю это конфликт имен. Вы назвали свой javascript файл web3/index.js, который Webpack видит как web3; это конфликтует с модулем узла, который вы пытаетесь импортировать под тем же именем. Попробуйте переименовать вашу собственную javascript папку / файл в другое. Похожие проблемы: https://github.com/webpack/webpack/issues/4817#issuecomment -316119100

...