From 681d9328967a8d799c006ba74659ed49e1d05e35 Mon Sep 17 00:00:00 2001 From: Victor Baranov Date: Tue, 1 Dec 2020 14:21:51 +0300 Subject: [PATCH] Fix contract write call inputs --- CHANGELOG.md | 2 +- .../assets/js/lib/smart_contract/functions.js | 44 +++++++++++++++---- 2 files changed, 37 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b8edb9154d..56532131db 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,7 @@ - [#3462](https://github.com/poanetwork/blockscout/pull/3462) - Display price for bridged tokens ### Fixes -- [#3494](https://github.com/poanetwork/blockscout/pull/3494) - Contracts interaction: fix method call with array[] input +- [#3494](https://github.com/poanetwork/blockscout/pull/3494), [#3497](https://github.com/poanetwork/blockscout/pull/3497) - Contracts interaction: fix method call with array[] input - [#3494](https://github.com/poanetwork/blockscout/pull/3494), [#3495](https://github.com/poanetwork/blockscout/pull/3495) - Contracts interaction: fix tuple output display - [#3479](https://github.com/poanetwork/blockscout/pull/3479) - Fix working with big numbers in Staking DApp - [#3477](https://github.com/poanetwork/blockscout/pull/3477) - Contracts interaction: fix broken call of GnosisProxy contract methods with parameters diff --git a/apps/block_scout_web/assets/js/lib/smart_contract/functions.js b/apps/block_scout_web/assets/js/lib/smart_contract/functions.js index 3e03437e81..027bf30e26 100644 --- a/apps/block_scout_web/assets/js/lib/smart_contract/functions.js +++ b/apps/block_scout_web/assets/js/lib/smart_contract/functions.js @@ -122,31 +122,51 @@ function callMethod (isWalletEnabled, $functionInputs, explorerChainId, $form, f const warningMsg = 'You haven\'t approved the reading of account list from your MetaMask or MetaMask/Nifty wallet is locked or is not installed.' return openWarningModal('Unauthorized', warningMsg) } + const contractAbi = getContractABI($form) + const functionAbi = contractAbi.find(abi => + abi.name === functionName + ) + const inputs = functionAbi && functionAbi.inputs const $functionInputsExceptTxValue = $functionInputs.filter(':not([tx-value])') - const args = $.map($functionInputsExceptTxValue, element => $(element).val()) + const args = $.map($functionInputsExceptTxValue, (element, ind) => { + const val = $(element).val() + const inputType = inputs[ind] && inputs[ind].type + let preparedVal + if (isNonSpaceInputType(inputType)) { preparedVal = val.replace(/\s/g, '') } else { preparedVal = val } + if (isArrayInputType(inputType)) { + return preparedVal.split(',') + } else { return preparedVal } + }) const txValue = getTxValue($functionInputs) const contractAddress = $form.data('contract-address') - const contractAbi = getContractABI($form) const { chainId: walletChainIdHex } = window.ethereum compareChainIDs(explorerChainId, walletChainIdHex) .then(currentAccount => { if (functionName) { const TargetContract = new window.web3.eth.Contract(contractAbi, contractAddress) - const functionAbi = contractAbi.find(abi => - abi.name === functionName - ) - const inputsCount = functionAbi && functionAbi.inputs.length + const inputsCount = inputs && inputs.length let methodToCall const sendParams = { from: currentAccount, value: txValue || 0 } if (inputsCount > 1) { methodToCall = TargetContract.methods[functionName](...args).send(sendParams) } else { + const inputType = inputs[0] && inputs[0].type if (Array.isArray(args) && args[0] === '') { - methodToCall = TargetContract.methods[functionName]([]).send(sendParams) - } else { methodToCall = TargetContract.methods[functionName](args).send(sendParams) } + if (isArrayInputType(inputType)) { + methodToCall = TargetContract.methods[functionName]([]).send(sendParams) + } else { + methodToCall = TargetContract.methods[functionName]().send(sendParams) + } + } else { + if (isArrayInputType(inputType)) { + methodToCall = TargetContract.methods[functionName](args).send(sendParams) + } else { + methodToCall = TargetContract.methods[functionName](args[0]).send(sendParams) + } + } } methodToCall .on('error', function (error) { @@ -178,6 +198,14 @@ function callMethod (isWalletEnabled, $functionInputs, explorerChainId, $form, f }) } +function isArrayInputType (inputType) { + return inputType && inputType.includes('[]') +} + +function isNonSpaceInputType (inputType) { + return inputType.includes('address') || inputType.includes('int') || inputType.includes('bool') +} + function getTxValue ($functionInputs) { const WEI_MULTIPLIER = 10 ** 18 const $txValue = $functionInputs.filter('[tx-value]:first')