Fix a hash displayed in tooltip when signing arbitrary data (#6283)

* Allow connections from firefox extension.

* Displaying actual data that will be signed on hover.

* Display a tooltip.

* Revert "Allow connections from firefox extension."

This reverts commit d3323b76fe28564c2366ceec3d891de19884192f.
This commit is contained in:
Tomasz Drwięga 2017-08-13 17:41:08 +02:00 committed by Gav Wood
parent 604ea5d684
commit b5b6e3dd2a
5 changed files with 65 additions and 5 deletions

View File

@ -75,7 +75,10 @@ export function bytesToAscii (bytes) {
}
export function asciiToHex (string) {
return '0x' + string.split('').map((s) => s.charCodeAt(0).toString(16)).join('');
return '0x' + string.split('')
.map(s => s.charCodeAt(0))
.map(s => s < 0x10 ? '0' + s.toString(16) : s.toString(16))
.join('');
}
export function padRight (input, length) {

View File

@ -67,6 +67,7 @@ describe('api/util/format', () => {
it('correctly converts a non-empty string', () => {
expect(asciiToHex('abc')).to.equal('0x616263');
expect(asciiToHex('a\nb')).to.equal('0x610a62');
});
});

View File

@ -17,7 +17,7 @@
import { isAddress as isAddressValid, toChecksumAddress } from '../../abi/util/address';
import { abiDecode, decodeCallData, decodeMethodInput, methodToAbi } from './decode';
import { abiEncode, abiUnencode, abiSignature, encodeMethodCallAbi } from './encode';
import { bytesToHex, hexToAscii, asciiToHex, cleanupValue } from './format';
import { bytesToHex, hexToAscii, hexToBytes, asciiToHex, cleanupValue } from './format';
import { fromWei, toWei } from './wei';
import { sha3 } from './sha3';
import { isArray, isFunction, isHex, isInstanceOf, isString } from './types';
@ -37,6 +37,7 @@ export default {
isString,
bytesToHex,
hexToAscii,
hexToBytes,
asciiToHex,
createIdentityImg,
decodeCallData,

View File

@ -18,6 +18,7 @@ import { observer } from 'mobx-react';
import React, { Component, PropTypes } from 'react';
import { FormattedMessage } from 'react-intl';
import { connect } from 'react-redux';
import ReactTooltip from 'react-tooltip';
import HardwareStore from '~/mobx/hardwareStore';
@ -70,6 +71,10 @@ class SignRequest extends Component {
}
};
state = {
hashToSign: null
};
hardwareStore = HardwareStore.get(this.context.api);
componentWillMount () {
@ -78,6 +83,25 @@ class SignRequest extends Component {
signerStore.fetchBalance(address);
}
componentDidMount () {
this.computeHashToSign(this.props.data);
}
componentWillReceiveProps (nextProps) {
if (this.props.data !== nextProps.data) {
this.computeHashToSign(nextProps.data);
}
}
computeHashToSign (data) {
const { sha3, hexToBytes, asciiToHex } = this.context.api.util;
const bytes = hexToBytes(data);
const message = hexToBytes(asciiToHex(`\x19Ethereum Signed Message:\n${bytes.length}`));
const hashToSign = sha3(message.concat(bytes));
this.setState({ hashToSign });
}
render () {
const { className } = this.props;
@ -113,6 +137,7 @@ class SignRequest extends Component {
renderDetails () {
const { api } = this.context;
const { address, data, netVersion, origin, signerStore } = this.props;
const { hashToSign } = this.state;
const { balances, externalLink } = signerStore;
const balance = balances[address];
@ -121,6 +146,20 @@ class SignRequest extends Component {
return <div />;
}
const tooltip = [
<FormattedMessage
id='signer.signRequest.tooltip.hash'
defaultMessage='Hash to be signed: {hashToSign}'
values={ { hashToSign } }
/>,
<br />,
<FormattedMessage
id='signer.signRequest.tooltip.data'
defaultMessage='Data: {data}'
values={ { data } }
/>
];
return (
<div className={ styles.signDetails }>
<div className={ styles.address }>
@ -133,7 +172,16 @@ class SignRequest extends Component {
/>
<RequestOrigin origin={ origin } />
</div>
<div className={ styles.info } title={ api.util.sha3(data) }>
<ReactTooltip id={ `signRequest-${hashToSign}` }>
{ tooltip }
</ReactTooltip>
<div
className={ styles.info }
data-effect='solid'
data-for={ `signRequest-${hashToSign}` }
data-place='top'
data-tip
>
<p>
<FormattedMessage
id='signer.signRequest.request'

View File

@ -53,7 +53,14 @@ function render () {
<SignRequest signerStore={ signerStore } />,
{
context: {
store: reduxStore
store: reduxStore,
api: {
util: {
sha3: (x) => x,
hexToBytes: (x) => x,
asciiToHex: (x) => x
}
}
}
}
).find('SignRequest').shallow();
@ -61,7 +68,7 @@ function render () {
return component;
}
describe('views/Signer/components/SignRequest', () => {
describe.only('views/Signer/components/SignRequest', () => {
beforeEach(() => {
render();
});