ethereum / solc-js

Javascript bindings for the Solidity compiler
https://soliditylang.org
MIT License
1.46k stars 476 forks source link

`Uncaught RangeError: WebAssembly.Compile is disallowed on the main thread` when importing solc in Chrome #456

Closed farooqahmad075 closed 2 years ago

farooqahmad075 commented 4 years ago

When I try to include var solc = require('solc'); in my react app I get an error in chrome console that

Uncaught RangeError: WebAssembly.Compile is disallowed on the main thread, if the buffer size is larger than 4KB. Use WebAssembly.compile, or compile on a worker thread.
    at instantiateSync (soljson.js:1)
    at Object.createWasm [as asm] (soljson.js:1)
    at Object.<anonymous> (soljson.js:1)
    at Object../node_modules/solc/soljson.js (soljson.js:1)
    at __webpack_require__ (bootstrap:785)
    at fn (bootstrap:150)
    at Object../node_modules/solc/index.js (index.js:3)
    at __webpack_require__ (bootstrap:785)
    at fn (bootstrap:150)
    at CompileButton.compile (CompileButton.js:10)
    at HTMLUnknownElement.callCallback (react-dom.development.js:188)
    at Object.invokeGuardedCallbackDev (react-dom.development.js:237)
    at invokeGuardedCallback (react-dom.development.js:292)
    at invokeGuardedCallbackAndCatchFirstError (react-dom.development.js:306)
    at executeDispatch (react-dom.development.js:389)
    at executeDispatchesInOrder (react-dom.development.js:414)
    at executeDispatchesAndRelease (react-dom.development.js:3278)
    at executeDispatchesAndReleaseTopLevel (react-dom.development.js:3287)
    at forEachAccumulated (react-dom.development.js:3259)
    at runEventsInBatch (react-dom.development.js:3304)
    at runExtractedPluginEventsInBatch (react-dom.development.js:3514)
    at handleTopLevel (react-dom.development.js:3558)
    at batchedEventUpdates$1 (react-dom.development.js:21902)
    at batchedEventUpdates (react-dom.development.js:1060)
    at dispatchEventForLegacyPluginEventSystem (react-dom.development.js:3568)
    at attemptToDispatchEvent (react-dom.development.js:4267)
    at dispatchEvent (react-dom.development.js:4189)
    at unstable_runWithPriority (scheduler.development.js:653)
    at runWithPriority$1 (react-dom.development.js:11061)
    at discreteUpdates$1 (react-dom.development.js:21918)
    at discreteUpdates (react-dom.development.js:1071)
    at dispatchDiscreteEvent (react-dom.development.js:4168)

What is causing the issue? or how can I fix using WebAssembly?

chriseth commented 4 years ago

Are you able to move this into a worker process?

farooqahmad075 commented 4 years ago

@chriseth when I use

var worker = new Worker("wasm_worker.js");
    fetch('solc').then(response =>
      response.arrayBuffer()
    ).then(bytes =>
      WebAssembly.compile(bytes)
    ).then(mod =>
      worker.postMessage(mod)
    );

it shows another error Uncaught (in promise) CompileError: WebAssembly.compile(): expected magic word 00 61 73 6d, found 3c 21 44 4f @+0

farooqahmad075 commented 4 years ago

I am totally frustrated, please help me to require solc for my react web app to add solidity compiler in the web.

chriseth commented 4 years ago

It should be enough to use solc-js inside the worker.js - you should not run WebAssembly.compile yourself.

Aniket-Engg commented 4 years ago

@farooqahmad075 Try to use importScripts https://developer.mozilla.org/en-US/docs/Web/API/WorkerGlobalScope/importScripts inside worker to fetch solc binaries using url like https://solc-bin.ethereum.org/bin/soljson-v0.6.1+commit.e6f7d5a4.js

Tectract commented 4 years ago

Bump. This affects me too.

Uncaught RangeError: WebAssembly.Compile is disallowed on the main thread, if the buffer size is larger than 4KB. Use WebAssembly.compile, or compile on a worker thread. at instantiateSync (soljson-v0.6.9+commit.3e3065ac.js:1) at Object.createWasm [as asm] (soljson-v0.6.9+commit.3e3065ac.js:1) at soljson-v0.6.9+commit.3e3065ac.js:1 instantiateSync @ soljson-v0.6.9+commit.3e3065ac.js:1 createWasm @ soljson-v0.6.9+commit.3e3065ac.js:1 (anonymous) @ soljson-v0.6.9+commit.3e3065ac.js:1 browser-solc.min.js:5 Uncaught TypeError: b.cwrap is not a function

I have code that uses cwrap, it used to work. Sadly no more.

chriseth commented 4 years ago

@Tectract are you sure that cwrap is not available anymore, even if you compile the webassembly code in a worker process?

r0qs commented 2 years ago

Hi, I'm closing this because, as pointed out here: https://github.com/ethereum/solc-js/issues/581 and by this comment: https://github.com/ethereum/solc-js/issues/456#issuecomment-604649453, it is currently required to use a web worker with solc-js in some browsers (chromium-based).

You can see examples of how to accomplish it here: https://github.com/ethereum/solc-js/issues/456#issuecomment-606045994, and here: https://github.com/ethereum/solc-js/issues/627#issuecomment-1243501953

@Tectract, here is an example of how you could use the cwrap if you need to use it directly (works on firefox). However, this is not the recommended way to use library since the underline function signature may vary between compiler versions.

    <script type="text/javascript" src="https://binaries.soliditylang.org/bin/soljson-v0.8.17+commit.8df45f5f.js"
        integrity="sha256-YXgo5jvkhcfMLby91aIrWCtA+vqkEBatWVY3uDyQZWw=" crossorigin="anonymous">
        </script>
    <script  type="text/javascript">
        const soljson = window.Module;
        let compile = null;
        if ('_solidity_compile' in soljson) {
            compile = soljson.cwrap('solidity_compile', 'string', ['string', 'number']);
        }

        const input = {
            language: 'Solidity',
            sources: {
                'test.sol': {
                    content: 'contract C { function f() public { } }'
                }
            },
            settings: {
                outputSelection: {
                    '*': {
                        '*': ['*']
                    }
                }
            }
        };

        const output = JSON.parse(compile(JSON.stringify(input)))
        // do something with the output
    </script>
Tectract commented 2 years ago

thanks for the reference. I'll take a look at my code again.

sayhicoelho commented 1 year ago

I'm receiving an error ReferenceError: window is not defined when importing solc-js in my worker.js

image

My worker.js:

import solcjs from 'solc-js'

self.addEventListener('message', async e => {
  const version = 'v0.8.23-stable-2023.11.07'

  const compiler = await solcjs(version)

  const sourceCode = `// SPDX-License-Identifier: MIT

  pragma solidity ^0.8.23;

  import "@openzeppelin/contracts/token/ERC20/ERC20.sol";

  contract Example is ERC20 {
    constructor() ERC20("Example", "EXM") {
        _mint(address(this), 1_000 ** 18);
    }
  }`

  const output = await compiler(sourceCode)

  console.log(output)

  self.postMessage({
    success: true
  })
}, false)