Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Write validators for primitive types #6

Open
rmw2 opened this issue Feb 5, 2019 · 0 comments
Open

Write validators for primitive types #6

rmw2 opened this issue Feb 5, 2019 · 0 comments

Comments

@rmw2
Copy link
Contributor

rmw2 commented Feb 5, 2019

Currently, all of the validators for solidity primitive types are the identity function (see src/primitives.js). We would like to replace these with conversion functions that ensure there is a single canonical javascript representation for each of the solidity primitive types we are emulating.

For example, one could conceivably represent an address as a Number or a String -- however allowing both in the same project creates ambiguity, which can lead to unexpected errors.

To provide the most ergonomic developer experience, we would also like that unambiguous but non-canonical representations of a particular solidity primitive are automatically converted to their canonical representation. For example, if '0x<20 hex bytes>' is the canonical representation for address, then we should prepend '0x' to an address argument of '<20 hex bytes>' with no prefix, rather than throwing an error.

Inversely, if a provided value is ambiguous or cannot be coerced into the canonical representation for the particular solidity type, the validator should throw an error.

To accomplish this, we can for each solidity primitive type, define a set of validation functions for each javascript primitive type. Most of these functions will simply throw an error, as there are unlikely to be multiple compatible javascript representations of each solidity primitive type.

To simplify this process, we can define a helper function which will allow us to define for each solidity primitive, an object mapping javascript type names to sub-validators for each supported javascript type, and which will automatically throw for any js type without a specified sub-validator:

/**
 * Create a validator function for the solidity type @param {String} target, by delegating
 * to the function in @param {Object} handlers for the javascript type of the input value.
 * If the type is missing in the {handlers} object, throw an error 
 */
function handleByType(target, handlers) {
   return input => {
     const jstype = typeof input
     // Call the proper sub-validator
     if (jstype in handlers) return handlers[jstype](input)
     // Throw an error for unsupported types
     throw new Error(`Cannot convert javascript type ${jstype} to solidity type ${target}`)
   }
 }

An example implementation of a handler using this helper, for the solidity address primitive, could look like this:

const validateAddress = handleByType('address', {
  string: x => x.slice(2) === '0x' ? x : `0x${x}`,
  object: x => x instanceof Buffer 
    ? `0x${x.toString('hex')}` 
    : reject('Cannot coerce object to address: must be string or Buffer')
})

Where we make use of another helper function reject, to simply throw an error with the provided message without requiring us to start a new statement block.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant