Merge pull request #3430 from ethcore/ng-array-parameters
Handle contract constructor inputs
This commit is contained in:
		
						commit
						28f11be200
					
				@ -46,7 +46,8 @@ function stringToBytes (input) {
 | 
				
			|||||||
  if (isArray(input)) {
 | 
					  if (isArray(input)) {
 | 
				
			||||||
    return input;
 | 
					    return input;
 | 
				
			||||||
  } else if (input.substr(0, 2) === '0x') {
 | 
					  } else if (input.substr(0, 2) === '0x') {
 | 
				
			||||||
    return input.substr(2).toLowerCase().match(/.{1,2}/g).map((value) => parseInt(value, 16));
 | 
					    const matches = input.substr(2).toLowerCase().match(/.{1,2}/g) || [];
 | 
				
			||||||
 | 
					    return matches.map((value) => parseInt(value, 16));
 | 
				
			||||||
  } else {
 | 
					  } else {
 | 
				
			||||||
    return input.split('').map((char) => char.charCodeAt(0));
 | 
					    return input.split('').map((char) => char.charCodeAt(0));
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
				
			|||||||
@ -15,10 +15,10 @@
 | 
				
			|||||||
// along with Parity.  If not, see <http://www.gnu.org/licenses/>.
 | 
					// along with Parity.  If not, see <http://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import React, { Component, PropTypes } from 'react';
 | 
					import React, { Component, PropTypes } from 'react';
 | 
				
			||||||
import { MenuItem } from 'material-ui';
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
import { AddressSelect, Form, Input, InputAddressSelect, Select } from '../../../ui';
 | 
					import { AddressSelect, Form, Input, TypedInput } from '../../../ui';
 | 
				
			||||||
import { validateAbi } from '../../../util/validation';
 | 
					import { validateAbi } from '../../../util/validation';
 | 
				
			||||||
 | 
					import { parseAbiType } from '../../../util/abi';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import styles from '../deployContract.css';
 | 
					import styles from '../deployContract.css';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -103,6 +103,7 @@ export default class DetailsStep extends Component {
 | 
				
			|||||||
          value={ code }
 | 
					          value={ code }
 | 
				
			||||||
          onSubmit={ this.onCodeChange }
 | 
					          onSubmit={ this.onCodeChange }
 | 
				
			||||||
          readOnly={ readOnly } />
 | 
					          readOnly={ readOnly } />
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        { this.renderConstructorInputs() }
 | 
					        { this.renderConstructorInputs() }
 | 
				
			||||||
      </Form>
 | 
					      </Form>
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
@ -117,59 +118,23 @@ export default class DetailsStep extends Component {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return inputs.map((input, index) => {
 | 
					    return inputs.map((input, index) => {
 | 
				
			||||||
      const onChange = (event, value) => this.onParamChange(index, value);
 | 
					      const onChange = (value) => this.onParamChange(index, value);
 | 
				
			||||||
      const onChangeBool = (event, _index, value) => this.onParamChange(index, value === 'true');
 | 
					 | 
				
			||||||
      const onSubmit = (value) => this.onParamChange(index, value);
 | 
					 | 
				
			||||||
      const label = `${input.name}: ${input.type}`;
 | 
					 | 
				
			||||||
      let inputBox = null;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
      switch (input.type) {
 | 
					      const label = `${input.name ? `${input.name}: ` : ''}${input.type}`;
 | 
				
			||||||
        case 'address':
 | 
					      const value = params[index];
 | 
				
			||||||
          inputBox = (
 | 
					      const error = paramsError[index];
 | 
				
			||||||
            <InputAddressSelect
 | 
					      const param = parseAbiType(input.type);
 | 
				
			||||||
              accounts={ accounts }
 | 
					 | 
				
			||||||
              editing
 | 
					 | 
				
			||||||
              label={ label }
 | 
					 | 
				
			||||||
              value={ params[index] }
 | 
					 | 
				
			||||||
              error={ paramsError[index] }
 | 
					 | 
				
			||||||
              onChange={ onChange } />
 | 
					 | 
				
			||||||
          );
 | 
					 | 
				
			||||||
          break;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        case 'bool':
 | 
					 | 
				
			||||||
          const boolitems = ['false', 'true'].map((bool) => {
 | 
					 | 
				
			||||||
            return (
 | 
					 | 
				
			||||||
              <MenuItem
 | 
					 | 
				
			||||||
                key={ bool }
 | 
					 | 
				
			||||||
                value={ bool }
 | 
					 | 
				
			||||||
                label={ bool }>{ bool }</MenuItem>
 | 
					 | 
				
			||||||
            );
 | 
					 | 
				
			||||||
          });
 | 
					 | 
				
			||||||
          inputBox = (
 | 
					 | 
				
			||||||
            <Select
 | 
					 | 
				
			||||||
              label={ label }
 | 
					 | 
				
			||||||
              value={ params[index] ? 'true' : 'false' }
 | 
					 | 
				
			||||||
              error={ paramsError[index] }
 | 
					 | 
				
			||||||
              onChange={ onChangeBool }>
 | 
					 | 
				
			||||||
              { boolitems }
 | 
					 | 
				
			||||||
            </Select>
 | 
					 | 
				
			||||||
          );
 | 
					 | 
				
			||||||
          break;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        default:
 | 
					 | 
				
			||||||
          inputBox = (
 | 
					 | 
				
			||||||
            <Input
 | 
					 | 
				
			||||||
              label={ label }
 | 
					 | 
				
			||||||
              value={ params[index] }
 | 
					 | 
				
			||||||
              error={ paramsError[index] }
 | 
					 | 
				
			||||||
              onSubmit={ onSubmit } />
 | 
					 | 
				
			||||||
            );
 | 
					 | 
				
			||||||
          break;
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
      return (
 | 
					      return (
 | 
				
			||||||
        <div key={ index } className={ styles.funcparams }>
 | 
					        <div key={ index } className={ styles.funcparams }>
 | 
				
			||||||
          { inputBox }
 | 
					          <TypedInput
 | 
				
			||||||
 | 
					            label={ label }
 | 
				
			||||||
 | 
					            value={ value }
 | 
				
			||||||
 | 
					            error={ error }
 | 
				
			||||||
 | 
					            accounts={ accounts }
 | 
				
			||||||
 | 
					            onChange={ onChange }
 | 
				
			||||||
 | 
					            param={ param }
 | 
				
			||||||
 | 
					          />
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
      );
 | 
					      );
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
@ -200,35 +165,14 @@ export default class DetailsStep extends Component {
 | 
				
			|||||||
    const { abiError, abiParsed } = validateAbi(abi, api);
 | 
					    const { abiError, abiParsed } = validateAbi(abi, api);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (!abiError) {
 | 
					    if (!abiError) {
 | 
				
			||||||
      const { inputs } = abiParsed.find((method) => method.type === 'constructor') || { inputs: [] };
 | 
					      const { inputs } = abiParsed
 | 
				
			||||||
 | 
					        .find((method) => method.type === 'constructor') || { inputs: [] };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      const params = [];
 | 
					      const params = [];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      inputs.forEach((input) => {
 | 
					      inputs.forEach((input) => {
 | 
				
			||||||
        switch (input.type) {
 | 
					        const param = parseAbiType(input.type);
 | 
				
			||||||
          case 'address':
 | 
					        params.push(param.default);
 | 
				
			||||||
            params.push('0x');
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
          case 'bool':
 | 
					 | 
				
			||||||
            params.push(false);
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
          case 'bytes':
 | 
					 | 
				
			||||||
            params.push('0x');
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
          case 'uint':
 | 
					 | 
				
			||||||
            params.push('0');
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
          case 'string':
 | 
					 | 
				
			||||||
            params.push('');
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
          default:
 | 
					 | 
				
			||||||
            params.push('0');
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      });
 | 
					      });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      onParamsChange(params);
 | 
					      onParamsChange(params);
 | 
				
			||||||
 | 
				
			|||||||
@ -101,7 +101,8 @@ export default class DeployContract extends Component {
 | 
				
			|||||||
        steps={ deployError ? null : steps }
 | 
					        steps={ deployError ? null : steps }
 | 
				
			||||||
        title={ deployError ? 'deployment failed' : null }
 | 
					        title={ deployError ? 'deployment failed' : null }
 | 
				
			||||||
        waiting={ [1] }
 | 
					        waiting={ [1] }
 | 
				
			||||||
        visible>
 | 
					        visible
 | 
				
			||||||
 | 
					        scroll>
 | 
				
			||||||
        { this.renderStep() }
 | 
					        { this.renderStep() }
 | 
				
			||||||
      </Modal>
 | 
					      </Modal>
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
@ -118,8 +119,22 @@ export default class DeployContract extends Component {
 | 
				
			|||||||
        onClick={ this.onClose } />
 | 
					        onClick={ this.onClose } />
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const closeBtn = (
 | 
				
			||||||
 | 
					      <Button
 | 
				
			||||||
 | 
					        icon={ <ContentClear /> }
 | 
				
			||||||
 | 
					        label='Close'
 | 
				
			||||||
 | 
					        onClick={ this.onClose } />
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const closeBtnOk = (
 | 
				
			||||||
 | 
					      <Button
 | 
				
			||||||
 | 
					        icon={ <ActionDoneAll /> }
 | 
				
			||||||
 | 
					        label='Close'
 | 
				
			||||||
 | 
					        onClick={ this.onClose } />
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (deployError) {
 | 
					    if (deployError) {
 | 
				
			||||||
      return cancelBtn;
 | 
					      return closeBtn;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    switch (step) {
 | 
					    switch (step) {
 | 
				
			||||||
@ -134,17 +149,10 @@ export default class DeployContract extends Component {
 | 
				
			|||||||
        ];
 | 
					        ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      case 1:
 | 
					      case 1:
 | 
				
			||||||
        return [
 | 
					        return [ closeBtn ];
 | 
				
			||||||
          cancelBtn
 | 
					 | 
				
			||||||
        ];
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
      case 2:
 | 
					      case 2:
 | 
				
			||||||
        return [
 | 
					        return [ closeBtnOk ];
 | 
				
			||||||
          <Button
 | 
					 | 
				
			||||||
            icon={ <ActionDoneAll /> }
 | 
					 | 
				
			||||||
            label='Close'
 | 
					 | 
				
			||||||
            onClick={ this.onClose } />
 | 
					 | 
				
			||||||
        ];
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -277,8 +285,6 @@ export default class DeployContract extends Component {
 | 
				
			|||||||
      return;
 | 
					      return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    console.log('onDeploymentState', data);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    switch (data.state) {
 | 
					    switch (data.state) {
 | 
				
			||||||
      case 'estimateGas':
 | 
					      case 'estimateGas':
 | 
				
			||||||
      case 'postTransaction':
 | 
					      case 'postTransaction':
 | 
				
			||||||
 | 
				
			|||||||
@ -39,6 +39,10 @@
 | 
				
			|||||||
  position: absolute;
 | 
					  position: absolute;
 | 
				
			||||||
  left: 0;
 | 
					  left: 0;
 | 
				
			||||||
  top: 35px;
 | 
					  top: 35px;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  &.noLabel {
 | 
				
			||||||
 | 
					    top: 11px;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.paddedInput input {
 | 
					.paddedInput input {
 | 
				
			||||||
 | 
				
			|||||||
@ -106,15 +106,21 @@ export default class AddressSelect extends Component {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  renderIdentityIcon (inputValue) {
 | 
					  renderIdentityIcon (inputValue) {
 | 
				
			||||||
    const { error, value } = this.props;
 | 
					    const { error, value, label } = this.props;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (error || !inputValue || value.length !== 42) {
 | 
					    if (error || !inputValue || value.length !== 42) {
 | 
				
			||||||
      return null;
 | 
					      return null;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const classes = [ styles.icon ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!label) {
 | 
				
			||||||
 | 
					      classes.push(styles.noLabel);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return (
 | 
					    return (
 | 
				
			||||||
      <IdentityIcon
 | 
					      <IdentityIcon
 | 
				
			||||||
        className={ styles.icon }
 | 
					        className={ classes.join(' ') }
 | 
				
			||||||
        inline center
 | 
					        inline center
 | 
				
			||||||
        address={ value } />
 | 
					        address={ value } />
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
 | 
				
			|||||||
@ -63,7 +63,9 @@ export default class Input extends Component {
 | 
				
			|||||||
    hideUnderline: PropTypes.bool,
 | 
					    hideUnderline: PropTypes.bool,
 | 
				
			||||||
    value: PropTypes.oneOfType([
 | 
					    value: PropTypes.oneOfType([
 | 
				
			||||||
      PropTypes.number, PropTypes.string
 | 
					      PropTypes.number, PropTypes.string
 | 
				
			||||||
    ])
 | 
					    ]),
 | 
				
			||||||
 | 
					    min: PropTypes.any,
 | 
				
			||||||
 | 
					    max: PropTypes.any
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  static defaultProps = {
 | 
					  static defaultProps = {
 | 
				
			||||||
@ -86,7 +88,7 @@ export default class Input extends Component {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  render () {
 | 
					  render () {
 | 
				
			||||||
    const { value } = this.state;
 | 
					    const { value } = this.state;
 | 
				
			||||||
    const { children, className, hideUnderline, disabled, error, label, hint, multiLine, rows, type } = this.props;
 | 
					    const { children, className, hideUnderline, disabled, error, label, hint, multiLine, rows, type, min, max } = this.props;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const readOnly = this.props.readOnly || disabled;
 | 
					    const readOnly = this.props.readOnly || disabled;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -130,6 +132,8 @@ export default class Input extends Component {
 | 
				
			|||||||
          onChange={ this.onChange }
 | 
					          onChange={ this.onChange }
 | 
				
			||||||
          onKeyDown={ this.onKeyDown }
 | 
					          onKeyDown={ this.onKeyDown }
 | 
				
			||||||
          inputStyle={ inputStyle }
 | 
					          inputStyle={ inputStyle }
 | 
				
			||||||
 | 
					          min={ min }
 | 
				
			||||||
 | 
					          max={ max }
 | 
				
			||||||
        >
 | 
					        >
 | 
				
			||||||
          { children }
 | 
					          { children }
 | 
				
			||||||
        </TextField>
 | 
					        </TextField>
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										17
									
								
								js/src/ui/Form/TypedInput/index.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								js/src/ui/Form/TypedInput/index.js
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,17 @@
 | 
				
			|||||||
 | 
					// Copyright 2015, 2016 Ethcore (UK) Ltd.
 | 
				
			||||||
 | 
					// This file is part of Parity.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Parity is free software: you can redistribute it and/or modify
 | 
				
			||||||
 | 
					// it under the terms of the GNU General Public License as published by
 | 
				
			||||||
 | 
					// the Free Software Foundation, either version 3 of the License, or
 | 
				
			||||||
 | 
					// (at your option) any later version.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Parity is distributed in the hope that it will be useful,
 | 
				
			||||||
 | 
					// but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
 | 
					// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
				
			||||||
 | 
					// GNU General Public License for more details.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// You should have received a copy of the GNU General Public License
 | 
				
			||||||
 | 
					// along with Parity.  If not, see <http://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default from './typedInput';
 | 
				
			||||||
							
								
								
									
										31
									
								
								js/src/ui/Form/TypedInput/typedInput.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								js/src/ui/Form/TypedInput/typedInput.css
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,31 @@
 | 
				
			|||||||
 | 
					/* Copyright 2015, 2016 Ethcore (UK) Ltd.
 | 
				
			||||||
 | 
					/* This file is part of Parity.
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					/* Parity is free software: you can redistribute it and/or modify
 | 
				
			||||||
 | 
					/* it under the terms of the GNU General Public License as published by
 | 
				
			||||||
 | 
					/* the Free Software Foundation, either version 3 of the License, or
 | 
				
			||||||
 | 
					/* (at your option) any later version.
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					/* Parity is distributed in the hope that it will be useful,
 | 
				
			||||||
 | 
					/* but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
 | 
					/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
				
			||||||
 | 
					/* GNU General Public License for more details.
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					/* You should have received a copy of the GNU General Public License
 | 
				
			||||||
 | 
					/* along with Parity.  If not, see <http://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.inputs {
 | 
				
			||||||
 | 
					  padding-top: 2px;
 | 
				
			||||||
 | 
					  overflow-x: hidden;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  label {
 | 
				
			||||||
 | 
					    line-height: 22px;
 | 
				
			||||||
 | 
					    pointer-events: none;
 | 
				
			||||||
 | 
					    color: rgba(255, 255, 255, 0.498039);
 | 
				
			||||||
 | 
					    -webkit-user-select: none;
 | 
				
			||||||
 | 
					    font-size: 12px;
 | 
				
			||||||
 | 
					    top: 11px;
 | 
				
			||||||
 | 
					    position: relative;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										239
									
								
								js/src/ui/Form/TypedInput/typedInput.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										239
									
								
								js/src/ui/Form/TypedInput/typedInput.js
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,239 @@
 | 
				
			|||||||
 | 
					// Copyright 2015, 2016 Ethcore (UK) Ltd.
 | 
				
			||||||
 | 
					// This file is part of Parity.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Parity is free software: you can redistribute it and/or modify
 | 
				
			||||||
 | 
					// it under the terms of the GNU General Public License as published by
 | 
				
			||||||
 | 
					// the Free Software Foundation, either version 3 of the License, or
 | 
				
			||||||
 | 
					// (at your option) any later version.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Parity is distributed in the hope that it will be useful,
 | 
				
			||||||
 | 
					// but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
 | 
					// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
				
			||||||
 | 
					// GNU General Public License for more details.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// You should have received a copy of the GNU General Public License
 | 
				
			||||||
 | 
					// along with Parity.  If not, see <http://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import React, { Component, PropTypes } from 'react';
 | 
				
			||||||
 | 
					import { MenuItem } from 'material-ui';
 | 
				
			||||||
 | 
					import { range } from 'lodash';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import IconButton from 'material-ui/IconButton';
 | 
				
			||||||
 | 
					import AddIcon from 'material-ui/svg-icons/content/add';
 | 
				
			||||||
 | 
					import RemoveIcon from 'material-ui/svg-icons/content/remove';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import { Input, InputAddressSelect, Select } from '../../../ui';
 | 
				
			||||||
 | 
					import { ABI_TYPES } from '../../../util/abi';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import styles from './typedInput.css';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default class TypedInput extends Component {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static propTypes = {
 | 
				
			||||||
 | 
					    onChange: PropTypes.func.isRequired,
 | 
				
			||||||
 | 
					    accounts: PropTypes.object.isRequired,
 | 
				
			||||||
 | 
					    param: PropTypes.object.isRequired,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    error: PropTypes.any,
 | 
				
			||||||
 | 
					    value: PropTypes.any,
 | 
				
			||||||
 | 
					    label: PropTypes.string
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  render () {
 | 
				
			||||||
 | 
					    const { param } = this.props;
 | 
				
			||||||
 | 
					    const { type } = param;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (type === ABI_TYPES.ARRAY) {
 | 
				
			||||||
 | 
					      const { accounts, label, value = param.default } = this.props;
 | 
				
			||||||
 | 
					      const { subtype, length } = param;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      const fixedLength = !!length;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      const inputs = range(length || value.length).map((_, index) => {
 | 
				
			||||||
 | 
					        const onChange = (inputValue) => {
 | 
				
			||||||
 | 
					          const newValues = [].concat(this.props.value);
 | 
				
			||||||
 | 
					          newValues[index] = inputValue;
 | 
				
			||||||
 | 
					          this.props.onChange(newValues);
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return (
 | 
				
			||||||
 | 
					          <TypedInput
 | 
				
			||||||
 | 
					            key={ `${subtype.type}_${index}` }
 | 
				
			||||||
 | 
					            onChange={ onChange }
 | 
				
			||||||
 | 
					            accounts={ accounts }
 | 
				
			||||||
 | 
					            param={ subtype }
 | 
				
			||||||
 | 
					            value={ value[index] }
 | 
				
			||||||
 | 
					          />
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      return (
 | 
				
			||||||
 | 
					        <div className={ styles.inputs }>
 | 
				
			||||||
 | 
					          <label>{ label }</label>
 | 
				
			||||||
 | 
					          { fixedLength ? null : this.renderLength() }
 | 
				
			||||||
 | 
					          { inputs }
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					      );
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return this.renderType(type);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  renderLength () {
 | 
				
			||||||
 | 
					    const iconStyle = {
 | 
				
			||||||
 | 
					      width: 16,
 | 
				
			||||||
 | 
					      height: 16
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const style = {
 | 
				
			||||||
 | 
					      width: 32,
 | 
				
			||||||
 | 
					      height: 32,
 | 
				
			||||||
 | 
					      padding: 0
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return (
 | 
				
			||||||
 | 
					      <div>
 | 
				
			||||||
 | 
					        <IconButton
 | 
				
			||||||
 | 
					          iconStyle={ iconStyle }
 | 
				
			||||||
 | 
					          style={ style }
 | 
				
			||||||
 | 
					          onClick={ this.onAddField }
 | 
				
			||||||
 | 
					        >
 | 
				
			||||||
 | 
					          <AddIcon />
 | 
				
			||||||
 | 
					        </IconButton>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        <IconButton
 | 
				
			||||||
 | 
					          iconStyle={ iconStyle }
 | 
				
			||||||
 | 
					          style={ style }
 | 
				
			||||||
 | 
					          onClick={ this.onRemoveField }
 | 
				
			||||||
 | 
					        >
 | 
				
			||||||
 | 
					          <RemoveIcon />
 | 
				
			||||||
 | 
					        </IconButton>
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  renderType (type) {
 | 
				
			||||||
 | 
					    if (type === ABI_TYPES.ADDRESS) {
 | 
				
			||||||
 | 
					      return this.renderAddress();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (type === ABI_TYPES.BOOL) {
 | 
				
			||||||
 | 
					      return this.renderBoolean();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (type === ABI_TYPES.STRING) {
 | 
				
			||||||
 | 
					      return this.renderDefault();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (type === ABI_TYPES.BYTES) {
 | 
				
			||||||
 | 
					      return this.renderDefault();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (type === ABI_TYPES.INT) {
 | 
				
			||||||
 | 
					      return this.renderNumber();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (type === ABI_TYPES.FIXED) {
 | 
				
			||||||
 | 
					      return this.renderNumber();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return this.renderDefault();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  renderNumber () {
 | 
				
			||||||
 | 
					    const { label, value, error, param } = this.props;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return (
 | 
				
			||||||
 | 
					      <Input
 | 
				
			||||||
 | 
					        label={ label }
 | 
				
			||||||
 | 
					        value={ value }
 | 
				
			||||||
 | 
					        error={ error }
 | 
				
			||||||
 | 
					        onSubmit={ this.onSubmit }
 | 
				
			||||||
 | 
					        type='number'
 | 
				
			||||||
 | 
					        min={ param.signed ? null : 0 }
 | 
				
			||||||
 | 
					      />
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  renderDefault () {
 | 
				
			||||||
 | 
					    const { label, value, error } = this.props;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return (
 | 
				
			||||||
 | 
					      <Input
 | 
				
			||||||
 | 
					        label={ label }
 | 
				
			||||||
 | 
					        value={ value }
 | 
				
			||||||
 | 
					        error={ error }
 | 
				
			||||||
 | 
					        onSubmit={ this.onSubmit }
 | 
				
			||||||
 | 
					      />
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  renderAddress () {
 | 
				
			||||||
 | 
					    const { accounts, label, value, error } = this.props;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return (
 | 
				
			||||||
 | 
					      <InputAddressSelect
 | 
				
			||||||
 | 
					        accounts={ accounts }
 | 
				
			||||||
 | 
					        label={ label }
 | 
				
			||||||
 | 
					        value={ value }
 | 
				
			||||||
 | 
					        error={ error }
 | 
				
			||||||
 | 
					        onChange={ this.onChange }
 | 
				
			||||||
 | 
					        editing
 | 
				
			||||||
 | 
					      />
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  renderBoolean () {
 | 
				
			||||||
 | 
					    const { label, value, error } = this.props;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const boolitems = ['false', 'true'].map((bool) => {
 | 
				
			||||||
 | 
					      return (
 | 
				
			||||||
 | 
					        <MenuItem
 | 
				
			||||||
 | 
					          key={ bool }
 | 
				
			||||||
 | 
					          value={ bool }
 | 
				
			||||||
 | 
					          label={ bool }
 | 
				
			||||||
 | 
					        >
 | 
				
			||||||
 | 
					          { bool }
 | 
				
			||||||
 | 
					        </MenuItem>
 | 
				
			||||||
 | 
					      );
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return (
 | 
				
			||||||
 | 
					      <Select
 | 
				
			||||||
 | 
					        label={ label }
 | 
				
			||||||
 | 
					        value={ value ? 'true' : 'false' }
 | 
				
			||||||
 | 
					        error={ error }
 | 
				
			||||||
 | 
					        onChange={ this.onChangeBool }
 | 
				
			||||||
 | 
					      >
 | 
				
			||||||
 | 
					        { boolitems }
 | 
				
			||||||
 | 
					      </Select>
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  onChangeBool = (event, _index, value) => {
 | 
				
			||||||
 | 
					    this.props.onChange(value === 'true');
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  onChange = (event, value) => {
 | 
				
			||||||
 | 
					    this.props.onChange(value);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  onSubmit = (value) => {
 | 
				
			||||||
 | 
					    this.props.onChange(value);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  onAddField = () => {
 | 
				
			||||||
 | 
					    const { value, onChange, param } = this.props;
 | 
				
			||||||
 | 
					    const newValues = [].concat(value, param.subtype.default);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    onChange(newValues);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  onRemoveField = () => {
 | 
				
			||||||
 | 
					    const { value, onChange } = this.props;
 | 
				
			||||||
 | 
					    const newValues = value.slice(0, -1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    onChange(newValues);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -16,6 +16,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import AddressSelect from './AddressSelect';
 | 
					import AddressSelect from './AddressSelect';
 | 
				
			||||||
import FormWrap from './FormWrap';
 | 
					import FormWrap from './FormWrap';
 | 
				
			||||||
 | 
					import TypedInput from './TypedInput';
 | 
				
			||||||
import Input from './Input';
 | 
					import Input from './Input';
 | 
				
			||||||
import InputAddress from './InputAddress';
 | 
					import InputAddress from './InputAddress';
 | 
				
			||||||
import InputAddressSelect from './InputAddressSelect';
 | 
					import InputAddressSelect from './InputAddressSelect';
 | 
				
			||||||
@ -27,6 +28,7 @@ export default from './form';
 | 
				
			|||||||
export {
 | 
					export {
 | 
				
			||||||
  AddressSelect,
 | 
					  AddressSelect,
 | 
				
			||||||
  FormWrap,
 | 
					  FormWrap,
 | 
				
			||||||
 | 
					  TypedInput,
 | 
				
			||||||
  Input,
 | 
					  Input,
 | 
				
			||||||
  InputAddress,
 | 
					  InputAddress,
 | 
				
			||||||
  InputAddressSelect,
 | 
					  InputAddressSelect,
 | 
				
			||||||
 | 
				
			|||||||
@ -29,7 +29,7 @@ import ContextProvider from './ContextProvider';
 | 
				
			|||||||
import CopyToClipboard from './CopyToClipboard';
 | 
					import CopyToClipboard from './CopyToClipboard';
 | 
				
			||||||
import Editor from './Editor';
 | 
					import Editor from './Editor';
 | 
				
			||||||
import Errors from './Errors';
 | 
					import Errors from './Errors';
 | 
				
			||||||
import Form, { AddressSelect, FormWrap, Input, InputAddress, InputAddressSelect, InputChip, InputInline, Select } from './Form';
 | 
					import Form, { AddressSelect, FormWrap, TypedInput, Input, InputAddress, InputAddressSelect, InputChip, InputInline, Select } from './Form';
 | 
				
			||||||
import IdentityIcon from './IdentityIcon';
 | 
					import IdentityIcon from './IdentityIcon';
 | 
				
			||||||
import IdentityName from './IdentityName';
 | 
					import IdentityName from './IdentityName';
 | 
				
			||||||
import MethodDecoding from './MethodDecoding';
 | 
					import MethodDecoding from './MethodDecoding';
 | 
				
			||||||
@ -62,6 +62,7 @@ export {
 | 
				
			|||||||
  Errors,
 | 
					  Errors,
 | 
				
			||||||
  Form,
 | 
					  Form,
 | 
				
			||||||
  FormWrap,
 | 
					  FormWrap,
 | 
				
			||||||
 | 
					  TypedInput,
 | 
				
			||||||
  Input,
 | 
					  Input,
 | 
				
			||||||
  InputAddress,
 | 
					  InputAddress,
 | 
				
			||||||
  InputAddressSelect,
 | 
					  InputAddressSelect,
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										146
									
								
								js/src/util/abi.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										146
									
								
								js/src/util/abi.js
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,146 @@
 | 
				
			|||||||
 | 
					// Copyright 2015, 2016 Ethcore (UK) Ltd.
 | 
				
			||||||
 | 
					// This file is part of Parity.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Parity is free software: you can redistribute it and/or modify
 | 
				
			||||||
 | 
					// it under the terms of the GNU General Public License as published by
 | 
				
			||||||
 | 
					// the Free Software Foundation, either version 3 of the License, or
 | 
				
			||||||
 | 
					// (at your option) any later version.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Parity is distributed in the hope that it will be useful,
 | 
				
			||||||
 | 
					// but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
 | 
					// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
				
			||||||
 | 
					// GNU General Public License for more details.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// You should have received a copy of the GNU General Public License
 | 
				
			||||||
 | 
					// along with Parity.  If not, see <http://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import { range } from 'lodash';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const ARRAY_TYPE = 'ARRAY_TYPE';
 | 
				
			||||||
 | 
					const ADDRESS_TYPE = 'ADDRESS_TYPE';
 | 
				
			||||||
 | 
					const STRING_TYPE = 'STRING_TYPE';
 | 
				
			||||||
 | 
					const BOOL_TYPE = 'BOOL_TYPE';
 | 
				
			||||||
 | 
					const BYTES_TYPE = 'BYTES_TYPE';
 | 
				
			||||||
 | 
					const INT_TYPE = 'INT_TYPE';
 | 
				
			||||||
 | 
					const FIXED_TYPE = 'FIXED_TYPE';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export const ABI_TYPES = {
 | 
				
			||||||
 | 
					  ARRAY: ARRAY_TYPE, ADDRESS: ADDRESS_TYPE,
 | 
				
			||||||
 | 
					  STRING: STRING_TYPE, BOOL: BOOL_TYPE,
 | 
				
			||||||
 | 
					  BYTES: BYTES_TYPE, INT: INT_TYPE,
 | 
				
			||||||
 | 
					  FIXED: FIXED_TYPE
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export function parseAbiType (type) {
 | 
				
			||||||
 | 
					  const arrayRegex = /^(.+)\[(\d*)]$/;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (arrayRegex.test(type)) {
 | 
				
			||||||
 | 
					    const matches = arrayRegex.exec(type);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const subtype = parseAbiType(matches[1]);
 | 
				
			||||||
 | 
					    const M = parseInt(matches[2]) || null;
 | 
				
			||||||
 | 
					    const defaultValue = !M
 | 
				
			||||||
 | 
					      ? []
 | 
				
			||||||
 | 
					      : range(M).map(() => subtype.default);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return {
 | 
				
			||||||
 | 
					      type: ARRAY_TYPE,
 | 
				
			||||||
 | 
					      subtype: subtype,
 | 
				
			||||||
 | 
					      length: M,
 | 
				
			||||||
 | 
					      default: defaultValue
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const lengthRegex = /^(u?int|bytes)(\d{1,3})$/;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (lengthRegex.test(type)) {
 | 
				
			||||||
 | 
					    const matches = lengthRegex.exec(type);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const subtype = parseAbiType(matches[1]);
 | 
				
			||||||
 | 
					    const length = parseInt(matches[2]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return {
 | 
				
			||||||
 | 
					      ...subtype,
 | 
				
			||||||
 | 
					      length
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const fixedLengthRegex = /^(u?fixed)(\d{1,3})x(\d{1,3})$/;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (fixedLengthRegex.test(type)) {
 | 
				
			||||||
 | 
					    const matches = fixedLengthRegex.exec(type);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const subtype = parseAbiType(matches[1]);
 | 
				
			||||||
 | 
					    const M = parseInt(matches[2]);
 | 
				
			||||||
 | 
					    const N = parseInt(matches[3]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return {
 | 
				
			||||||
 | 
					      ...subtype,
 | 
				
			||||||
 | 
					      M, N
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (type === 'string') {
 | 
				
			||||||
 | 
					    return {
 | 
				
			||||||
 | 
					      type: STRING_TYPE,
 | 
				
			||||||
 | 
					      default: ''
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (type === 'bool') {
 | 
				
			||||||
 | 
					    return {
 | 
				
			||||||
 | 
					      type: BOOL_TYPE,
 | 
				
			||||||
 | 
					      default: false
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (type === 'address') {
 | 
				
			||||||
 | 
					    return {
 | 
				
			||||||
 | 
					      type: ADDRESS_TYPE,
 | 
				
			||||||
 | 
					      default: ''
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (type === 'bytes') {
 | 
				
			||||||
 | 
					    return {
 | 
				
			||||||
 | 
					      type: BYTES_TYPE,
 | 
				
			||||||
 | 
					      default: '0x'
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (type === 'uint') {
 | 
				
			||||||
 | 
					    return {
 | 
				
			||||||
 | 
					      type: INT_TYPE,
 | 
				
			||||||
 | 
					      default: 0,
 | 
				
			||||||
 | 
					      length: 256,
 | 
				
			||||||
 | 
					      signed: false
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (type === 'int') {
 | 
				
			||||||
 | 
					    return {
 | 
				
			||||||
 | 
					      type: INT_TYPE,
 | 
				
			||||||
 | 
					      default: 0,
 | 
				
			||||||
 | 
					      length: 256,
 | 
				
			||||||
 | 
					      signed: true
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (type === 'ufixed') {
 | 
				
			||||||
 | 
					    return {
 | 
				
			||||||
 | 
					      type: FIXED_TYPE,
 | 
				
			||||||
 | 
					      default: 0,
 | 
				
			||||||
 | 
					      length: 256,
 | 
				
			||||||
 | 
					      signed: false
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (type === 'fixed') {
 | 
				
			||||||
 | 
					    return {
 | 
				
			||||||
 | 
					      type: FIXED_TYPE,
 | 
				
			||||||
 | 
					      default: 0,
 | 
				
			||||||
 | 
					      length: 256,
 | 
				
			||||||
 | 
					      signed: true
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Loading…
	
		Reference in New Issue
	
	Block a user