Auto-detect hex encoded bytes in sha3 (#4108)

* Auto-detect hex encoded bytes in sha3

* Using types/isHex

* Removing unused imports
This commit is contained in:
Tomasz Drwięga 2017-01-10 18:56:56 +01:00 committed by Gav Wood
parent 23feb7998f
commit 7aa2af3e21
14 changed files with 40 additions and 16 deletions

View File

@ -17,9 +17,12 @@
import { keccak_256 } from 'js-sha3'; // eslint-disable-line import { keccak_256 } from 'js-sha3'; // eslint-disable-line
import { hexToBytes } from './format'; import { hexToBytes } from './format';
import { isHex } from './types';
export function sha3 (value, options) { 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); const bytes = hexToBytes(value);
return sha3(bytes); return sha3(bytes);
} }
@ -28,3 +31,5 @@ export function sha3 (value, options) {
return `0x${hash}`; return `0x${hash}`;
} }
sha3.text = (val) => sha3(val, { encoding: 'raw' });

View File

@ -32,5 +32,14 @@ describe('api/util/sha3', () => {
expect(sha3('01020304', { encoding: 'hex' })).to.equal('0xa6885b3731702da62e8e4a8f584ac46a7f6822f4e2ba50fba902f67b1588d23b'); expect(sha3('01020304', { encoding: 'hex' })).to.equal('0xa6885b3731702da62e8e4a8f584ac46a7f6822f4e2ba50fba902f67b1588d23b');
expect(sha3(Uint8Array.from([1, 2, 3, 4]))).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');
});
}); });
}); });

View File

@ -29,6 +29,10 @@ export function isFunction (test) {
} }
export function isHex (_test) { export function isHex (_test) {
if (!isString(_test)) {
return false;
}
if (_test.substr(0, 2) === '0x') { if (_test.substr(0, 2) === '0x') {
return isHex(_test.slice(2)); return isHex(_test.slice(2));
} }

View File

@ -66,6 +66,12 @@ describe('api/util/types', () => {
it('correctly identifies non-hex values', () => { it('correctly identifies non-hex values', () => {
expect(isHex('123j')).to.be.false; 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', () => { describe('isInstanceOf', () => {

View File

@ -91,7 +91,7 @@ export default class Registry {
lookupAddress (_name) { lookupAddress (_name) {
const name = _name.toLowerCase(); 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 this.getInstance().then((instance) => {
return instance.getAddress.call({}, [sha3, 'A']); return instance.getAddress.call({}, [sha3, 'A']);

View File

@ -39,7 +39,7 @@ export const lookup = (name, key) => (dispatch, getState) => {
name = name.toLowerCase(); name = name.toLowerCase();
dispatch(lookupStart(name, key)); dispatch(lookupStart(name, key));
getAddress.call({}, [ sha3(name), key ]) getAddress.call({}, [ sha3.text(name), key ])
.then((address) => dispatch(success('lookup', address))) .then((address) => dispatch(success('lookup', address)))
.catch((err) => { .catch((err) => {
console.error(`could not lookup ${key} for ${name}`); console.error(`could not lookup ${key} for ${name}`);

View File

@ -62,7 +62,7 @@ export const reserve = (name) => (dispatch, getState) => {
value: fee value: fee
}; };
const values = [ const values = [
sha3(name) sha3.text(name)
]; ];
return postTx(api, reserve, options, values); return postTx(api, reserve, options, values);
@ -116,7 +116,7 @@ export const drop = (name) => (dispatch, getState) => {
}; };
const values = [ const values = [
sha3(name) sha3.text(name)
]; ];
return postTx(api, drop, options, values); return postTx(api, drop, options, values);

View File

@ -54,7 +54,7 @@ export const update = (name, key, value) => (dispatch, getState) => {
}; };
const values = [ const values = [
sha3(name), sha3.text(name),
key, key,
value value
]; ];

View File

@ -17,7 +17,7 @@
export const getOwner = (contract, name) => { export const getOwner = (contract, name) => {
const { address, api } = contract; 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' }); const position = api.util.sha3(key, { encoding: 'hex' });
return api return api

View File

@ -68,13 +68,13 @@ const STORE = {
}; };
function createApi (result = true) { function createApi (result = true) {
const sha3 = sinon.stub().resolves('0x0000000000000000000000000000000000000000');
sha3.text = sha3;
return { return {
parity: { parity: {
registryAddress: sinon.stub().resolves('0x0000000000000000000000000000000000000000') registryAddress: sinon.stub().resolves('0x0000000000000000000000000000000000000000')
}, },
util: { util: { sha3 }
sha3: sinon.stub().resolves('0x0000000000000000000000000000000000000000')
}
}; };
} }

View File

@ -59,7 +59,7 @@ export default class EmailVerificationStore extends VerificationStore {
super(api, EmailVerificationABI, EMAIL_VERIFICATION, account, isTestnet); super(api, EmailVerificationABI, EMAIL_VERIFICATION, account, isTestnet);
} }
requestValues = () => [ sha3(this.email) ] requestValues = () => [ sha3.text(this.email) ]
@action setEmail = (email) => { @action setEmail = (email) => {
this.email = email; this.email = email;

View File

@ -120,7 +120,7 @@ export default class VerificationStore {
const confirm = contract.functions.find((fn) => fn.name === 'confirm'); const confirm = contract.functions.find((fn) => fn.name === 'confirm');
const options = { from: account }; const options = { from: account };
const values = [ sha3(code) ]; const values = [ sha3.text(code) ];
this.code = code; this.code = code;
this.isCodeValid = null; this.isCodeValid = null;
@ -192,7 +192,7 @@ export default class VerificationStore {
@action sendConfirmation = () => { @action sendConfirmation = () => {
const { api, account, contract, code } = this; 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 confirm = contract.functions.find((fn) => fn.name === 'confirm');
const options = { from: account }; const options = { from: account };

View File

@ -85,7 +85,7 @@ export default class AddressSelectStore {
return emailVerification return emailVerification
.instance .instance
.reverse .reverse
.call({}, [ sha3(email) ]) .call({}, [ sha3.text(email) ])
.then((address) => { .then((address) => {
return { return {
address, address,
@ -109,7 +109,7 @@ export default class AddressSelectStore {
this.regLookups.push((name) => { this.regLookups.push((name) => {
return registryInstance return registryInstance
.getAddress .getAddress
.call({}, [ sha3(name), 'A' ]) .call({}, [ sha3.text(name), 'A' ])
.then((address) => { .then((address) => {
return { return {
address, address,

View File

@ -141,7 +141,7 @@ class Background extends Component {
generateSeed () { generateSeed () {
const { api, muiTheme } = this.context; const { api, muiTheme } = this.context;
return api.util.sha3(`${muiTheme.backgroundSeed}${Math.random()}${counter++}`); return api.util.sha3.text(`${muiTheme.backgroundSeed}${Math.random()}${counter++}`);
} }
} }