Validate checksum address for RSK on sendind txs

This commit is contained in:
Victor Baranov 2019-06-16 21:21:24 +03:00
parent 45834b0d2a
commit c1142ddda9
8 changed files with 119 additions and 60 deletions

View File

@ -6,7 +6,7 @@ const actions = require('../../ui/app/actions')
const Tooltip = require('./components/tooltip.js')
const ethUtil = require('ethereumjs-util')
const Copyable = require('./components/copy/copyable')
const { addressSummary, toChecksumAddress } = require('./util')
const { addressSummary, toChecksumAddress, isValidAddress } = require('./util')
module.exports = connect(mapStateToProps)(AddSuggestedTokenScreen)
@ -27,12 +27,10 @@ function AddSuggestedTokenScreen () {
}
AddSuggestedTokenScreen.prototype.render = function () {
const state = this.state
const props = this.props
const { warning } = state
const { network } = props
const key = Object.keys(props.suggestedTokens)[0]
const { address, symbol, decimals } = props.suggestedTokens[key]
const { warning } = this.state
const { network, suggestedTokens, dispatch } = this.props
const key = Object.keys(suggestedTokens)[0]
const { address, symbol, decimals } = suggestedTokens[key]
return (
h('.flex-column.flex-grow', [
@ -133,7 +131,7 @@ AddSuggestedTokenScreen.prototype.render = function () {
margin: '8px',
},
onClick: (event) => {
this.props.dispatch(actions.removeSuggestedTokens())
dispatch(actions.removeSuggestedTokens())
},
}, 'Cancel'),
@ -146,9 +144,9 @@ AddSuggestedTokenScreen.prototype.render = function () {
const valid = this.validateInputs({ address, symbol, decimals })
if (!valid) return
this.props.dispatch(actions.addToken(address.trim(), symbol.trim(), decimals))
dispatch(actions.addToken(address.trim(), symbol.trim(), decimals))
.then(() => {
this.props.dispatch(actions.removeSuggestedTokens())
dispatch(actions.removeSuggestedTokens())
})
},
}, 'Add'),
@ -163,12 +161,13 @@ AddSuggestedTokenScreen.prototype.componentWillMount = function () {
}
AddSuggestedTokenScreen.prototype.validateInputs = function (opts) {
const { network, identities } = this.props
let msg = ''
const identitiesList = Object.keys(this.props.identities)
const identitiesList = Object.keys(identities)
const { address, symbol, decimals } = opts
const standardAddress = ethUtil.addHexPrefix(address).toLowerCase()
const validAddress = ethUtil.isValidAddress(address)
const validAddress = isValidAddress(address, network)
if (!validAddress) {
msg += 'Address is invalid.'
}

View File

@ -4,7 +4,7 @@ const h = require('react-hyperscript')
const Tooltip = require('../tooltip.js')
const TabBar = require('../tab-bar')
const { checkExistingAddresses } = require('./util')
const { getCurrentKeyring, ifContractAcc } = require('../../util')
const { getCurrentKeyring, ifContractAcc, isValidAddress } = require('../../util')
const TokenList = require('./token-list')
const TokenSearch = require('./token-search')
const { tokenInfoGetter } = require('../../../../ui/app/token-util')
@ -351,7 +351,7 @@ class AddTokenScreen extends Component {
const { customAddress: address, customSymbol: symbol, customDecimals: decimals } = state
const standardAddress = ethUtil.addHexPrefix(address).toLowerCase()
const validAddress = ethUtil.isValidAddress(address)
const validAddress = isValidAddress(address, network)
if (!validAddress) {
msg += 'Address is invalid.'
}
@ -472,7 +472,7 @@ class AddTokenScreen extends Component {
autoFilled: false,
})
const isValidAddress = ethUtil.isValidAddress(customAddress)
const isValidAddress = isValidAddress(customAddress, network)
const standardAddress = ethUtil.addHexPrefix(customAddress).toLowerCase()
let warning

View File

@ -115,7 +115,7 @@ PendingTx.prototype.render = function () {
const balance = account ? account.balance : '0x0'
// recipient check
const isValidAddress = !txParams.to || util.isValidAddress(txParams.to)
const isValidAddress = !txParams.to || util.isValidAddress(txParams.to, network)
// Gas
const gas = txParams.gas

View File

@ -124,8 +124,8 @@ class SendTransactionScreen extends PersistentForm {
createFreshTokenTracker () {
this.setState({isLoading: true})
const { address, tokenAddress } = this.props
if (!isValidAddress(tokenAddress)) return
const { address, tokenAddress, network } = this.props
if (!isValidAddress(tokenAddress, network)) return
if (this.tracker) {
// Clean up old trackers when refreshing:
this.tracker.stop()
@ -225,12 +225,12 @@ class SendTransactionScreen extends PersistentForm {
return this.props.displayWarning(message)
}
if ((isInvalidChecksumAddress(recipient))) {
if ((isInvalidChecksumAddress(recipient, this.props.network))) {
message = 'Recipient address checksum is invalid.'
return this.props.displayWarning(message)
}
if (!isValidAddress(recipient) || (!recipient)) {
if (!isValidAddress(recipient, this.props.network) || (!recipient)) {
message = 'Recipient address is invalid.'
return this.props.displayWarning(message)
}

View File

@ -205,12 +205,12 @@ SendTransactionScreen.prototype.onSubmit = function () {
return this.props.dispatch(actions.displayWarning(message))
}
if ((isInvalidChecksumAddress(recipient))) {
if ((isInvalidChecksumAddress(recipient, this.props.network))) {
message = 'Recipient address checksum is invalid.'
return this.props.dispatch(actions.displayWarning(message))
}
if ((!isValidAddress(recipient) && !txData) || (!recipient && !txData)) {
if ((!isValidAddress(recipient, this.props.network) && !txData) || (!recipient && !txData)) {
message = 'Recipient address is invalid.'
return this.props.dispatch(actions.displayWarning(message))
}

View File

@ -296,7 +296,7 @@ function renderErrorOrWarning (transaction, network) {
// show warning
const isRSK = ifRSK(network)
if (warning && !isRSK || (isRSK && !warning.error.includes('[ethjs-rpc] rpc error with payload'))) {
if (warning && !isRSK || (isRSK && warning && !warning.error.includes('[ethjs-rpc] rpc error with payload'))) {
const message = warning.message
return h(Tooltip, {
title: message,

View File

@ -24,25 +24,25 @@ for (var currency in valueTable) {
}
module.exports = {
valuesFor: valuesFor,
addressSummary: addressSummary,
accountSummary: accountSummary,
isAllOneCase: isAllOneCase,
isValidAddress: isValidAddress,
valuesFor,
addressSummary,
accountSummary,
isAllOneCase,
isValidAddress,
isValidENSAddress,
numericBalance: numericBalance,
parseBalance: parseBalance,
formatBalance: formatBalance,
generateBalanceObject: generateBalanceObject,
dataSize: dataSize,
readableDate: readableDate,
normalizeToWei: normalizeToWei,
normalizeEthStringToWei: normalizeEthStringToWei,
normalizeNumberToWei: normalizeNumberToWei,
valueTable: valueTable,
bnTable: bnTable,
isHex: isHex,
exportAsFile: exportAsFile,
numericBalance,
parseBalance,
formatBalance,
generateBalanceObject,
dataSize,
readableDate,
normalizeToWei,
normalizeEthStringToWei,
normalizeNumberToWei,
valueTable,
bnTable,
isHex,
exportAsFile,
isInvalidChecksumAddress,
countSignificantDecimals,
getCurrentKeyring,
@ -52,6 +52,7 @@ module.exports = {
getAllKeyRingsAccounts,
ifRSK,
toChecksumAddress,
isValidChecksumAddress,
}
function valuesFor (obj) {
@ -77,20 +78,27 @@ function accountSummary (acc, firstSegLength = 6, lastSegLength = 4) {
return acc.slice(0, firstSegLength) + '...' + acc.slice(posOfLastPart)
}
function isValidAddress (address) {
function isValidAddress (address, network) {
var prefixed = ethUtil.addHexPrefix(address)
if (address === '0x0000000000000000000000000000000000000000') return false
return (isAllOneCase(prefixed) && ethUtil.isValidAddress(prefixed)) || ethUtil.isValidChecksumAddress(prefixed)
if (ifRSK(network)) {
// console.log('addHexPrefixRSK:', prefixed)
if (address === '0x0000000000000000000000000000000000000000') return false
return (ethUtil.isValidAddress(prefixed))
} else {
// console.log('addHexPrefix:', prefixed)
if (address === '0x0000000000000000000000000000000000000000') return false
return (isAllOneCase(prefixed) && ethUtil.isValidAddress(prefixed)) || ethUtil.isValidChecksumAddress(prefixed)
}
}
function isValidENSAddress (address) {
return address.match(/^.{7,}\.(eth|test)$/)
}
function isInvalidChecksumAddress (address) {
function isInvalidChecksumAddress (address, network) {
var prefixed = ethUtil.addHexPrefix(address)
if (address === '0x0000000000000000000000000000000000000000') return false
return !isAllOneCase(prefixed) && !ethUtil.isValidChecksumAddress(prefixed) && ethUtil.isValidAddress(prefixed)
return !isAllOneCase(prefixed) && !isValidChecksumAddress(network, prefixed)
}
function isAllOneCase (address) {
@ -375,19 +383,26 @@ function getAllKeyRingsAccounts (keyrings, network) {
return accountOrder
}
function toChecksumAddressRSK (address, chainId = null) {
const stripAddress = ethUtil.stripHexPrefix(address).toLowerCase()
const prefix = chainId != null ? (chainId.toString() + '0x') : ''
const keccakHash = ethUtil.sha3(prefix + stripAddress).toString('hex')
let output = '0x'
for (let i = 0; i < stripAddress.length; i++) {
output += parseInt(keccakHash[i], 16) >= 8 ?
stripAddress[i].toUpperCase() :
stripAddress[i]
function ifRSK (network) {
if (!network) return false
const numericNet = isNaN(network) ? network : parseInt(network)
return numericNet === RSK_CODE || numericNet === RSK_TESTNET_CODE
}
return output
function toChecksumAddressRSK (address, chainId = null) {
const zeroX = '0x'
const stripAddress = ethUtil.stripHexPrefix(address).toLowerCase()
const prefix = chainId != null ? (chainId.toString() + zeroX) : ''
const keccakHash = ethUtil.sha3(prefix + stripAddress).toString('hex')
let output = zeroX
for (let i = 0; i < stripAddress.length; i++) {
output += parseInt(keccakHash[i], 16) >= 8 ?
stripAddress[i].toUpperCase() :
stripAddress[i]
}
return output
}
function toChecksumAddress (network, address, chainId = null) {
@ -398,7 +413,10 @@ function toChecksumAddress (network, address, chainId = null) {
}
}
function ifRSK (network) {
const numericNet = isNaN(network) ? network : parseInt(network)
return numericNet === RSK_CODE || numericNet === RSK_TESTNET_CODE
function isValidChecksumAddress (network, address) {
// console.log('isValidAddress(address):', isValidAddress(address, network))
// console.log('toChecksumAddress(network, address) === address', toChecksumAddress(network, address) === address)
// console.log('ethUtil.isValidAddress(address)', ethUtil.isValidAddress(address))
// console.log('isAllOneCase', isAllOneCase(address))
return isValidAddress(address, network) && toChecksumAddress(network, address) === address
}

View File

@ -13,6 +13,9 @@ const {
normalizeEthStringToWei,
normalizeNumberToWei,
isHex,
ifRSK,
toChecksumAddress,
isValidChecksumAddress,
} = require('../../../../old-ui/app/util')
const ethUtil = require('ethereumjs-util')
let ethInWei = '1'
@ -329,4 +332,43 @@ describe('normalizing values', function () {
assert(result)
})
})
describe('#ifRSK', function () {
it('checks if this is RSK chain', function () {
var result1 = ifRSK(30)
assert(result1)
var result2 = ifRSK(31)
assert(result2)
var result3 = ifRSK(1)
assert(!result3)
var result4 = ifRSK()
assert(!result4)
})
})
const addr = '0xB707b030A7887a21cc595Cd139746A8c2Ed91615'
const addrRSKMainnet = '0xB707b030A7887a21Cc595cD139746A8c2ED91615'
const addrRSKTestnet = '0xB707b030a7887a21Cc595CD139746a8C2ED91615'
const addrETHMainnet = '0xB707b030A7887a21cc595Cd139746A8c2Ed91615'
describe('#toChecksumAddress', function () {
it('calculates correct checksum', function () {
var resultMainnet = toChecksumAddress('30', addr)
assert.equal(resultMainnet, addrRSKMainnet)
var resultTestnet = toChecksumAddress('31', addr)
assert.equal(resultTestnet, addrRSKTestnet)
var resultNotRSK = toChecksumAddress('1', addr)
assert.equal(resultNotRSK, addrETHMainnet)
})
})
describe('#isValidChecksumAddress', function () {
it('checks if is valid checksum address', function () {
var resultMainnet = isValidChecksumAddress('30', addrRSKMainnet)
assert(resultMainnet)
var resultTestnet = isValidChecksumAddress('31', addrRSKTestnet)
assert(resultTestnet)
var resultNotRSK = isValidChecksumAddress('1', addrETHMainnet)
assert(resultNotRSK)
})
})
})