Skip to content
This repository has been archived by the owner on Nov 6, 2020. It is now read-only.

Commit

Permalink
Add ownership checks the Registry dApp (#4001)
Browse files Browse the repository at this point in the history
* Fixes to the Registry dApp

* WIP Add Owner Lookup

* Proper sha3 implementation

* Add working owner lookup to reg dApp

* Add errors to Name Reg

* Add records error in Reg dApp

* Add errors for reverse in reg dApp

* PR Grumbles
  • Loading branch information
ngotchac authored and jacogr committed Jan 4, 2017
1 parent 4c532f9 commit 6301726
Show file tree
Hide file tree
Showing 26 changed files with 574 additions and 218 deletions.
1 change: 1 addition & 0 deletions js/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@
"blockies": "0.0.2",
"brace": "0.9.0",
"bytes": "2.4.0",
"crypto-js": "3.1.9-1",
"debounce": "1.0.0",
"es6-error": "4.0.0",
"es6-promise": "4.0.5",
Expand Down
19 changes: 16 additions & 3 deletions js/src/api/util/sha3.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,21 @@
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.

import { keccak_256 } from 'js-sha3'; // eslint-disable-line camelcase
import CryptoJS from 'crypto-js';
import CryptoSha3 from 'crypto-js/sha3';

export function sha3 (value) {
return `0x${keccak_256(value)}`;
export function sha3 (value, options) {
if (options && options.encoding === 'hex') {
if (value.length > 2 && value.substr(0, 2) === '0x') {
value = value.substr(2);
}

value = CryptoJS.enc.Hex.parse(value);
}

const hash = CryptoSha3(value, {
outputLength: 256
}).toString();

return `0x${hash}`;
}
13 changes: 13 additions & 0 deletions js/src/dapps/registry.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,16 @@ ReactDOM.render(
</Provider>,
document.querySelector('#container')
);

if (module.hot) {
module.hot.accept('./registry/Container', () => {
require('./registry/Container');

ReactDOM.render(
<Provider store={ store }>
<Container />
</Provider>,
document.querySelector('#container')
);
});
}
4 changes: 2 additions & 2 deletions js/src/dapps/registry/Application/application.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,8 @@ export default class Application extends Component {

static propTypes = {
accounts: PropTypes.object.isRequired,
contract: nullableProptype(PropTypes.object).isRequired,
fee: nullableProptype(PropTypes.object).isRequired
contract: nullableProptype(PropTypes.object.isRequired),
fee: nullableProptype(PropTypes.object.isRequired)
};

render () {
Expand Down
44 changes: 36 additions & 8 deletions js/src/dapps/registry/Lookup/actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,13 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>.

import { sha3 } from '../parity.js';
import { getOwner } from '../util/registry';

export const clear = () => ({ type: 'lookup clear' });

export const lookupStart = (name, key) => ({ type: 'lookup start', name, key });
export const reverseLookupStart = (address) => ({ type: 'reverseLookup start', address });
export const ownerLookupStart = (name) => ({ type: 'ownerLookup start', name });

export const success = (action, result) => ({ type: `${action} success`, result: result });

Expand Down Expand Up @@ -48,24 +50,50 @@ export const lookup = (name, key) => (dispatch, getState) => {
});
};

export const reverseLookup = (address) => (dispatch, getState) => {
export const reverseLookup = (lookupAddress) => (dispatch, getState) => {
const { contract } = getState();

if (!contract) {
return;
}

const reverse = contract.functions
.find((f) => f.name === 'reverse');

dispatch(reverseLookupStart(address));
dispatch(reverseLookupStart(lookupAddress));

reverse.call({}, [ address ])
.then((address) => dispatch(success('reverseLookup', address)))
contract.instance
.reverse
.call({}, [ lookupAddress ])
.then((address) => {
dispatch(success('reverseLookup', address));
})
.catch((err) => {
console.error(`could not lookup reverse for ${address}`);
console.error(`could not lookup reverse for ${lookupAddress}`);
if (err) {
console.error(err.stack);
}
dispatch(fail('reverseLookup'));
});
};

export const ownerLookup = (name) => (dispatch, getState) => {
const { contract } = getState();

if (!contract) {
return;
}

dispatch(ownerLookupStart(name));

return getOwner(contract, name)
.then((owner) => {
dispatch(success('ownerLookup', owner));
})
.catch((err) => {
console.error(`could not lookup owner for ${name}`);

if (err) {
console.error(err.stack);
}

dispatch(fail('ownerLookup'));
});
};
116 changes: 80 additions & 36 deletions js/src/dapps/registry/Lookup/lookup.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,14 @@ import DropDownMenu from 'material-ui/DropDownMenu';
import MenuItem from 'material-ui/MenuItem';
import RaisedButton from 'material-ui/RaisedButton';
import SearchIcon from 'material-ui/svg-icons/action/search';
import keycode from 'keycode';

import { nullableProptype } from '~/util/proptypes';

import Address from '../ui/address.js';
import renderImage from '../ui/image.js';

import { clear, lookup, reverseLookup } from './actions';
import { clear, lookup, ownerLookup, reverseLookup } from './actions';
import styles from './lookup.css';

class Lookup extends Component {
Expand All @@ -39,6 +40,7 @@ class Lookup extends Component {

clear: PropTypes.func.isRequired,
lookup: PropTypes.func.isRequired,
ownerLookup: PropTypes.func.isRequired,
reverseLookup: PropTypes.func.isRequired
}

Expand All @@ -50,33 +52,6 @@ class Lookup extends Component {
const { input, type } = this.state;
const { result } = this.props;

let output = '';
if (result) {
if (type === 'A') {
output = (
<code>
<Address
address={ result }
shortenHash={ false }
/>
</code>
);
} else if (type === 'IMG') {
output = renderImage(result);
} else if (type === 'CONTENT') {
output = (
<div>
<code>{ result }</code>
<p>Keep in mind that this is most likely the hash of the content you are looking for.</p>
</div>
);
} else {
output = (
<code>{ result }</code>
);
}
}

return (
<Card className={ styles.lookup }>
<CardHeader title={ 'Query the Registry' } />
Expand All @@ -85,6 +60,7 @@ class Lookup extends Component {
hintText={ type === 'reverse' ? 'address' : 'name' }
value={ input }
onChange={ this.onInputChange }
onKeyDown={ this.onKeyDown }
/>
<DropDownMenu
value={ type }
Expand All @@ -94,6 +70,7 @@ class Lookup extends Component {
<MenuItem value='IMG' primaryText='IMG – hash of a picture in the blockchain' />
<MenuItem value='CONTENT' primaryText='CONTENT – hash of a data in the blockchain' />
<MenuItem value='reverse' primaryText='reverse – find a name for an address' />
<MenuItem value='owner' primaryText='owner – find a the owner' />
</DropDownMenu>
<RaisedButton
label='Lookup'
Expand All @@ -102,35 +79,102 @@ class Lookup extends Component {
onTouchTap={ this.onLookupClick }
/>
</div>
<CardText>{ output }</CardText>
<CardText>
{ this.renderOutput(type, result) }
</CardText>
</Card>
);
}

renderOutput (type, result) {
if (result === null) {
return null;
}

if (type === 'A') {
return (
<code>
<Address
address={ result }
shortenHash={ false }
/>
</code>
);
}

if (type === 'owner') {
if (!result) {
return (
<code>Not reserved yet</code>
);
}

return (
<code>
<Address
address={ result }
shortenHash={ false }
/>
</code>
);
}

if (type === 'IMG') {
return renderImage(result);
}

if (type === 'CONTENT') {
return (
<div>
<code>{ result }</code>
<p>Keep in mind that this is most likely the hash of the content you are looking for.</p>
</div>
);
}

return (
<code>{ result || 'No data' }</code>
);
}

onInputChange = (e) => {
this.setState({ input: e.target.value });
};
}

onKeyDown = (event) => {
const codeName = keycode(event);

if (codeName !== 'enter') {
return;
}

this.onLookupClick();
}

onTypeChange = (e, i, type) => {
this.setState({ type });
this.props.clear();
};
}

onLookupClick = () => {
const { input, type } = this.state;

if (type === 'reverse') {
this.props.reverseLookup(input);
} else {
this.props.lookup(input, type);
return this.props.reverseLookup(input);
}
};

if (type === 'owner') {
return this.props.ownerLookup(input);
}

return this.props.lookup(input, type);
}
}

const mapStateToProps = (state) => state.lookup;
const mapDispatchToProps = (dispatch) =>
bindActionCreators({
clear, lookup, reverseLookup
clear, lookup, ownerLookup, reverseLookup
}, dispatch);

export default connect(mapStateToProps, mapDispatchToProps)(Lookup);
2 changes: 1 addition & 1 deletion js/src/dapps/registry/Lookup/reducers.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ const initialState = {
export default (state = initialState, action) => {
const { type } = action;

if (type.slice(0, 7) !== 'lookup ' && type.slice(0, 14) !== 'reverseLookup ') {
if (!/^(lookup|reverseLookup|ownerLookup)/.test(type)) {
return state;
}

Expand Down
Loading

0 comments on commit 6301726

Please sign in to comment.