Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix representation of contract write call input values before making a call #3497

Merged
merged 1 commit into from Dec 1, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion CHANGELOG.md
Expand Up @@ -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
Expand Down
44 changes: 36 additions & 8 deletions apps/block_scout_web/assets/js/lib/smart_contract/functions.js
Expand Up @@ -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) {
Expand Down Expand Up @@ -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')
Expand Down