You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
104 lines
4.9 KiB
104 lines
4.9 KiB
'use strict'
|
|
var ethers = require('ethers')
|
|
|
|
module.exports = {
|
|
/**
|
|
* deploy the given contract
|
|
*
|
|
* @param {String} from - sender address
|
|
* @param {String} data - data to send with the transaction ( return of txFormat.buildData(...) ).
|
|
* @param {String} value - decimal representation of value.
|
|
* @param {String} gasLimit - decimal representation of gas limit.
|
|
* @param {Object} txRunner - TxRunner.js instance
|
|
* @param {Object} callbacks - { confirmationCb, gasEstimationForceSend, promptCb }
|
|
* [validate transaction] confirmationCb (network, tx, gasEstimation, continueTxExecution, cancelCb)
|
|
* [transaction failed, force send] gasEstimationForceSend (error, continueTxExecution, cancelCb)
|
|
* [personal mode enabled, need password to continue] promptCb (okCb, cancelCb)
|
|
* @param {Function} finalCallback - last callback.
|
|
*/
|
|
createContract: function (from, data, value, gasLimit, txRunner, callbacks, finalCallback) {
|
|
if (!callbacks.confirmationCb || !callbacks.gasEstimationForceSend || !callbacks.promptCb) {
|
|
return finalCallback('all the callbacks must have been defined')
|
|
}
|
|
var tx = { from: from, to: null, data: data, useCall: false, value: value, gasLimit: gasLimit }
|
|
txRunner.rawRun(tx, callbacks.confirmationCb, callbacks.gasEstimationForceSend, callbacks.promptCb, (error, txResult) => {
|
|
// see universaldapp.js line 660 => 700 to check possible values of txResult (error case)
|
|
finalCallback(error, txResult)
|
|
})
|
|
},
|
|
|
|
/**
|
|
* call the current given contract ! that will create a transaction !
|
|
*
|
|
* @param {String} from - sender address
|
|
* @param {String} to - recipient address
|
|
* @param {String} data - data to send with the transaction ( return of txFormat.buildData(...) ).
|
|
* @param {String} value - decimal representation of value.
|
|
* @param {String} gasLimit - decimal representation of gas limit.
|
|
* @param {Object} txRunner - TxRunner.js instance
|
|
* @param {Object} callbacks - { confirmationCb, gasEstimationForceSend, promptCb }
|
|
* [validate transaction] confirmationCb (network, tx, gasEstimation, continueTxExecution, cancelCb)
|
|
* [transaction failed, force send] gasEstimationForceSend (error, continueTxExecution, cancelCb)
|
|
* [personal mode enabled, need password to continue] promptCb (okCb, cancelCb)
|
|
* @param {Function} finalCallback - last callback.
|
|
*/
|
|
callFunction: function (from, to, data, value, gasLimit, funAbi, txRunner, callbacks, finalCallback) {
|
|
var tx = { from: from, to: to, data: data, useCall: false, value: value, gasLimit: gasLimit }
|
|
txRunner.rawRun(tx, callbacks.confirmationCb, callbacks.gasEstimationForceSend, callbacks.promptCb, (error, txResult) => {
|
|
// see universaldapp.js line 660 => 700 to check possible values of txResult (error case)
|
|
finalCallback(error, txResult)
|
|
})
|
|
},
|
|
|
|
/**
|
|
* check if the vm has errored
|
|
*
|
|
* @param {Object} txResult - the value returned by the vm
|
|
* @return {Object} - { error: true/false, message: DOMNode }
|
|
*/
|
|
checkVMError: function (txResult) {
|
|
var errorCode = {
|
|
OUT_OF_GAS: 'out of gas',
|
|
STACK_UNDERFLOW: 'stack underflow',
|
|
STACK_OVERFLOW: 'stack overflow',
|
|
INVALID_JUMP: 'invalid JUMP',
|
|
INVALID_OPCODE: 'invalid opcode',
|
|
REVERT: 'revert',
|
|
STATIC_STATE_CHANGE: 'static state change'
|
|
}
|
|
var ret = {
|
|
error: false,
|
|
message: ''
|
|
}
|
|
if (!txResult.result.vm.exceptionError) {
|
|
return ret
|
|
}
|
|
var exceptionError = txResult.result.vm.exceptionError.error || ''
|
|
var error = `VM error: ${exceptionError}.\n`
|
|
var msg
|
|
if (exceptionError === errorCode.INVALID_OPCODE) {
|
|
msg = `\t\n\tThe execution might have thrown.\n`
|
|
ret.error = true
|
|
} else if (exceptionError === errorCode.OUT_OF_GAS) {
|
|
msg = `\tThe transaction ran out of gas. Please increase the Gas Limit.\n`
|
|
ret.error = true
|
|
} else if (exceptionError === errorCode.REVERT) {
|
|
var returnData = txResult.result.vm.return
|
|
// It is the hash of Error(string)
|
|
if (returnData && (returnData.slice(0, 4).toString('hex') === '08c379a0')) {
|
|
var abiCoder = new ethers.utils.AbiCoder()
|
|
var reason = abiCoder.decode(['string'], returnData.slice(4))[0]
|
|
msg = `\tThe transaction has been reverted to the initial state.\nReason provided by the contract: "${reason}".`
|
|
} else {
|
|
msg = `\tThe transaction has been reverted to the initial state.\nNote: The constructor should be payable if you send value.`
|
|
}
|
|
ret.error = true
|
|
} else if (exceptionError === errorCode.STATIC_STATE_CHANGE) {
|
|
msg = `\tState changes is not allowed in Static Call context\n`
|
|
ret.error = true
|
|
}
|
|
ret.message = `${error}${exceptionError}${msg}\tDebug the transaction to get more information.`
|
|
return ret
|
|
}
|
|
}
|
|
|
|
|