Repository files navigation

Build Status

RuffVM

RuffVM is a light-weight VM environment designed for DApps(Decentralized applications). It provides secure, isolated execution environment as well as resource control (e.g Memory and CPU) for Dapps. It lowers the barrier of Blockchain application development by significant amount via JavaScript based abstraction (But not limited to JS).

RuffVM's build-in,plug-in mechanism allows developers to customize DApp runtime depends on their need, these modules will be completely independent to a public chain base and will be compatible with any Blockchain platforms(e.g EOS,Ethereum,ruffchain).

RoadMap

Present

  • 0.1 Implementation on Node.js
  • 0.2 Build-in modules

In progress

  • Verification and optimization on ruffchain blockchain
  • Standerlize modules build-in, plug-in mechanism

Future release

  • Split out ruffvm-core into separate repo
  • Port to EOS
  • Port to Ethereum
  • DApp Module registry

RuffVM-Node

RuffVM integration for node.js, aim to provide usable, secure sandbox in order to run untrusted javascript code in nodejs, Resource control abilities supported in this version (e.g. cpu time and memory). RuffVM leverage jerryscript(a lightweight JavaScript engine) as javascript runtime, it is isolated with Node V8 engine naturally. Refer some idea from duktape.node.

Building manually and running tests

Currently enabled build on Macos & Linux with C++1y support

build

git clone --recurse-submodules https://github.com/ruffchain/RuffVM.git
cd RuffVM
npm install

build manually

node-gyp configure
node-gyp build

how to test

npm run test

data type supported between VM and Host by bridge

  • Undefined
  • Boolean
  • Number
  • String
  • ArrayBuffer

API

Class: Script

new Script(code)

  • code <string> code to compile and evaluate in VM
  • Returns: <Script>

script.setUserCode(userCode)

  • userCode <string> script to run in VM after code
  • Returns: <Script>

script.setOption(options)

  • options
    • cpuCount <number> cpu count to limit
    • memSizeKB <number> memory size in KB
  • Returns: <Script>

script.setSandbox(sandbox)

  • sandbox <Object> will be the global object in vm
  • Returns: <Script>

script.runAsync()

  • Returns: <Promise>
    • resolve return value from script
    • reject error status (boolean)

createScript(code)

  • code <string> code to compile and evaluate in VM
  • Returns: <Script>

Example

Host return no Promised value to VM

constassert=require('assert')const{ createScript }=require('ruffvm')constcode=` function helloFun(parameterString) { var buf = new Uint8Array(20) buf[0] = 1 buf[1] = 2 return hello(buf.buffer) }`letisTriggered=falseconstsandbox={hello: function(resolve,param){isTriggered=trueconstu8=newUint8Array(param,0,param.byteLength)assert(u8.length===20)assert((u8[0]=1&&u8[1]===2))returntrue}};(async()=>{constres=awaitcreateScript(code).setUserCode(`helloFun("ruffVM")`).setSandbox(sandbox).setOption({cpuCount: 1,memSizeKB: 200}).runAsync()assert(isTriggered)assert(res===true)})()

Host return Resolved Promised value to VM

