Search code examples
javascriptethereumweb3jsgo-ethereum

how does ethereum web3js imports "crypto-js"?


I am a bit confused by the syntax used in the web3.js file of the ethereum repository, although there is no file named crypto-js nor any npm or yarn, how is this import is being done? https://github.com/ethereum/go-ethereum/blob/master/internal/jsre/deps/web3.js#L1828


Solution

  • The javascript file you're looking at (web3.js) is the result of web3's build, i.e., a browserify bundle of the whole web3 project and its dependencies. The entire crypto-js library from npm is bundled in that file - that's why there's no other references to crypto-js within the go-ethereum project. Let's take a look at the object containing the code you've linked, which looks something like this:

    {
        //...
        19: [
            function(require, module, exports) {
                //...
                var CryptoJS = require('crypto-js');
                var sha3 = require('crypto-js/sha3');
                //...
            },
            {
                "crypto-js": 59,
                "crypto-js/sha3": 80
            }
        ]
        //...
    }
    

    This key/value pair represents a module. The key 19 is an ID for the module within the bundle. The value is an array with two elements: (1) the module code and (2) the module's dependencies. The dependencies are given as an object with module name keys and module ID values. Thus, the crypto-js module can be found in the same object under key 59, and likewise crypto-js/sha3 under key 80.

    Modifying web3.js can be done by obtaining the source and rebuilding it. The version in the go-ethereum repo seems to be 0.20.1, which corresponds to commit 996148d3 in the web3 repository. Building this version is somewhat of a pain, as back then web3 did not commit package-lock.json. I was able to build it by forcing the use of gulp 3.9 and node 10. As for replacing crypto-js, you can edit lib/utils/sha3.js and replace it with a different sha3 implementation.

    After rebuilding web3, copy dist/web3-light.js to internals/jsre/deps/web3.js in the go-ethereum repo and run go generate to regenerate internals/jsre/deps/bindata.go. Finally, build geth.

    Putting this all together:

    # Clone web3
    git clone https://github.com/ChainSafe/web3.js
    cd web3.js
    git switch -c replace-crypto-js 996148d356570745ef20630b499bce37f8484920
    
    # Edit the sha3 implementation
    vim lib/utils/sha3.js
    
    # Build using gulp 3.9 and node 10
    sed -i 's/"gulp": ">=3.9.0"/"gulp": "^3.9.0"/' package.json
    npm install
    npm --no-save install node@10
    PATH=./node_modules/.bin gulp
    
    # Clone go-ethereum
    cd ..
    git clone https://github.com/ethereum/go-ethereum.git
    cd go-ethereum
    
    # Copy new web3 and regenerate bindata.go
    cp ../web3.js/dist/web3-light.js internal/jsre/deps/web3.js
    make devtools
    PATH=$PATH:$(go env GOPATH)/bin go generate internal/jsre/deps/deps.go
    
    # Build geth and test out changes in console
    make geth
    ./build/bin/geth console