Files
2017-06-18 03:50:34 -07:00

197 lines
8.6 KiB
JavaScript

'use strict';
var contractsCtrl = function($scope, $sce, walletService) {
$scope.ajaxReq = ajaxReq;
walletService.wallet = null;
$scope.visibility = "interactView";
$scope.sendContractModal = new Modal(document.getElementById('sendContract'));
$scope.showReadWrite = false;
$scope.sendTxModal = new Modal(document.getElementById('deployContract'));
$scope.Validator = Validator;
$scope.tx = {
gasLimit: '',
data: '',
to: '',
unit: "ether",
value: 0,
nonce: null,
gasPrice: null
}
$scope.contract = {
address: globalFuncs.urlGet('address') != null && $scope.Validator.isValidAddress(globalFuncs.urlGet('address')) ? globalFuncs.urlGet('address') : '',
abi: '',
functions: [],
selectedFunc: null
}
$scope.selectedAbi = ajaxReq.abiList[0];
$scope.showRaw = false;
$scope.$watch(function() {
if (walletService.wallet == null) return null;
return walletService.wallet.getAddressString();
}, function() {
if (walletService.wallet == null) return;
$scope.wallet = walletService.wallet;
$scope.wd = true;
$scope.tx.nonce = 0;
});
$scope.$watch('visibility', function(newValue, oldValue) {
$scope.tx = {
gasLimit: '',
data: '',
to: '',
unit: "ether",
value: 0,
nonce: null,
gasPrice: null
}
});
$scope.$watch('tx', function(newValue, oldValue) {
$scope.showRaw = false;
if (newValue.gasLimit == oldValue.gasLimit && $scope.Validator.isValidHex($scope.tx.data) && $scope.tx.data != '' && $scope.Validator.isPositiveNumber($scope.tx.value)) {
if ($scope.estimateTimer) clearTimeout($scope.estimateTimer);
$scope.estimateTimer = setTimeout(function() {
$scope.estimateGasLimit();
}, 500);
}
}, true);
$scope.$watch('contract.address', function(newValue, oldValue) {
if ($scope.Validator.isValidAddress($scope.contract.address)) {
for (var i in ajaxReq.abiList) {
if (ajaxReq.abiList[i].address.toLowerCase() == $scope.contract.address.toLowerCase()) {
$scope.contract.abi = ajaxReq.abiList[i].abi;
break;
}
}
}
});
$scope.selectExistingAbi = function(index) {
$scope.selectedAbi = ajaxReq.abiList[index];
$scope.contract.address = $scope.selectedAbi.address;
$scope.dropdownExistingContracts = false;
}
$scope.estimateGasLimit = function() {
var estObj = {
from: $scope.wallet != null ? $scope.wallet.getAddressString() : globalFuncs.donateAddress,
value: ethFuncs.sanitizeHex(ethFuncs.decimalToHex(etherUnits.toWei($scope.tx.value, $scope.tx.unit))),
data: ethFuncs.sanitizeHex($scope.tx.data),
}
if ($scope.tx.to != '') estObj.to = $scope.tx.to;
ethFuncs.estimateGas(estObj, function(data) {
if (!data.error) $scope.tx.gasLimit = data.data;
});
}
$scope.generateTx = function() {
try {
if ($scope.wallet == null) throw globalFuncs.errorMsgs[3];
else if (!ethFuncs.validateHexString($scope.tx.data)) throw globalFuncs.errorMsgs[9];
else if (!globalFuncs.isNumeric($scope.tx.gasLimit) || parseFloat($scope.tx.gasLimit) <= 0) throw globalFuncs.errorMsgs[8];
$scope.tx.data = ethFuncs.sanitizeHex($scope.tx.data);
ajaxReq.getTransactionData($scope.wallet.getAddressString(), function(data) {
if (data.error) $scope.notifier.danger(data.msg);
data = data.data;
$scope.tx.to = $scope.tx.to == '' ? '0xCONTRACT' : $scope.tx.to;
$scope.tx.contractAddr = $scope.tx.to == '0xCONTRACT' ? ethFuncs.getDeteministicContractAddress($scope.wallet.getAddressString(), data.nonce) : '';
var txData = uiFuncs.getTxData($scope);
uiFuncs.generateTx(txData, function(rawTx) {
if (!rawTx.isError) {
$scope.rawTx = rawTx.rawTx;
$scope.signedTx = rawTx.signedTx;
$scope.showRaw = true;
} else {
$scope.showRaw = false;
$scope.notifier.danger(rawTx.error);
}
if (!$scope.$$phase) $scope.$apply();
});
});
} catch (e) {
$scope.notifier.danger(e);
}
}
$scope.sendTx = function() {
$scope.sendTxModal.close();
$scope.sendContractModal.close();
uiFuncs.sendTx($scope.signedTx, function(resp) {
if (!resp.isError) {
var bExStr = $scope.ajaxReq.type != nodes.nodeTypes.Custom ? "<a href='" + $scope.ajaxReq.blockExplorerTX.replace("[[txHash]]", resp.data) + "' target='_blank' rel='noopener'> View your transaction </a>" : '';
var contractAddr = $scope.tx.contractAddr != '' ? " & Contract Address <a href='" + ajaxReq.blockExplorerAddr.replace('[[address]]', $scope.tx.contractAddr) + "' target='_blank' rel='noopener'>" + $scope.tx.contractAddr + "</a>" : '';
$scope.notifier.success(globalFuncs.successMsgs[2] + "<br />" + resp.data + "<br />" + bExStr + contractAddr);
} else {
$scope.notifier.danger(resp.error);
}
});
}
$scope.setVisibility = function(str) {
$scope.visibility = str;
}
$scope.selectFunc = function(index) {
$scope.contract.selectedFunc = { name: $scope.contract.functions[index].name, index: index };
if (!$scope.contract.functions[index].inputs.length) {
$scope.readFromContract();
$scope.showRead = false;
} else $scope.showRead = true;
$scope.dropdownContracts = !$scope.dropdownContracts;
}
$scope.getTxData = function() {
var curFunc = $scope.contract.functions[$scope.contract.selectedFunc.index];
var fullFuncName = ethUtil.solidityUtils.transformToFullName(curFunc);
var funcSig = ethFuncs.getFunctionSignature(fullFuncName);
var typeName = ethUtil.solidityUtils.extractTypeName(fullFuncName);
var types = typeName.split(',');
types = types[0] == "" ? [] : types;
var values = [];
for (var i in curFunc.inputs) {
if (curFunc.inputs[i].value) {
if (curFunc.inputs[i].type.indexOf('[') !== -1 && curFunc.inputs[i].type.indexOf(']') !== -1) values.push(curFunc.inputs[i].value.split(','));
else values.push(curFunc.inputs[i].value);
} else values.push('');
}
return '0x' + funcSig + ethUtil.solidityCoder.encodeParams(types, values);
}
$scope.readFromContract = function() {
ajaxReq.getEthCall({ to: $scope.contract.address, data: $scope.getTxData() }, function(data) {
if (!data.error) {
var curFunc = $scope.contract.functions[$scope.contract.selectedFunc.index];
var outTypes = curFunc.outputs.map(function(i) {
return i.type;
});
var decoded = ethUtil.solidityCoder.decodeParams(outTypes, data.data.replace('0x', ''));
for (var i in decoded) {
if (decoded[i] instanceof BigNumber) curFunc.outputs[i].value = decoded[i].toFixed(0);
else curFunc.outputs[i].value = decoded[i];
}
} else throw data.msg;
});
}
$scope.initContract = function() {
try {
if (!$scope.Validator.isValidAddress($scope.contract.address)) throw globalFuncs.errorMsgs[5];
else if (!$scope.Validator.isJSON($scope.contract.abi)) throw globalFuncs.errorMsgs[26];
$scope.contract.functions = [];
var tAbi = JSON.parse($scope.contract.abi);
for (var i in tAbi)
if (tAbi[i].type == "function") {
tAbi[i].inputs.map(function(i) { i.value = ''; });
$scope.contract.functions.push(tAbi[i]);
}
$scope.showReadWrite = true;
} catch (e) {
$scope.notifier.danger(e);
}
}
$scope.generateContractTx = function() {
if (!$scope.wd) {
$scope.notifier.danger(globalFuncs.errorMsgs[3]);
return;
}
$scope.tx.data = $scope.getTxData();
$scope.tx.to = $scope.contract.address;
$scope.sendContractModal.open();
}
}
module.exports = contractsCtrl;