constassert=require('assert')constvm=require('ruffvm')functionbufferToArrayBuffer(b){returnb.buffer.slice(b.byteOffset,b.byteOffset+b.byteLength);}constcode=` function helloFun(parameterString) { var buf = new Uint8Array(20) buf[0] = 1 buf[1] = 2 return hello(buf.buffer) }`constsandbox={hello: function(vmResolve,name){returnnewPromise(function(resolve){letab1=bufferToArrayBuffer(Buffer.from('this is hostapi test'))constu8=newUint8Array(ab1,0,ab1.byteLength)setTimeout(()=>{vmResolve(u8)// send resolved value to VMresolve()},20)})}};(async()=>{constres=awaitcreateScript(code).setUserCode(`helloFun("ruffVM")`).setSandbox(sandbox).setOption({cpuCount: 1,memSizeKB: 200}).runAsync()constexpectBuffer=bufferToArrayBuffer(Buffer.from('this is hostapi test'))constexpectU8=newUint8Array(expectBuffer,0,expectBuffer.byteLength)constresU8=newUint8Array(res,0,res.byteLength)assert.deepStrictEqual(resU8,expectU8)})()

For more example please refer to test/basic.test.js

Function export to VM from Node.js

  • function hostApi(vmResolve, parmFromVM)
    • vmResolve: resolve handler to resolve Resolved Value on Node.js, just ignore this handler if the return value is not promise
    • paramFromVM: parameter specified from VM

Main usage

ruffchain use ruffvm as its smart contract execute engine, provide the ability for user develop their smart contract by JavaScript.

Difference from Node's vm

Following code will escape node vm sandbox and do exit on host

constvm=require('vm');vm.runInNewContext('this.constructor.constructor("return process")().exit()');console.log('Never gets executed.');

Difference from duktape.node

ruffvm-node support set limit on CPU and Memory comparing to duktape.node

To do list

  • Enable build on Linux
  • Add chain style API
  • Add SharedArrayBuffer support (ES2017)
  • Evaluate XS JavaScript Engine

Known improvements

Does not support multiple instance of vm run simultaneously. Communication between VM and Host is not optimized for heavily usage scenario.

About

RuffVM is a small embeddable VM provides security, isolate execution environment for run DApp.

Resources

Stars

21 stars

Watchers

7 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Repository files navigation

Build Status

RuffVM

RuffVM is a light-weight VM environment designed for DApps(Decentralized applications). It provides secure, isolated execution environment as well as resource control (e.g Memory and CPU) for Dapps. It lowers the barrier of Blockchain application development by significant amount via JavaScript based abstraction (But not limited to JS).

RuffVM's build-in,plug-in mechanism allows developers to customize DApp runtime depends on their need, these modules will be completely independent to a public chain base and will be compatible with any Blockchain platforms(e.g EOS,Ethereum,ruffchain).

RoadMap

Present

  • 0.1 Implementation on Node.js
  • 0.2 Build-in modules

In progress

  • Verification and optimization on ruffchain blockchain
  • Standerlize modules build-in, plug-in mechanism

Future release

  • Split out ruffvm-core into separate repo
  • Port to EOS
  • Port to Ethereum
  • DApp Module registry

RuffVM-Node

RuffVM integration for node.js, aim to provide usable, secure sandbox in order to run untrusted javascript code in nodejs, Resource control abilities supported in this version (e.g. cpu time and memory). RuffVM leverage jerryscript(a lightweight JavaScript engine) as javascript runtime, it is isolated with Node V8 engine naturally. Refer some idea from duktape.node.

Building manually and running tests

Currently enabled build on Macos & Linux with C++1y support

build

git clone --recurse-submodules https://github.com/ruffchain/RuffVM.git
cd RuffVM
npm install

build manually

node-gyp configure
node-gyp build

how to test

npm run test

data type supported between VM and Host by bridge

  • Undefined
  • Boolean
  • Number
  • String
  • ArrayBuffer

API

Class: Script

new Script(code)

  • code <string> code to compile and evaluate in VM
  • Returns: <Script>

script.setUserCode(userCode)

  • userCode <string> script to run in VM after code
  • Returns: <Script>

script.setOption(options)

  • options
    • cpuCount <number> cpu count to limit
    • memSizeKB <number> memory size in KB
  • Returns: <Script>

script.setSandbox(sandbox)

  • sandbox <Object> will be the global object in vm
  • Returns: <Script>

script.runAsync()

  • Returns: <Promise>
    • resolve return value from script
    • reject error status (boolean)

createScript(code)

  • code <string> code to compile and evaluate in VM
  • Returns: <Script>

Example

Host return no Promised value to VM

constassert=require('assert')const{ createScript }=require('ruffvm')constcode=` function helloFun(parameterString) { var buf = new Uint8Array(20) buf[0] = 1 buf[1] = 2 return hello(buf.buffer) }`letisTriggered=falseconstsandbox={hello: function(resolve,param){isTriggered=trueconstu8=newUint8Array(param,0,param.byteLength)assert(u8.length===20)assert((u8[0]=1&&u8[1]===2))returntrue}};(async()=>{constres=awaitcreateScript(code).setUserCode(`helloFun("ruffVM")`).setSandbox(sandbox).setOption({cpuCount: 1,memSizeKB: 200}).runAsync()assert(isTriggered)assert(res===true)})()

Host return Resolved Promised value to VM

constassert=require('assert')constvm=require('ruffvm')functionbufferToArrayBuffer(b){returnb.buffer.slice(b.byteOffset,b.byteOffset+b.byteLength);}constcode=` function helloFun(parameterString) { var buf = new Uint8Array(20) buf[0] = 1 buf[1] = 2 return hello(buf.buffer) }`constsandbox={hello: function(vmResolve,name){returnnewPromise(function(resolve){letab1=bufferToArrayBuffer(Buffer.from('this is hostapi test'))constu8=newUint8Array(ab1,0,ab1.byteLength)setTimeout(()=>{vmResolve(u8)// send resolved value to VMresolve()},20)})}};(async()=>{constres=awaitcreateScript(code).setUserCode(`helloFun("ruffVM")`).setSandbox(sandbox).setOption({cpuCount: 1,memSizeKB: 200}).runAsync()constexpectBuffer=bufferToArrayBuffer(Buffer.from('this is hostapi test'))constexpectU8=newUint8Array(expectBuffer,0,expectBuffer.byteLength)constresU8=newUint8Array(res,0,res.byteLength)assert.deepStrictEqual(resU8,expectU8)})()

For more example please refer to test/basic.test.js

Function export to VM from Node.js

  • function hostApi(vmResolve, parmFromVM)
    • vmResolve: resolve handler to resolve Resolved Value on Node.js, just ignore this handler if the return value is not promise
    • paramFromVM: parameter specified from VM

Main usage

ruffchain use ruffvm as its smart contract execute engine, provide the ability for user develop their smart contract by JavaScript.

Difference from Node's vm

Following code will escape node vm sandbox and do exit on host

constvm=require('vm');vm.runInNewContext('this.constructor.constructor("return process")().exit()');console.log('Never gets executed.');

Difference from duktape.node

ruffvm-node support set limit on CPU and Memory comparing to duktape.node

To do list

  • Enable build on Linux
  • Add chain style API
  • Add SharedArrayBuffer support (ES2017)
  • Evaluate XS JavaScript Engine

Known improvements

Does not support multiple instance of vm run simultaneously. Communication between VM and Host is not optimized for heavily usage scenario.

About

RuffVM is a small embeddable VM provides security, isolate execution environment for run DApp.

Resources

Stars

21 stars

Watchers

7 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Build Status

RuffVM

RuffVM is a light-weight VM environment designed for DApps(Decentralized applications). It provides secure, isolated execution environment as well as resource control (e.g Memory and CPU) for Dapps. It lowers the barrier of Blockchain application development by significant amount via JavaScript based abstraction (But not limited to JS).

RuffVM's build-in,plug-in mechanism allows developers to customize DApp runtime depends on their need, these modules will be completely independent to a public chain base and will be compatible with any Blockchain platforms(e.g EOS,Ethereum,ruffchain).

RoadMap

Present

  • 0.1 Implementation on Node.js
  • 0.2 Build-in modules

In progress

  • Verification and optimization on ruffchain blockchain
  • Standerlize modules build-in, plug-in mechanism

Future release

  • Split out ruffvm-core into separate repo
  • Port to EOS
  • Port to Ethereum
  • DApp Module registry

RuffVM-Node

RuffVM integration for node.js, aim to provide usable, secure sandbox in order to run untrusted javascript code in nodejs, Resource control abilities supported in this version (e.g. cpu time and memory). RuffVM leverage jerryscript(a lightweight JavaScript engine) as javascript runtime, it is isolated with Node V8 engine naturally. Refer some idea from duktape.node.

Building manually and running tests

Currently enabled build on Macos & Linux with C++1y support

build

git clone --recurse-submodules https://github.com/ruffchain/RuffVM.git
cd RuffVM
npm install

build manually

node-gyp configure
node-gyp build

how to test

npm run test

data type supported between VM and Host by bridge

  • Undefined
  • Boolean
  • Number
  • String
  • ArrayBuffer

API

Class: Script

new Script(code)

  • code <string> code to compile and evaluate in VM
  • Returns: <Script>

script.setUserCode(userCode)

  • userCode <string> script to run in VM after code
  • Returns: <Script>

script.setOption(options)

  • options
    • cpuCount <number> cpu count to limit
    • memSizeKB <number> memory size in KB
  • Returns: <Script>

script.setSandbox(sandbox)

  • sandbox <Object> will be the global object in vm
  • Returns: <Script>

script.runAsync()

  • Returns: <Promise>
    • resolve return value from script
    • reject error status (boolean)

createScript(code)

  • code <string> code to compile and evaluate in VM
  • Returns: <Script>

Example

Host return no Promised value to VM

constassert=require('assert')const{ createScript }=require('ruffvm')constcode=` function helloFun(parameterString) { var buf = new Uint8Array(20) buf[0] = 1 buf[1] = 2 return hello(buf.buffer) }`letisTriggered=falseconstsandbox={hello: function(resolve,param){isTriggered=trueconstu8=newUint8Array(param,0,param.byteLength)assert(u8.length===20)assert((u8[0]=1&&u8[1]===2))returntrue}};(async()=>{constres=awaitcreateScript(code).setUserCode(`helloFun("ruffVM")`).setSandbox(sandbox).setOption({cpuCount: 1,memSizeKB: 200}).runAsync()assert(isTriggered)assert(res===true)})()

Host return Resolved Promised value to VM

constassert=require('assert')constvm=require('ruffvm')functionbufferToArrayBuffer(b){returnb.buffer.slice(b.byteOffset,b.byteOffset+b.byteLength);}constcode=` function helloFun(parameterString) { var buf = new Uint8Array(20) buf[0] = 1 buf[1] = 2 return hello(buf.buffer) }`constsandbox={hello: function(vmResolve,name){returnnewPromise(function(resolve){letab1=bufferToArrayBuffer(Buffer.from('this is hostapi test'))constu8=newUint8Array(ab1,0,ab1.byteLength)setTimeout(()=>{vmResolve(u8)// send resolved value to VMresolve()},20)})}};(async()=>{constres=awaitcreateScript(code).setUserCode(`helloFun("ruffVM")`).setSandbox(sandbox).setOption({cpuCount: 1,memSizeKB: 200}).runAsync()constexpectBuffer=bufferToArrayBuffer(Buffer.from('this is hostapi test'))constexpectU8=newUint8Array(expectBuffer,0,expectBuffer.byteLength)constresU8=newUint8Array(res,0,res.byteLength)assert.deepStrictEqual(resU8,expectU8)})()

For more example please refer to test/basic.test.js

Function export to VM from Node.js

  • function hostApi(vmResolve, parmFromVM)
    • vmResolve: resolve handler to resolve Resolved Value on Node.js, just ignore this handler if the return value is not promise
    • paramFromVM: parameter specified from VM

Main usage

ruffchain use ruffvm as its smart contract execute engine, provide the ability for user develop their smart contract by JavaScript.

Difference from Node's vm

Following code will escape node vm sandbox and do exit on host

constvm=require('vm');vm.runInNewContext('this.constructor.constructor("return process")().exit()');console.log('Never gets executed.');

Difference from duktape.node

ruffvm-node support set limit on CPU and Memory comparing to duktape.node

To do list

  • Enable build on Linux
  • Add chain style API
  • Add SharedArrayBuffer support (ES2017)
  • Evaluate XS JavaScript Engine

Known improvements

Does not support multiple instance of vm run simultaneously. Communication between VM and Host is not optimized for heavily usage scenario.

About

RuffVM is a small embeddable VM provides security, isolate execution environment for run DApp.

Resources

Stars

21 stars

Watchers

7 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Build Status

RuffVM

RuffVM is a light-weight VM environment designed for DApps(Decentralized applications). It provides secure, isolated execution environment as well as resource control (e.g Memory and CPU) for Dapps. It lowers the barrier of Blockchain application development by significant amount via JavaScript based abstraction (But not limited to JS).

RuffVM's build-in,plug-in mechanism allows developers to customize DApp runtime depends on their need, these modules will be completely independent to a public chain base and will be compatible with any Blockchain platforms(e.g EOS,Ethereum,ruffchain).

RoadMap

Present

  • 0.1 Implementation on Node.js
  • 0.2 Build-in modules

In progress

  • Verification and optimization on ruffchain blockchain
  • Standerlize modules build-in, plug-in mechanism

Future release

  • Split out ruffvm-core into separate repo
  • Port to EOS
  • Port to Ethereum
  • DApp Module registry

RuffVM-Node

RuffVM integration for node.js, aim to provide usable, secure sandbox in order to run untrusted javascript code in nodejs, Resource control abilities supported in this version (e.g. cpu time and memory). RuffVM leverage jerryscript(a lightweight JavaScript engine) as javascript runtime, it is isolated with Node V8 engine naturally. Refer some idea from duktape.node.

Building manually and running tests

Currently enabled build on Macos & Linux with C++1y support

build

git clone --recurse-submodules https://github.com/ruffchain/RuffVM.git
cd RuffVM
npm install

build manually

node-gyp configure
node-gyp build

how to test

npm run test

data type supported between VM and Host by bridge

  • Undefined
  • Boolean
  • Number
  • String
  • ArrayBuffer

API

Class: Script

new Script(code)

  • code <string> code to compile and evaluate in VM
  • Returns: <Script>

script.setUserCode(userCode)

  • userCode <string> script to run in VM after code
  • Returns: <Script>

script.setOption(options)

  • options
    • cpuCount <number> cpu count to limit
    • memSizeKB <number> memory size in KB
  • Returns: <Script>

script.setSandbox(sandbox)

  • sandbox <Object> will be the global object in vm
  • Returns: <Script>

script.runAsync()

  • Returns: <Promise>
    • resolve return value from script
    • reject error status (boolean)

createScript(code)

  • code <string> code to compile and evaluate in VM
  • Returns: <Script>

Example

Host return no Promised value to VM

constassert=require('assert')const{ createScript }=require('ruffvm')constcode=` function helloFun(parameterString) { var buf = new Uint8Array(20) buf[0] = 1 buf[1] = 2 return hello(buf.buffer) }`letisTriggered=falseconstsandbox={hello: function(resolve,param){isTriggered=trueconstu8=newUint8Array(param,0,param.byteLength)assert(u8.length===20)assert((u8[0]=1&&u8[1]===2))returntrue}};(async()=>{constres=awaitcreateScript(code).setUserCode(`helloFun("ruffVM")`).setSandbox(sandbox).setOption({cpuCount: 1,memSizeKB: 200}).runAsync()assert(isTriggered)assert(res===true)})()

Host return Resolved Promised value to VM

constassert=require('assert')constvm=require('ruffvm')functionbufferToArrayBuffer(b){returnb.buffer.slice(b.byteOffset,b.byteOffset+b.byteLength);}constcode=` function helloFun(parameterString) { var buf = new Uint8Array(20) buf[0] = 1 buf[1] = 2 return hello(buf.buffer) }`constsandbox={hello: function(vmResolve,name){returnnewPromise(function(resolve){letab1=bufferToArrayBuffer(Buffer.from('this is hostapi test'))constu8=newUint8Array(ab1,0,ab1.byteLength)setTimeout(()=>{vmResolve(u8)// send resolved value to VMresolve()},20)})}};(async()=>{constres=awaitcreateScript(code).setUserCode(`helloFun("ruffVM")`).setSandbox(sandbox).setOption({cpuCount: 1,memSizeKB: 200}).runAsync()constexpectBuffer=bufferToArrayBuffer(Buffer.from('this is hostapi test'))constexpectU8=newUint8Array(expectBuffer,0,expectBuffer.byteLength)constresU8=newUint8Array(res,0,res.byteLength)assert.deepStrictEqual(resU8,expectU8)})()

For more example please refer to test/basic.test.js

Function export to VM from Node.js

  • function hostApi(vmResolve, parmFromVM)
    • vmResolve: resolve handler to resolve Resolved Value on Node.js, just ignore this handler if the return value is not promise
    • paramFromVM: parameter specified from VM

Main usage

ruffchain use ruffvm as its smart contract execute engine, provide the ability for user develop their smart contract by JavaScript.

Difference from Node's vm

Following code will escape node vm sandbox and do exit on host

constvm=require('vm');vm.runInNewContext('this.constructor.constructor("return process")().exit()');console.log('Never gets executed.');

Difference from duktape.node

ruffvm-node support set limit on CPU and Memory comparing to duktape.node

To do list

  • Enable build on Linux
  • Add chain style API
  • Add SharedArrayBuffer support (ES2017)
  • Evaluate XS JavaScript Engine

Known improvements

Does not support multiple instance of vm run simultaneously. Communication between VM and Host is not optimized for heavily usage scenario.

About

RuffVM is a small embeddable VM provides security, isolate execution environment for run DApp.

Resources

Stars

21 stars

Watchers

7 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Repository files navigation

Build Status

RuffVM

RuffVM is a light-weight VM environment designed for DApps(Decentralized applications). It provides secure, isolated execution environment as well as resource control (e.g Memory and CPU) for Dapps. It lowers the barrier of Blockchain application development by significant amount via JavaScript based abstraction (But not limited to JS).

RuffVM's build-in,plug-in mechanism allows developers to customize DApp runtime depends on their need, these modules will be completely independent to a public chain base and will be compatible with any Blockchain platforms(e.g EOS,Ethereum,ruffchain).

RoadMap

Present

  • 0.1 Implementation on Node.js
  • 0.2 Build-in modules

In progress

  • Verification and optimization on ruffchain blockchain
  • Standerlize modules build-in, plug-in mechanism

Future release

  • Split out ruffvm-core into separate repo
  • Port to EOS
  • Port to Ethereum
  • DApp Module registry

RuffVM-Node

RuffVM integration for node.js, aim to provide usable, secure sandbox in order to run untrusted javascript code in nodejs, Resource control abilities supported in this version (e.g. cpu time and memory). RuffVM leverage jerryscript(a lightweight JavaScript engine) as javascript runtime, it is isolated with Node V8 engine naturally. Refer some idea from duktape.node.

Building manually and running tests

Currently enabled build on Macos & Linux with C++1y support

build

git clone --recurse-submodules https://github.com/ruffchain/RuffVM.git
cd RuffVM
npm install

build manually

node-gyp configure
node-gyp build

how to test

npm run test

data type supported between VM and Host by bridge

  • Undefined
  • Boolean
  • Number
  • String
  • ArrayBuffer

API

Class: Script

new Script(code)

  • code <string> code to compile and evaluate in VM
  • Returns: <Script>

script.setUserCode(userCode)

  • userCode <string> script to run in VM after code
  • Returns: <Script>

script.setOption(options)

  • options
    • cpuCount <number> cpu count to limit
    • memSizeKB <number> memory size in KB
  • Returns: <Script>

script.setSandbox(sandbox)

  • sandbox <Object> will be the global object in vm
  • Returns: <Script>

script.runAsync()

  • Returns: <Promise>
    • resolve return value from script
    • reject error status (boolean)

createScript(code)

  • code <string> code to compile and evaluate in VM
  • Returns: <Script>

Example

Host return no Promised value to VM

constassert=require('assert')const{ createScript }=require('ruffvm')constcode=` function helloFun(parameterString) { var buf = new Uint8Array(20) buf[0] = 1 buf[1] = 2 return hello(buf.buffer) }`letisTriggered=falseconstsandbox={hello: function(resolve,param){isTriggered=trueconstu8=newUint8Array(param,0,param.byteLength)assert(u8.length===20)assert((u8[0]=1&&u8[1]===2))returntrue}};(async()=>{constres=awaitcreateScript(code).setUserCode(`helloFun("ruffVM")`).setSandbox(sandbox).setOption({cpuCount: 1,memSizeKB: 200}).runAsync()assert(isTriggered)assert(res===true)})()

Host return Resolved Promised value to VM

constassert=require('assert')constvm=require('ruffvm')functionbufferToArrayBuffer(b){returnb.buffer.slice(b.byteOffset,b.byteOffset+b.byteLength);}constcode=` function helloFun(parameterString) { var buf = new Uint8Array(20) buf[0] = 1 buf[1] = 2 return hello(buf.buffer) }`constsandbox={hello: function(vmResolve,name){returnnewPromise(function(resolve){letab1=bufferToArrayBuffer(Buffer.from('this is hostapi test'))constu8=newUint8Array(ab1,0,ab1.byteLength)setTimeout(()=>{vmResolve(u8)// send resolved value to VMresolve()},20)})}};(async()=>{constres=awaitcreateScript(code).setUserCode(`helloFun("ruffVM")`).setSandbox(sandbox).setOption({cpuCount: 1,memSizeKB: 200}).runAsync()constexpectBuffer=bufferToArrayBuffer(Buffer.from('this is hostapi test'))constexpectU8=newUint8Array(expectBuffer,0,expectBuffer.byteLength)constresU8=newUint8Array(res,0,res.byteLength)assert.deepStrictEqual(resU8,expectU8)})()

For more example please refer to test/basic.test.js

Function export to VM from Node.js

  • function hostApi(vmResolve, parmFromVM)
    • vmResolve: resolve handler to resolve Resolved Value on Node.js, just ignore this handler if the return value is not promise
    • paramFromVM: parameter specified from VM

Main usage

ruffchain use ruffvm as its smart contract execute engine, provide the ability for user develop their smart contract by JavaScript.

Difference from Node's vm

Following code will escape node vm sandbox and do exit on host

constvm=require('vm');vm.runInNewContext('this.constructor.constructor("return process")().exit()');console.log('Never gets executed.');

Difference from duktape.node

ruffvm-node support set limit on CPU and Memory comparing to duktape.node

To do list

  • Enable build on Linux
  • Add chain style API
  • Add SharedArrayBuffer support (ES2017)
  • Evaluate XS JavaScript Engine

Known improvements

Does not support multiple instance of vm run simultaneously. Communication between VM and Host is not optimized for heavily usage scenario.

About

RuffVM is a small embeddable VM provides security, isolate execution environment for run DApp.

Resources

Stars

21 stars

Watchers

7 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Build Status

RuffVM

RuffVM is a light-weight VM environment designed for DApps(Decentralized applications). It provides secure, isolated execution environment as well as resource control (e.g Memory and CPU) for Dapps. It lowers the barrier of Blockchain application development by significant amount via JavaScript based abstraction (But not limited to JS).

RuffVM's build-in,plug-in mechanism allows developers to customize DApp runtime depends on their need, these modules will be completely independent to a public chain base and will be compatible with any Blockchain platforms(e.g EOS,Ethereum,ruffchain).

RoadMap

Present

  • 0.1 Implementation on Node.js
  • 0.2 Build-in modules

In progress

  • Verification and optimization on ruffchain blockchain
  • Standerlize modules build-in, plug-in mechanism

Future release

  • Split out ruffvm-core into separate repo
  • Port to EOS
  • Port to Ethereum
  • DApp Module registry

RuffVM-Node

RuffVM integration for node.js, aim to provide usable, secure sandbox in order to run untrusted javascript code in nodejs, Resource control abilities supported in this version (e.g. cpu time and memory). RuffVM leverage jerryscript(a lightweight JavaScript engine) as javascript runtime, it is isolated with Node V8 engine naturally. Refer some idea from duktape.node.

Building manually and running tests

Currently enabled build on Macos & Linux with C++1y support

build

git clone --recurse-submodules https://github.com/ruffchain/RuffVM.git
cd RuffVM
npm install

build manually

node-gyp configure
node-gyp build

how to test

npm run test

data type supported between VM and Host by bridge

  • Undefined
  • Boolean
  • Number
  • String
  • ArrayBuffer

API

Class: Script

new Script(code)

  • code <string> code to compile and evaluate in VM
  • Returns: <Script>

script.setUserCode(userCode)

  • userCode <string> script to run in VM after code
  • Returns: <Script>

script.setOption(options)

  • options
    • cpuCount <number> cpu count to limit
    • memSizeKB <number> memory size in KB
  • Returns: <Script>

script.setSandbox(sandbox)

  • sandbox <Object> will be the global object in vm
  • Returns: <Script>

script.runAsync()

  • Returns: <Promise>
    • resolve return value from script
    • reject error status (boolean)

createScript(code)

  • code <string> code to compile and evaluate in VM
  • Returns: <Script>

Example

Host return no Promised value to VM

constassert=require('assert')const{ createScript }=require('ruffvm')constcode=` function helloFun(parameterString) { var buf = new Uint8Array(20) buf[0] = 1 buf[1] = 2 return hello(buf.buffer) }`letisTriggered=falseconstsandbox={hello: function(resolve,param){isTriggered=trueconstu8=newUint8Array(param,0,param.byteLength)assert(u8.length===20)assert((u8[0]=1&&u8[1]===2))returntrue}};(async()=>{constres=awaitcreateScript(code).setUserCode(`helloFun("ruffVM")`).setSandbox(sandbox).setOption({cpuCount: 1,memSizeKB: 200}).runAsync()assert(isTriggered)assert(res===true)})()

Host return Resolved Promised value to VM

constassert=require('assert')constvm=require('ruffvm')functionbufferToArrayBuffer(b){returnb.buffer.slice(b.byteOffset,b.byteOffset+b.byteLength);}constcode=` function helloFun(parameterString) { var buf = new Uint8Array(20) buf[0] = 1 buf[1] = 2 return hello(buf.buffer) }`constsandbox={hello: function(vmResolve,name){returnnewPromise(function(resolve){letab1=bufferToArrayBuffer(Buffer.from('this is hostapi test'))constu8=newUint8Array(ab1,0,ab1.byteLength)setTimeout(()=>{vmResolve(u8)// send resolved value to VMresolve()},20)})}};(async()=>{constres=awaitcreateScript(code).setUserCode(`helloFun("ruffVM")`).setSandbox(sandbox).setOption({cpuCount: 1,memSizeKB: 200}).runAsync()constexpectBuffer=bufferToArrayBuffer(Buffer.from('this is hostapi test'))constexpectU8=newUint8Array(expectBuffer,0,expectBuffer.byteLength)constresU8=newUint8Array(res,0,res.byteLength)assert.deepStrictEqual(resU8,expectU8)})()

For more example please refer to test/basic.test.js

Function export to VM from Node.js

  • function hostApi(vmResolve, parmFromVM)
    • vmResolve: resolve handler to resolve Resolved Value on Node.js, just ignore this handler if the return value is not promise
    • paramFromVM: parameter specified from VM

Main usage

ruffchain use ruffvm as its smart contract execute engine, provide the ability for user develop their smart contract by JavaScript.

Difference from Node's vm

Following code will escape node vm sandbox and do exit on host

constvm=require('vm');vm.runInNewContext('this.constructor.constructor("return process")().exit()');console.log('Never gets executed.');

Difference from duktape.node

ruffvm-node support set limit on CPU and Memory comparing to duktape.node

To do list

  • Enable build on Linux
  • Add chain style API
  • Add SharedArrayBuffer support (ES2017)
  • Evaluate XS JavaScript Engine

Known improvements

Does not support multiple instance of vm run simultaneously. Communication between VM and Host is not optimized for heavily usage scenario.

About

RuffVM is a small embeddable VM provides security, isolate execution environment for run DApp.

Resources

Stars

21 stars

Watchers

7 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Build Status

RuffVM

RuffVM is a light-weight VM environment designed for DApps(Decentralized applications). It provides secure, isolated execution environment as well as resource control (e.g Memory and CPU) for Dapps. It lowers the barrier of Blockchain application development by significant amount via JavaScript based abstraction (But not limited to JS).

RuffVM's build-in,plug-in mechanism allows developers to customize DApp runtime depends on their need, these modules will be completely independent to a public chain base and will be compatible with any Blockchain platforms(e.g EOS,Ethereum,ruffchain).

RoadMap

Present

  • 0.1 Implementation on Node.js
  • 0.2 Build-in modules

In progress

  • Verification and optimization on ruffchain blockchain
  • Standerlize modules build-in, plug-in mechanism

Future release

  • Split out ruffvm-core into separate repo
  • Port to EOS
  • Port to Ethereum
  • DApp Module registry

RuffVM-Node

RuffVM integration for node.js, aim to provide usable, secure sandbox in order to run untrusted javascript code in nodejs, Resource control abilities supported in this version (e.g. cpu time and memory). RuffVM leverage jerryscript(a lightweight JavaScript engine) as javascript runtime, it is isolated with Node V8 engine naturally. Refer some idea from duktape.node.

Building manually and running tests

Currently enabled build on Macos & Linux with C++1y support

build

git clone --recurse-submodules https://github.com/ruffchain/RuffVM.git
cd RuffVM
npm install

build manually

node-gyp configure
node-gyp build

how to test

npm run test

data type supported between VM and Host by bridge

  • Undefined
  • Boolean
  • Number
  • String
  • ArrayBuffer

API

Class: Script

new Script(code)

  • code <string> code to compile and evaluate in VM
  • Returns: <Script>

script.setUserCode(userCode)

  • userCode <string> script to run in VM after code
  • Returns: <Script>

script.setOption(options)

  • options
    • cpuCount <number> cpu count to limit
    • memSizeKB <number> memory size in KB
  • Returns: <Script>

script.setSandbox(sandbox)

  • sandbox <Object> will be the global object in vm
  • Returns: <Script>

script.runAsync()

  • Returns: <Promise>
    • resolve return value from script
    • reject error status (boolean)

createScript(code)

  • code <string> code to compile and evaluate in VM
  • Returns: <Script>

Example

Host return no Promised value to VM

constassert=require('assert')const{ createScript }=require('ruffvm')constcode=` function helloFun(parameterString) { var buf = new Uint8Array(20) buf[0] = 1 buf[1] = 2 return hello(buf.buffer) }`letisTriggered=falseconstsandbox={hello: function(resolve,param){isTriggered=trueconstu8=newUint8Array(param,0,param.byteLength)assert(u8.length===20)assert((u8[0]=1&&u8[1]===2))returntrue}};(async()=>{constres=awaitcreateScript(code).setUserCode(`helloFun("ruffVM")`).setSandbox(sandbox).setOption({cpuCount: 1,memSizeKB: 200}).runAsync()assert(isTriggered)assert(res===true)})()

Host return Resolved Promised value to VM

constassert=require('assert')constvm=require('ruffvm')functionbufferToArrayBuffer(b){returnb.buffer.slice(b.byteOffset,b.byteOffset+b.byteLength);}constcode=` function helloFun(parameterString) { var buf = new Uint8Array(20) buf[0] = 1 buf[1] = 2 return hello(buf.buffer) }`constsandbox={hello: function(vmResolve,name){returnnewPromise(function(resolve){letab1=bufferToArrayBuffer(Buffer.from('this is hostapi test'))constu8=newUint8Array(ab1,0,ab1.byteLength)setTimeout(()=>{vmResolve(u8)// send resolved value to VMresolve()},20)})}};(async()=>{constres=awaitcreateScript(code).setUserCode(`helloFun("ruffVM")`).setSandbox(sandbox).setOption({cpuCount: 1,memSizeKB: 200}).runAsync()constexpectBuffer=bufferToArrayBuffer(Buffer.from('this is hostapi test'))constexpectU8=newUint8Array(expectBuffer,0,expectBuffer.byteLength)constresU8=newUint8Array(res,0,res.byteLength)assert.deepStrictEqual(resU8,expectU8)})()

For more example please refer to test/basic.test.js

Function export to VM from Node.js

  • function hostApi(vmResolve, parmFromVM)
    • vmResolve: resolve handler to resolve Resolved Value on Node.js, just ignore this handler if the return value is not promise
    • paramFromVM: parameter specified from VM

Main usage

ruffchain use ruffvm as its smart contract execute engine, provide the ability for user develop their smart contract by JavaScript.

Difference from Node's vm

Following code will escape node vm sandbox and do exit on host

constvm=require('vm');vm.runInNewContext('this.constructor.constructor("return process")().exit()');console.log('Never gets executed.');

Difference from duktape.node

ruffvm-node support set limit on CPU and Memory comparing to duktape.node

To do list

  • Enable build on Linux
  • Add chain style API
  • Add SharedArrayBuffer support (ES2017)
  • Evaluate XS JavaScript Engine

Known improvements

Does not support multiple instance of vm run simultaneously. Communication between VM and Host is not optimized for heavily usage scenario.

About

RuffVM is a small embeddable VM provides security, isolate execution environment for run DApp.

Resources

Stars

21 stars

Watchers

7 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Repository files navigation

Build Status

RuffVM

RuffVM is a light-weight VM environment designed for DApps(Decentralized applications). It provides secure, isolated execution environment as well as resource control (e.g Memory and CPU) for Dapps. It lowers the barrier of Blockchain application development by significant amount via JavaScript based abstraction (But not limited to JS).

RuffVM's build-in,plug-in mechanism allows developers to customize DApp runtime depends on their need, these modules will be completely independent to a public chain base and will be compatible with any Blockchain platforms(e.g EOS,Ethereum,ruffchain).

RoadMap

Present

  • 0.1 Implementation on Node.js
  • 0.2 Build-in modules

In progress

  • Verification and optimization on ruffchain blockchain
  • Standerlize modules build-in, plug-in mechanism

Future release

  • Split out ruffvm-core into separate repo
  • Port to EOS
  • Port to Ethereum
  • DApp Module registry

RuffVM-Node

RuffVM integration for node.js, aim to provide usable, secure sandbox in order to run untrusted javascript code in nodejs, Resource control abilities supported in this version (e.g. cpu time and memory). RuffVM leverage jerryscript(a lightweight JavaScript engine) as javascript runtime, it is isolated with Node V8 engine naturally. Refer some idea from duktape.node.

Building manually and running tests

Currently enabled build on Macos & Linux with C++1y support

build

git clone --recurse-submodules https://github.com/ruffchain/RuffVM.git
cd RuffVM
npm install

build manually

node-gyp configure
node-gyp build

how to test

npm run test

data type supported between VM and Host by bridge

  • Undefined
  • Boolean
  • Number
  • String
  • ArrayBuffer

API

Class: Script

new Script(code)

  • code <string> code to compile and evaluate in VM
  • Returns: <Script>

script.setUserCode(userCode)

  • userCode <string> script to run in VM after code
  • Returns: <Script>

script.setOption(options)

  • options
    • cpuCount <number> cpu count to limit
    • memSizeKB <number> memory size in KB
  • Returns: <Script>

script.setSandbox(sandbox)

  • sandbox <Object> will be the global object in vm
  • Returns: <Script>

script.runAsync()

  • Returns: <Promise>
    • resolve return value from script
    • reject error status (boolean)

createScript(code)

  • code <string> code to compile and evaluate in VM
  • Returns: <Script>

Example

Host return no Promised value to VM

constassert=require('assert')const{ createScript }=require('ruffvm')constcode=` function helloFun(parameterString) { var buf = new Uint8Array(20) buf[0] = 1 buf[1] = 2 return hello(buf.buffer) }`letisTriggered=falseconstsandbox={hello: function(resolve,param){isTriggered=trueconstu8=newUint8Array(param,0,param.byteLength)assert(u8.length===20)assert((u8[0]=1&&u8[1]===2))returntrue}};(async()=>{constres=awaitcreateScript(code).setUserCode(`helloFun("ruffVM")`).setSandbox(sandbox).setOption({cpuCount: 1,memSizeKB: 200}).runAsync()assert(isTriggered)assert(res===true)})()

Host return Resolved Promised value to VM

constassert=require('assert')constvm=require('ruffvm')functionbufferToArrayBuffer(b){returnb.buffer.slice(b.byteOffset,b.byteOffset+b.byteLength);}constcode=` function helloFun(parameterString) { var buf = new Uint8Array(20) buf[0] = 1 buf[1] = 2 return hello(buf.buffer) }`constsandbox={hello: function(vmResolve,name){returnnewPromise(function(resolve){letab1=bufferToArrayBuffer(Buffer.from('this is hostapi test'))constu8=newUint8Array(ab1,0,ab1.byteLength)setTimeout(()=>{vmResolve(u8)// send resolved value to VMresolve()},20)})}};(async()=>{constres=awaitcreateScript(code).setUserCode(`helloFun("ruffVM")`).setSandbox(sandbox).setOption({cpuCount: 1,memSizeKB: 200}).runAsync()constexpectBuffer=bufferToArrayBuffer(Buffer.from('this is hostapi test'))constexpectU8=newUint8Array(expectBuffer,0,expectBuffer.byteLength)constresU8=newUint8Array(res,0,res.byteLength)assert.deepStrictEqual(resU8,expectU8)})()

For more example please refer to test/basic.test.js

Function export to VM from Node.js

  • function hostApi(vmResolve, parmFromVM)
    • vmResolve: resolve handler to resolve Resolved Value on Node.js, just ignore this handler if the return value is not promise
    • paramFromVM: parameter specified from VM

Main usage

ruffchain use ruffvm as its smart contract execute engine, provide the ability for user develop their smart contract by JavaScript.

Difference from Node's vm

Following code will escape node vm sandbox and do exit on host

constvm=require('vm');vm.runInNewContext('this.constructor.constructor("return process")().exit()');console.log('Never gets executed.');

Difference from duktape.node

ruffvm-node support set limit on CPU and Memory comparing to duktape.node

To do list

  • Enable build on Linux
  • Add chain style API
  • Add SharedArrayBuffer support (ES2017)
  • Evaluate XS JavaScript Engine

Known improvements

Does not support multiple instance of vm run simultaneously. Communication between VM and Host is not optimized for heavily usage scenario.

About

RuffVM is a small embeddable VM provides security, isolate execution environment for run DApp.

Resources

Stars

21 stars

Watchers

7 watching

Forks

Releases

Packages

Used by

Contributors

Languages