diff --git a/js/src/api/util/sha3.js b/js/src/api/util/sha3.js index 11ca6189a..f07f88068 100644 --- a/js/src/api/util/sha3.js +++ b/js/src/api/util/sha3.js @@ -17,9 +17,12 @@ import { keccak_256 } from 'js-sha3'; // eslint-disable-line import { hexToBytes } from './format'; +import { isHex } from './types'; export function sha3 (value, options) { - if (options && options.encoding === 'hex') { + const forceHex = options && options.encoding === 'hex'; + + if (forceHex || (!options && isHex(value))) { const bytes = hexToBytes(value); return sha3(bytes); } @@ -28,3 +31,5 @@ export function sha3 (value, options) { return `0x${hash}`; } + +sha3.text = (val) => sha3(val, { encoding: 'raw' }); diff --git a/js/src/api/util/sha3.spec.js b/js/src/api/util/sha3.spec.js index 3446f7def..2945ce51a 100644 --- a/js/src/api/util/sha3.spec.js +++ b/js/src/api/util/sha3.spec.js @@ -32,5 +32,14 @@ describe('api/util/sha3', () => { expect(sha3('01020304', { encoding: 'hex' })).to.equal('0xa6885b3731702da62e8e4a8f584ac46a7f6822f4e2ba50fba902f67b1588d23b'); expect(sha3(Uint8Array.from([1, 2, 3, 4]))).to.equal('0xa6885b3731702da62e8e4a8f584ac46a7f6822f4e2ba50fba902f67b1588d23b'); }); + + it('should interpret as bytes by default', () => { + expect(sha3('0x01020304')).to.equal('0xa6885b3731702da62e8e4a8f584ac46a7f6822f4e2ba50fba902f67b1588d23b'); + }); + + it('should force text if option is passed', () => { + expect(sha3('0x01020304', { encoding: 'raw' })).to.equal('0x16bff43de576d28857dcba65a56fc17c5e93c09bd6a709268eff8e62025ae869'); + expect(sha3.text('0x01020304')).to.equal('0x16bff43de576d28857dcba65a56fc17c5e93c09bd6a709268eff8e62025ae869'); + }); }); }); diff --git a/js/src/api/util/types.js b/js/src/api/util/types.js index 6fe442e93..96d7251d5 100644 --- a/js/src/api/util/types.js +++ b/js/src/api/util/types.js @@ -29,6 +29,10 @@ export function isFunction (test) { } export function isHex (_test) { + if (!isString(_test)) { + return false; + } + if (_test.substr(0, 2) === '0x') { return isHex(_test.slice(2)); } diff --git a/js/src/api/util/types.spec.js b/js/src/api/util/types.spec.js index df9bf2f1f..1436eb160 100644 --- a/js/src/api/util/types.spec.js +++ b/js/src/api/util/types.spec.js @@ -66,6 +66,12 @@ describe('api/util/types', () => { it('correctly identifies non-hex values', () => { expect(isHex('123j')).to.be.false; }); + + it('correctly indentifies non-string values', () => { + expect(isHex(false)).to.be.false; + expect(isHex()).to.be.false; + expect(isHex([1, 2, 3])).to.be.false; + }); }); describe('isInstanceOf', () => { diff --git a/js/src/contracts/registry.js b/js/src/contracts/registry.js index 04c562f50..ffb14c626 100644 --- a/js/src/contracts/registry.js +++ b/js/src/contracts/registry.js @@ -91,7 +91,7 @@ export default class Registry { lookupAddress (_name) { const name = _name.toLowerCase(); - const sha3 = this._api.util.sha3(name); + const sha3 = this._api.util.sha3.text(name); return this.getInstance().then((instance) => { return instance.getAddress.call({}, [sha3, 'A']); diff --git a/js/src/dapps/registry/Lookup/actions.js b/js/src/dapps/registry/Lookup/actions.js index 1e8ed5898..3a8ef515e 100644 --- a/js/src/dapps/registry/Lookup/actions.js +++ b/js/src/dapps/registry/Lookup/actions.js @@ -39,7 +39,7 @@ export const lookup = (name, key) => (dispatch, getState) => { name = name.toLowerCase(); dispatch(lookupStart(name, key)); - getAddress.call({}, [ sha3(name), key ]) + getAddress.call({}, [ sha3.text(name), key ]) .then((address) => dispatch(success('lookup', address))) .catch((err) => { console.error(`could not lookup ${key} for ${name}`); diff --git a/js/src/dapps/registry/Names/actions.js b/js/src/dapps/registry/Names/actions.js index 2396278cb..12600ff80 100644 --- a/js/src/dapps/registry/Names/actions.js +++ b/js/src/dapps/registry/Names/actions.js @@ -62,7 +62,7 @@ export const reserve = (name) => (dispatch, getState) => { value: fee }; const values = [ - sha3(name) + sha3.text(name) ]; return postTx(api, reserve, options, values); @@ -116,7 +116,7 @@ export const drop = (name) => (dispatch, getState) => { }; const values = [ - sha3(name) + sha3.text(name) ]; return postTx(api, drop, options, values); diff --git a/js/src/dapps/registry/Records/actions.js b/js/src/dapps/registry/Records/actions.js index f85304d5f..8318c9dcc 100644 --- a/js/src/dapps/registry/Records/actions.js +++ b/js/src/dapps/registry/Records/actions.js @@ -54,7 +54,7 @@ export const update = (name, key, value) => (dispatch, getState) => { }; const values = [ - sha3(name), + sha3.text(name), key, value ]; diff --git a/js/src/dapps/registry/util/registry.js b/js/src/dapps/registry/util/registry.js index 371b29aec..ed3039b4d 100644 --- a/js/src/dapps/registry/util/registry.js +++ b/js/src/dapps/registry/util/registry.js @@ -17,7 +17,7 @@ export const getOwner = (contract, name) => { const { address, api } = contract; - const key = api.util.sha3(name) + '0000000000000000000000000000000000000000000000000000000000000001'; + const key = api.util.sha3.text(name) + '0000000000000000000000000000000000000000000000000000000000000001'; const position = api.util.sha3(key, { encoding: 'hex' }); return api diff --git a/js/src/modals/ExecuteContract/executeContract.test.js b/js/src/modals/ExecuteContract/executeContract.test.js index 8d9e4ccca..ac1138a17 100644 --- a/js/src/modals/ExecuteContract/executeContract.test.js +++ b/js/src/modals/ExecuteContract/executeContract.test.js @@ -68,13 +68,13 @@ const STORE = { }; function createApi (result = true) { + const sha3 = sinon.stub().resolves('0x0000000000000000000000000000000000000000'); + sha3.text = sha3; return { parity: { registryAddress: sinon.stub().resolves('0x0000000000000000000000000000000000000000') }, - util: { - sha3: sinon.stub().resolves('0x0000000000000000000000000000000000000000') - } + util: { sha3 } }; } diff --git a/js/src/modals/Verification/email-store.js b/js/src/modals/Verification/email-store.js index a12d1968d..5360ad611 100644 --- a/js/src/modals/Verification/email-store.js +++ b/js/src/modals/Verification/email-store.js @@ -59,7 +59,7 @@ export default class EmailVerificationStore extends VerificationStore { super(api, EmailVerificationABI, EMAIL_VERIFICATION, account, isTestnet); } - requestValues = () => [ sha3(this.email) ] + requestValues = () => [ sha3.text(this.email) ] @action setEmail = (email) => { this.email = email; diff --git a/js/src/modals/Verification/store.js b/js/src/modals/Verification/store.js index 9d6680231..06250fd76 100644 --- a/js/src/modals/Verification/store.js +++ b/js/src/modals/Verification/store.js @@ -120,7 +120,7 @@ export default class VerificationStore { const confirm = contract.functions.find((fn) => fn.name === 'confirm'); const options = { from: account }; - const values = [ sha3(code) ]; + const values = [ sha3.text(code) ]; this.code = code; this.isCodeValid = null; @@ -192,7 +192,7 @@ export default class VerificationStore { @action sendConfirmation = () => { const { api, account, contract, code } = this; - const token = sha3(code); + const token = sha3.text(code); const confirm = contract.functions.find((fn) => fn.name === 'confirm'); const options = { from: account }; diff --git a/js/src/ui/Form/AddressSelect/addressSelectStore.js b/js/src/ui/Form/AddressSelect/addressSelectStore.js index bdb7c1fb2..e04f8b55d 100644 --- a/js/src/ui/Form/AddressSelect/addressSelectStore.js +++ b/js/src/ui/Form/AddressSelect/addressSelectStore.js @@ -85,7 +85,7 @@ export default class AddressSelectStore { return emailVerification .instance .reverse - .call({}, [ sha3(email) ]) + .call({}, [ sha3.text(email) ]) .then((address) => { return { address, @@ -109,7 +109,7 @@ export default class AddressSelectStore { this.regLookups.push((name) => { return registryInstance .getAddress - .call({}, [ sha3(name), 'A' ]) + .call({}, [ sha3.text(name), 'A' ]) .then((address) => { return { address, diff --git a/js/src/views/Settings/Background/background.js b/js/src/views/Settings/Background/background.js index 48f3a49ec..ebf3c7a96 100644 --- a/js/src/views/Settings/Background/background.js +++ b/js/src/views/Settings/Background/background.js @@ -141,7 +141,7 @@ class Background extends Component { generateSeed () { const { api, muiTheme } = this.context; - return api.util.sha3(`${muiTheme.backgroundSeed}${Math.random()}${counter++}`); + return api.util.sha3.text(`${muiTheme.backgroundSeed}${Math.random()}${counter++}`); } }