1
0
mirror of https://github.com/trezor/trezor-wallet synced 2024-11-28 03:08:30 +00:00

Merge pull request #136 from trezor/fix/allow-data-prefix

allow "0x" prefix in transaction data
This commit is contained in:
Vladimir Volek 2018-10-09 10:45:35 +02:00 committed by GitHub
commit 95c3c8dba7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 16 additions and 12 deletions

View File

@ -11,6 +11,7 @@ import * as ValidationActions from 'actions/SendFormValidationActions';
import { initialState } from 'reducers/SendFormReducer'; import { initialState } from 'reducers/SendFormReducer';
import { findToken } from 'reducers/TokensReducer'; import { findToken } from 'reducers/TokensReducer';
import * as reducerUtils from 'reducers/utils'; import * as reducerUtils from 'reducers/utils';
import * as ethUtils from 'utils/ethUtils';
import type { import type {
Dispatch, Dispatch,
@ -397,8 +398,7 @@ const estimateGasPrice = (): AsyncAction => async (dispatch: Dispatch, getState:
} }
const requestedData = state.data; const requestedData = state.data;
const re = /^[0-9A-Fa-f]+$/g; // TODO: allow "0x" prefix if (!ethUtils.isHex(requestedData)) {
if (!re.test(requestedData)) {
// stop "calculatingGasLimit" process // stop "calculatingGasLimit" process
dispatch(onGasLimitChange(requestedData.length > 0 ? state.gasLimit : network.defaultGasLimit.toString())); dispatch(onGasLimitChange(requestedData.length > 0 ? state.gasLimit : network.defaultGasLimit.toString()));
return; return;

View File

@ -6,6 +6,7 @@ import EthereumjsUnits from 'ethereumjs-units';
import { findToken } from 'reducers/TokensReducer'; import { findToken } from 'reducers/TokensReducer';
import { findDevice, getPendingAmount } from 'reducers/utils'; import { findDevice, getPendingAmount } from 'reducers/utils';
import * as SEND from 'actions/constants/send'; import * as SEND from 'actions/constants/send';
import * as ethUtils from 'utils/ethUtils';
import type { import type {
Dispatch, Dispatch,
@ -19,7 +20,6 @@ const NUMBER_RE: RegExp = new RegExp('^(0|0\\.([0-9]+)?|[1-9][0-9]*\\.?([0-9]+)?
const UPPERCASE_RE = new RegExp('^(.*[A-Z].*)$'); const UPPERCASE_RE = new RegExp('^(.*[A-Z].*)$');
const ABS_RE = new RegExp('^[0-9]+$'); const ABS_RE = new RegExp('^[0-9]+$');
const ETH_18_RE = new RegExp('^(0|0\\.([0-9]{0,18})?|[1-9][0-9]*\\.?([0-9]{0,18})?|\\.[0-9]{0,18})$'); const ETH_18_RE = new RegExp('^(0|0\\.([0-9]{0,18})?|[1-9][0-9]*\\.?([0-9]{0,18})?|\\.[0-9]{0,18})$');
const HEX_RE = new RegExp('^[0-9A-Fa-f]+$');
const dynamicRegexp = (decimals: number): RegExp => { const dynamicRegexp = (decimals: number): RegExp => {
if (decimals > 0) { if (decimals > 0) {
return new RegExp(`^(0|0\\.([0-9]{0,${decimals}})?|[1-9][0-9]*\\.?([0-9]{0,${decimals}})?|\\.[0-9]{1,${decimals}})$`); return new RegExp(`^(0|0\\.([0-9]{0,${decimals}})?|[1-9][0-9]*\\.?([0-9]{0,${decimals}})?|\\.[0-9]{1,${decimals}})$`);
@ -326,7 +326,7 @@ export const nonceValidation = ($state: State): PayloadAction<State> => (dispatc
export const dataValidation = ($state: State): PayloadAction<State> => (): State => { export const dataValidation = ($state: State): PayloadAction<State> => (): State => {
const state = { ...$state }; const state = { ...$state };
if (!state.touched.data || state.data.length === 0) return state; if (!state.touched.data || state.data.length === 0) return state;
if (!HEX_RE.test(state.data)) { if (!ethUtils.isHex(state.data)) {
state.errors.data = 'Data is not valid hexadecimal'; state.errors.data = 'Data is not valid hexadecimal';
} }
return state; return state;

View File

@ -5,6 +5,7 @@ import EthereumjsUnits from 'ethereumjs-units';
import BigNumber from 'bignumber.js'; import BigNumber from 'bignumber.js';
import { toHex } from 'web3-utils'; // eslint-disable-line import/no-extraneous-dependencies import { toHex } from 'web3-utils'; // eslint-disable-line import/no-extraneous-dependencies
import { initWeb3 } from 'actions/Web3Actions'; import { initWeb3 } from 'actions/Web3Actions';
import * as ethUtils from 'utils/ethUtils';
import type { import type {
Dispatch, Dispatch,
@ -29,10 +30,9 @@ type EthereumTxRequest = {
export const prepareEthereumTx = (tx: EthereumTxRequest): PromiseAction<EthereumTransaction> => async (dispatch: Dispatch): Promise<EthereumTransaction> => { export const prepareEthereumTx = (tx: EthereumTxRequest): PromiseAction<EthereumTransaction> => async (dispatch: Dispatch): Promise<EthereumTransaction> => {
const instance = await dispatch(initWeb3(tx.network)); const instance = await dispatch(initWeb3(tx.network));
const { token } = tx; const { token } = tx;
let data: string = `0x${tx.data}`; // TODO: check if already prefixed let data: string = ethUtils.sanitizeHex(tx.data);
let value: string = toHex(EthereumjsUnits.convert(tx.amount, 'ether', 'wei')); let value: string = toHex(EthereumjsUnits.convert(tx.amount, 'ether', 'wei'));
let to: string = tx.to; // eslint-disable-line prefer-destructuring let to: string = tx.to; // eslint-disable-line prefer-destructuring
if (token) { if (token) {
// smart contract transaction // smart contract transaction
const contract = instance.erc20.clone(); const contract = instance.erc20.clone();

View File

@ -7,6 +7,7 @@ import EthereumjsUnits from 'ethereumjs-units';
import type { EstimateGasOptions } from 'web3'; import type { EstimateGasOptions } from 'web3';
import * as WEB3 from 'actions/constants/web3'; import * as WEB3 from 'actions/constants/web3';
import * as PENDING from 'actions/constants/pendingTx'; import * as PENDING from 'actions/constants/pendingTx';
import * as ethUtils from 'utils/ethUtils';
import type { import type {
Dispatch, Dispatch,
@ -272,8 +273,7 @@ export const updateGasPrice = (network: string): PromiseAction<void> => async (d
export const estimateGasLimit = (network: string, $options: EstimateGasOptions): PromiseAction<string> => async (dispatch: Dispatch): Promise<string> => { export const estimateGasLimit = (network: string, $options: EstimateGasOptions): PromiseAction<string> => async (dispatch: Dispatch): Promise<string> => {
const instance = await dispatch(initWeb3(network)); const instance = await dispatch(initWeb3(network));
// TODO: allow data starting with 0x ... const data = ethUtils.sanitizeHex($options.data);
const data = `0x${$options.data.length % 2 === 0 ? $options.data : `0${$options.data}`}`;
const options = { const options = {
...$options, ...$options,
to: '0x0000000000000000000000000000000000000000', to: '0x0000000000000000000000000000000000000000',

View File

@ -7,15 +7,14 @@ export const decimalToHex = (dec: number): string => new BigNumber(dec).toString
export const padLeftEven = (hex: string): string => (hex.length % 2 !== 0 ? `0${hex}` : hex); export const padLeftEven = (hex: string): string => (hex.length % 2 !== 0 ? `0${hex}` : hex);
export const sanitizeHex = ($hex: number | string): ?string => { export const sanitizeHex = ($hex: string): string => {
if (typeof $hex !== 'string') return null; const hex = $hex.toLowerCase().substring(0, 2) === '0x' ? $hex.substring(2) : $hex;
const hex = $hex.substring(0, 2) === '0x' ? $hex.substring(2) : $hex;
if (hex === '') return ''; if (hex === '') return '';
return `0x${padLeftEven(hex)}`; return `0x${padLeftEven(hex)}`;
}; };
export const hexToDecimal = (hex: number): string => { export const hexToDecimal = (hex: number): string => {
const sanitized: ?string = sanitizeHex(hex); const sanitized: ?string = sanitizeHex(hex.toString());
return !sanitized ? 'null' : new BigNumber(sanitized).toString(); return !sanitized ? 'null' : new BigNumber(sanitized).toString();
}; };
@ -41,3 +40,8 @@ export const validateAddress = (address: string): ?string => {
} }
return null; return null;
}; };
export const isHex = (str: string): boolean => {
const regExp = /^(0x|0X)?[0-9A-Fa-f]+$/g;
return regExp.test(str);
};