我有一个nodejs服务器接收请求。进入此服务的数据是交易对象,如下所示。
{ "_id": "5c2f3e4c5f627d785086d0f7", "action_time": 1546600012970, "amount": -0.164, "asset": "SKK", "complete_time": 1546600012970, "confirm_rate": 100, "desc": "15901 nolu işlem ücreti", "fee": "", "fee_asset": "", "group": 15901, "hash": "cd2105320da97800a9d65aa90f55e755d16e9bb48f4f831a15b1ff5f95b902e2", "nonce": "", "prev_hash": "7f35b213e044109d676788043763e2cb48c35d1da887d4624813410090474d82", "seq": 15903, "status": 1, "subtype": 3, "to": "SKK19FiKEtunucWqLjNXtnDH479mzkRrD1DEr", "type": 1, "wallet": "SKK1PVTXzG15vwQX9U6c4si8iVsFRgkV2RAAg", "isSmartCOntract": 1, "smartContractId": 123456 }
如果此对象的smart_contract_id字段已满,这是一个智能合约过程。并且从数据库中以JavaScript脚本的形式读取此id智能合约信息。这个javascript文件包含各种功能。这个javascript文件必须由服务器运行并返回。每个智能合约都有不同的内容。我认为使用nodejs vm2 sandbox处理此任务是正确的。
但是对于服务器来说,直接从该数据库运行脚本将是一种糟糕的体验。我认为使用javascript中的继承来满足此要求会更准确。
我编写的代码和收到的错误如下所示。
main.js(超类)
var fs = require('fs')
const { NodeVM } = require('vm2');
class Animal {
constructor(name) {
this.speed = 0;
this.name = name;
}
run(speed) {
this.speed += speed;
console.log(`${this.name} runs with speed ${this.speed}.`);
}
stop() {
this.speed = 0;
console.log(`${this.name} stopped.`);
}
}
let tx = { "_id": "5c2f3e4c5f627d785086d0f7", "action_time": 1546600012970, "amount": -0.164, "asset": "SKK", "complete_time": 1546600012970, "confirm_rate": 100, "desc": "15901 nolu işlem ücreti", "fee": "", "fee_asset": "", "group": 15901, "hash": "cd2105320da97800a9d65aa90f55e755d16e9bb48f4f831a15b1ff5f95b902e2", "nonce": "", "prev_hash": "7f35b213e044109d676788043763e2cb48c35d1da887d4624813410090474d82", "seq": 15903, "status": 1, "subtype": 3, "to": "SKK19FiKEtunucWqLjNXtnDH479mzkRrD1DEr", "type": 1, "wallet": "SKK1PVTXzG15vwQX9U6c4si8iVsFRgkV2RAAg", "isSmartCOntract": 1, "smartContractId": 123456 };
if (tx.isSmartContract) {
}
const sandbox = {
object: Animal.prototype,
tx: tx
}
const vm = new NodeVM({
console: 'inherit',
sandbox: { tx, Animal },
require: {
external: true,
builtin: ['*'],
root: "./",
mock: {
}
}
});
/*
var scriptContent = fs.readFileSync('./sampleOne.js');
vm.run(scriptContent, 'sampleOne.js');
*/
vm.run(`
class Rabbit extends Animal {
constructor(name) {
super(name);
}
hide() {
console.log('${this.name} hides!');
}
stop() {
super.stop(); // call parent stop
this.hide(); // and then hide
}
}
let rabbit = new Rabbit("White Rabbit");
rabbit.run(5); // White Rabbit runs with speed 5.
rabbit.stop(); // White Rabbit stopped. White rabbit hides!
`, 'vm.js');
我遇到错误:
C:\nodejs\node-smart-contract\node_modules\vm2\lib\main.js:430
throw this._internal.Decontextify.value(e);
^
TypeError: 'get' on proxy: property 'prototype' is a read-only and non-configurable data property on the proxy target but the proxy did not return its actual value (expected '[object Object]' but got '[object Object]')
at Object.<anonymous> (C:\nodejs\node-smart-contract\vm.js:3:22)
at NodeVM.run (C:\nodejs\node-smart-contract\node_modules\vm2\lib\main.js:428:23)
at Object.<anonymous> (C:\nodejs\node-smart-contract\main.js:47:4)
at Module._compile (internal/modules/cjs/loader.js:688:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:699:10)
at Module.load (internal/modules/cjs/loader.js:598:32)
at tryModuleLoad (internal/modules/cjs/loader.js:537:12)
at Function.Module._load (internal/modules/cjs/loader.js:529:3)
at Function.Module.runMain (internal/modules/cjs/loader.js:741:12)
at startup (internal/bootstrap/node.js:285:19)
[nodemon] app crashed - waiting for file changes before starting...
如何处理此任务?