|
|
|
@ -1,6 +1,7 @@ |
|
|
|
|
/* global */ |
|
|
|
|
'use strict' |
|
|
|
|
|
|
|
|
|
var async = require('async') |
|
|
|
|
var ethJSUtil = require('ethereumjs-util') |
|
|
|
|
var BN = ethJSUtil.BN |
|
|
|
|
var remixLib = require('remix-lib') |
|
|
|
@ -201,99 +202,66 @@ UniversalDApp.prototype.getInputs = function (funABI) { |
|
|
|
|
return txHelper.inputParametersDeclarationToString(funABI.inputs) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
function execute (pipeline, env, callback) { |
|
|
|
|
function next (err, env) { |
|
|
|
|
if (err) return callback(err) |
|
|
|
|
var step = pipeline.shift() |
|
|
|
|
if (step) step(env, next) |
|
|
|
|
else callback(null, env.result) |
|
|
|
|
} |
|
|
|
|
next(null, env) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
UniversalDApp.prototype.runTx = function (args, cb) { |
|
|
|
|
var self = this |
|
|
|
|
var tx = { to: args.to, data: args.data.dataHex, useCall: args.useCall, from: args.from, value: args.value } |
|
|
|
|
var payLoad = { funAbi: args.data.funAbi, funArgs: args.data.funArgs, contractBytecode: args.data.contractBytecode, contractName: args.data.contractName } // contains decoded parameters
|
|
|
|
|
var pipeline = [queryGasLimit] |
|
|
|
|
if (!args.value) { |
|
|
|
|
pipeline.push(queryValue) |
|
|
|
|
} |
|
|
|
|
if (!args.from) { |
|
|
|
|
pipeline.push(queryAddress) |
|
|
|
|
} |
|
|
|
|
pipeline.push(runTransaction) |
|
|
|
|
var env = { self, tx, payLoad } |
|
|
|
|
execute(pipeline, env, cb) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
function queryGasLimit (env, next) { |
|
|
|
|
var { self, tx } = env |
|
|
|
|
tx.gasLimit = 3000000 |
|
|
|
|
if (self.transactionContextAPI.getGasLimit) { |
|
|
|
|
self.transactionContextAPI.getGasLimit(function (err, ret) { |
|
|
|
|
if (err) return next(err) |
|
|
|
|
tx.gasLimit = ret |
|
|
|
|
next(null, env) |
|
|
|
|
}) |
|
|
|
|
} else next(null, env) |
|
|
|
|
} |
|
|
|
|
const self = this |
|
|
|
|
async.waterfall([ |
|
|
|
|
function getGasLimit (next) { |
|
|
|
|
if (self.transactionContextAPI.getGasLimit) { |
|
|
|
|
return self.transactionContextAPI.getGasLimit(next) |
|
|
|
|
} |
|
|
|
|
next(null, 3000000) |
|
|
|
|
}, |
|
|
|
|
function queryValue (gasLimit, next) { |
|
|
|
|
if (args.value) { |
|
|
|
|
return next(null, args.value, gasLimit) |
|
|
|
|
} |
|
|
|
|
if (args.useCall || !self.transactionContextAPI.getValue) { |
|
|
|
|
return next(null, 0, gasLimit) |
|
|
|
|
} |
|
|
|
|
self.transactionContextAPI.getValue(function (err, value) { |
|
|
|
|
next(err, value, gasLimit) |
|
|
|
|
}) |
|
|
|
|
}, |
|
|
|
|
function getAccount (value, gasLimit, next) { |
|
|
|
|
if (args.from) { |
|
|
|
|
return next(null, args.from, value, gasLimit) |
|
|
|
|
} |
|
|
|
|
if (self.transactionContextAPI.getAddress) { |
|
|
|
|
return self.transactionContextAPI.getAddress(function (err, address) { |
|
|
|
|
next(err, address, value, gasLimit) |
|
|
|
|
}) |
|
|
|
|
} |
|
|
|
|
self.getAccounts(function (err, accounts) { |
|
|
|
|
let address = accounts[0] |
|
|
|
|
|
|
|
|
|
function queryValue (env, next) { |
|
|
|
|
var { self, tx } = env |
|
|
|
|
tx.value = 0 |
|
|
|
|
if (tx.useCall) return next(null, env) |
|
|
|
|
if (self.transactionContextAPI.getValue) { |
|
|
|
|
self.transactionContextAPI.getValue(function (err, ret) { |
|
|
|
|
if (err) return next(err) |
|
|
|
|
tx.value = ret |
|
|
|
|
next(null, env) |
|
|
|
|
}) |
|
|
|
|
} else next(null, env) |
|
|
|
|
} |
|
|
|
|
if (err) return next(err) |
|
|
|
|
if (!address) return next('No accounts available') |
|
|
|
|
if (executionContext.isVM() && !self.accounts[address]) { |
|
|
|
|
return next('Invalid account selected') |
|
|
|
|
} |
|
|
|
|
next(null, address, value, gasLimit) |
|
|
|
|
}) |
|
|
|
|
}, |
|
|
|
|
function runTransaction (fromAddress, value, gasLimit, next) { |
|
|
|
|
var tx = { to: args.to, data: args.data.dataHex, useCall: args.useCall, from: fromAddress, value: value, gasLimit: gasLimit } |
|
|
|
|
var payLoad = { funAbi: args.data.funAbi, funArgs: args.data.funArgs, contractBytecode: args.data.contractBytecode, contractName: args.data.contractName } |
|
|
|
|
var timestamp = Date.now() |
|
|
|
|
|
|
|
|
|
function queryAddress (env, next) { |
|
|
|
|
var { self, tx } = env |
|
|
|
|
if (self.transactionContextAPI.getAddress) { |
|
|
|
|
self.transactionContextAPI.getAddress(function (err, ret) { |
|
|
|
|
if (err) return next(err) |
|
|
|
|
tx.from = ret |
|
|
|
|
next(null, env) |
|
|
|
|
}) |
|
|
|
|
} else { |
|
|
|
|
self.getAccounts(function (err, ret) { |
|
|
|
|
if (err) return next(err) |
|
|
|
|
if (ret.length === 0) return next('No accounts available') |
|
|
|
|
if (executionContext.isVM() && !self.accounts[ret[0]]) { |
|
|
|
|
return next('Invalid account selected') |
|
|
|
|
} |
|
|
|
|
tx.from = ret[0] |
|
|
|
|
next(null, env) |
|
|
|
|
}) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
self.event.trigger('initiatingTransaction', [timestamp, tx, payLoad]) |
|
|
|
|
self.txRunner.rawRun(tx, function (error, result) { |
|
|
|
|
let eventName = (tx.useCall ? 'callExecuted' : 'transactionExecuted') |
|
|
|
|
self.event.trigger(eventName, [error, tx.from, tx.to, tx.data, tx.useCall, result, timestamp, payLoad]) |
|
|
|
|
|
|
|
|
|
function runTransaction (env, next) { |
|
|
|
|
var { self, tx, payLoad } = env |
|
|
|
|
var timestamp = Date.now() |
|
|
|
|
self.event.trigger('initiatingTransaction', [timestamp, tx, payLoad]) |
|
|
|
|
self.txRunner.rawRun(tx, function (error, result) { |
|
|
|
|
if (!tx.useCall) { |
|
|
|
|
self.event.trigger('transactionExecuted', [error, tx.from, tx.to, tx.data, false, result, timestamp, payLoad]) |
|
|
|
|
} else { |
|
|
|
|
self.event.trigger('callExecuted', [error, tx.from, tx.to, tx.data, true, result, timestamp, payLoad]) |
|
|
|
|
} |
|
|
|
|
if (error) { |
|
|
|
|
if (typeof (error) !== 'string') { |
|
|
|
|
if (error.message) error = error.message |
|
|
|
|
else { |
|
|
|
|
try { error = 'error: ' + JSON.stringify(error) } catch (e) {} |
|
|
|
|
if (error && (typeof (error) !== 'string')) { |
|
|
|
|
if (error.message) error = error.message |
|
|
|
|
else { |
|
|
|
|
try { error = 'error: ' + JSON.stringify(error) } catch (e) {} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
next(error, result) |
|
|
|
|
}) |
|
|
|
|
} |
|
|
|
|
env.result = result |
|
|
|
|
next(error, env) |
|
|
|
|
}) |
|
|
|
|
], cb) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
module.exports = UniversalDApp |
|
|
|
|