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

Unique function identifiers for use in the function selector in contracts #96

Closed
sezna opened this issue Jun 28, 2021 · 8 comments · Fixed by #113
Closed

Unique function identifiers for use in the function selector in contracts #96

sezna opened this issue Jun 28, 2021 · 8 comments · Fixed by #113
Assignees
Labels
compiler General compiler. Should eventually become more specific as the issue is triaged enhancement New feature or request good first issue Good for newcomers

Comments

@sezna
Copy link
Contributor

sezna commented Jun 28, 2021

In the Solidity world, functions are hashed using a specific algorithm and then truncated for 4 bytes. We need to decide if we want to follow the same scheme (it sounds like we do), and implement it. These will then be baked into the contract preamble section in the ABI/"switch statement" for contracts.

Assigning Victor for now since he seemed to have interest, but feel free to reassign if that is not the case.

@sezna sezna added enhancement New feature or request good first issue Good for newcomers compiler General compiler. Should eventually become more specific as the issue is triaged labels Jun 28, 2021
@sezna
Copy link
Contributor Author

sezna commented Jul 6, 2021

A function selector will be composed of the function name and then the types of its parameters concatenated and hashed via SHA256, and then truncated to 4 bytes.

A contract ABI function should have some additional requirements due to the nature of it being an FFI. No generic or delayed-resolution types can be allowed due to the necessity of a known type at the time of interaction.

In addition, we need a consistent way to represent types that will be easily maintainable, so that we may include them in the hash for the function selector. Some options would be to rely on the default Debug implementation, or to use the syntax of the language's representation. I find both of these flawed, as they mean syntax changes or internal naming conventions could break backwards compatibility with existing contract ABIs. I propose instead that we introduce a new method that stringifies types for the explicit purpose of this function selector. For now, it can strongly resemble the syntax of the language, but it prevents us from drift in the future.

To summarize:

  1. No generics in contract trait functions
  2. Hashes will be the first 4 bytes of the SHA256 hash of the string format!("{}{}", function_name, function_param_types) where function_param_types is the stringified type name as described in the paragraph above.

@adlerjohn adlerjohn assigned sezna and unassigned vlopes11 Jul 6, 2021
@adlerjohn
Copy link
Contributor

adlerjohn commented Jul 6, 2021

  1. I agree with using a stringified representation for parameter types, seems like the most reasonable.
  2. Also agree no generics for ABI functions; everything should have a concrete type.
  3. The string should be UTF-8 encoded, right? Rust and Solidity use UTF-8. Regardless of what we choose, the string encoding needs to be defined since you can only hash bytes (i.e. zeroes and ones), not strings.
  4. To avoid collisions, the formatting should have a domain separator between the function name and the parameter types, and between each parameter type. To make it more visually appealing, I suggest ( and ) around the parameter types and , between each parameter type. I.e. function_name(type1,type2,type3).

@sezna could you provide an example of how a generic type would look when made concrete in the ABI string?

@sezna
Copy link
Contributor Author

sezna commented Jul 6, 2021

That domain separator works for me. And yes, everything will be UTF-8.

@sezna
Copy link
Contributor Author

sezna commented Jul 6, 2021

I was thinking we would not allow generic types at all in the ABI. So, if somebody writes:

contract;

contract trait {
    fn foo<T>(a: T) -> T;
};

They would get an error along the lines of generic types are not allowed in contract ABIs.

@sezna
Copy link
Contributor Author

sezna commented Jul 6, 2021

For structs and enums, we could use the syntax:
s(field,field,field) and e(variant,variant,variant). That way we don't have collisions between enums with variants that are identical to the fields in a struct.

@sezna
Copy link
Contributor Author

sezna commented Jul 6, 2021

We have forgotten about return types. How about:

foo(param_type_1,param_type_2)->return_type

?

@adlerjohn
Copy link
Contributor

I don't think return type is needed, since it's irrelevant to the function signature (e.g. in C++ you can't have two overloaded functions differ only in their return type).

@sezna
Copy link
Contributor Author

sezna commented Jul 6, 2021

Ok, I will remove it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
compiler General compiler. Should eventually become more specific as the issue is triaged enhancement New feature or request good first issue Good for newcomers
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants