diff --git a/README.md b/README.md index 1d2d276..f522304 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,6 @@ then add embark-nim-compiler to the plugins section in `embark.json`: "plugins": { "embark-nim-compiler": { "setupBlockchainOptions": true, - "useTestnet": false, "libHeraPath": "path/to/libHera.so" } } @@ -28,6 +27,13 @@ then add embark-nim-compiler to the plugins section in `embark.json`: - `setupBlockchainOptions`: boolean that when set to `true`, will change the blockchain config for you. If you set this to `false`, you need to set the blockchain config yourself so that it supports eWasm - `libHeraPath`: string path to the file `libHera.so` that is used to have Geth use Hera as a VM. Not needed if `setupBlockchainOptions` is `false` +Since you need to have Geth+Hera installed, make sure that the built Geth is in your Path or change `ethereumClientBin` in you blockchain config to point to the Geth executable (absolute path). + +### Temporary endpoint + +You can use our temporary endpoint available at `http://159.65.52.177:8545/`. +This endpoint connects to an eWasm testnet node, but we'll probably shut down at some point, so don't rely on it for production. + ## Requirements - [Embark](https://www.npmjs.com/package/embark) 5.0.0 or higher diff --git a/ewasm-testnet-geth-config.json b/ewasm-testnet-geth-config.json index 2c01cb3..78d538b 100644 --- a/ewasm-testnet-geth-config.json +++ b/ewasm-testnet-geth-config.json @@ -23,7 +23,7 @@ "balance": "0x1" }, "9fa4f23079bae7a7a5c392b67e18093310315bfc": { - "balance": "0x200000000000000000000000000000000000000000000000000000000000000" + "balance": "100000000000000000000000000" } }, "number": "0x0", diff --git a/index.js b/index.js index a978935..9f8f321 100644 --- a/index.js +++ b/index.js @@ -2,6 +2,7 @@ const fs = require("fs"); const path = require('path'); const {exec} = require('child_process'); const async = require('async'); +const binaryen = require('binaryen'); function buf2hex(buffer) { // buffer is an ArrayBuffer return Array.prototype.map.call(new Uint8Array(buffer), x => ('00' + x.toString(16)).slice(-2)).join(''); @@ -44,29 +45,48 @@ class NimCompiler { compiledObject[className] = {}; // Compile file - // TODO wait for docker image - - - // Get code from wasm file - const codeHex = "0x" + buf2hex(fs.readFileSync(file.path.replace('.nim', '.wasm'))); - - compiledObject[className].runtimeBytecode = codeHex; - compiledObject[className].realRuntimeBytecode = codeHex; - compiledObject[className].code = codeHex; - - // Get ABI from nim file - exec(`docker run --entrypoint="abi_gen" -v "${this.dappPath('contracts')}":/code/ -w /code/ jacqueswww/nimclang ${path.basename(file.path)}`, (err, stdout, stderr) => { + exec(`docker run --entrypoint="nimplayc" -v "${this.dappPath()}":/code/ -w /code/ jacqueswww/nimclang ${file.path.replace(/\\/g, '/')}`, (err, stdout, stderr) => { if (err) { - this.logger.error('Error while getting ABI'); + this.logger.error('Error while compiling Nim contract'); this.logger.error(stderr); return eachCb(err); } + + // Get bytecode from the WASM file + let escapedWast = ''; + const wasm = buf2hex(fs.readFileSync(file.path.replace('.nim', '.wasm'))); + for (let i = 0; i < wasm.length; i += 2) { + escapedWast += "\\" + wasm.slice(i, i + 2); + } + + let codeHex; + const wast = `(module (import "ethereum" "finish" (func $finish (param i32 i32))) (memory 100) (data (i32.const 0) "${escapedWast}") (export "memory" (memory 0)) (export "main" (func $main)) (func $main (call $finish (i32.const 0) (i32.const ${wasm.length / 2}))))`; + try { - compiledObject[className].abiDefinition = JSON.parse(stdout); - return eachCb(); + let module = binaryen.parseText(wast); + codeHex = buf2hex(module.emitBinary()); } catch (e) { return eachCb(e); } + + compiledObject[className].runtimeBytecode = codeHex; + compiledObject[className].realRuntimeBytecode = codeHex; + compiledObject[className].code = codeHex; + + // Get ABI from nim file + exec(`docker run --entrypoint="abi_gen" -v "${this.dappPath('contracts')}":/code/ -w /code/ jacqueswww/nimclang ${path.basename(file.path)}`, (err, stdout, stderr) => { + if (err) { + this.logger.error('Error while getting ABI'); + this.logger.error(stderr); + return eachCb(err); + } + try { + compiledObject[className].abiDefinition = JSON.parse(stdout); + return eachCb(); + } catch (e) { + return eachCb(e); + } + }); }); }, (err) => { cb(err, compiledObject); diff --git a/package.json b/package.json index 4a6038e..fea9764 100644 --- a/package.json +++ b/package.json @@ -26,6 +26,6 @@ }, "dependencies": { "async": "^3.1.0", - "shelljs": "^0.8.3" + "binaryen": "^89.0.0" } } diff --git a/yarn.lock b/yarn.lock index a64ee6d..0a91b32 100644 --- a/yarn.lock +++ b/yarn.lock @@ -82,6 +82,11 @@ balanced-match@^1.0.0: resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= +binaryen@^89.0.0: + version "89.0.0" + resolved "https://registry.yarnpkg.com/binaryen/-/binaryen-89.0.0.tgz#ae5044422fddae3d5a117d62da5ceca46ff8b914" + integrity sha512-yvTTdiCzWUQb3NHcdpiyhQOTUpTw8l+YcjvDQ1+R4e2jr3VQspMScoQitOTPC6mftXkEP67x5S14kCApNX/X1Q== + brace-expansion@^1.1.7: version "1.1.11" resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" @@ -340,7 +345,7 @@ functional-red-black-tree@^1.0.1: resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= -glob@^7.0.0, glob@^7.1.2, glob@^7.1.3: +glob@^7.1.2, glob@^7.1.3: version "7.1.4" resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.4.tgz#aa608a2f6c577ad357e1ae5a5c26d9a8d1969255" integrity sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A== @@ -419,11 +424,6 @@ inquirer@^6.2.2: strip-ansi "^5.1.0" through "^2.3.6" -interpret@^1.0.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.2.0.tgz#d5061a6224be58e8083985f5014d844359576296" - integrity sha512-mT34yGKMNceBQUoVn7iCDKDntA7SC6gycMAWzGx1z/CMCTV7b2AAtXlo3nRyHZ1FelRkQbQjprHSYGwzLtkVbw== - is-fullwidth-code-point@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" @@ -572,11 +572,6 @@ path-key@^2.0.1: resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A= -path-parse@^1.0.6: - version "1.0.6" - resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c" - integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw== - prelude-ls@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" @@ -592,13 +587,6 @@ punycode@^2.1.0: resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== -rechoir@^0.6.2: - version "0.6.2" - resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384" - integrity sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q= - dependencies: - resolve "^1.1.6" - regexpp@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-2.0.1.tgz#8d19d31cf632482b589049f8281f93dbcba4d07f" @@ -609,13 +597,6 @@ resolve-from@^4.0.0: resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== -resolve@^1.1.6: - version "1.12.0" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.12.0.tgz#3fc644a35c84a48554609ff26ec52b66fa577df6" - integrity sha512-B/dOmuoAik5bKcD6s6nXDCjzUKnaDvdkRyAk6rsmsKLipWj4797iothd7jmmUhWTfinVMU+wc56rYKsit2Qy4w== - dependencies: - path-parse "^1.0.6" - restore-cursor@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-2.0.0.tgz#9f7ee287f82fd326d4fd162923d62129eee0dfaf" @@ -667,15 +648,6 @@ shebang-regex@^1.0.0: resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" integrity sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM= -shelljs@^0.8.3: - version "0.8.3" - resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.8.3.tgz#a7f3319520ebf09ee81275b2368adb286659b097" - integrity sha512-fc0BKlAWiLpwZljmOvAOTE/gXawtCoNrP5oaY7KIaQbbyHeQVg01pSEuEGvGh3HEdBU4baCD7wQBwADmM/7f7A== - dependencies: - glob "^7.0.0" - interpret "^1.0.0" - rechoir "^0.6.2" - signal-exit@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d"