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

Meta-programming interface - ERC165 support #1447

Closed
axic opened this issue Nov 29, 2016 · 19 comments
Closed

Meta-programming interface - ERC165 support #1447

axic opened this issue Nov 29, 2016 · 19 comments
Labels
closed due inactivity The issue/PR was automatically closed due to inactivity. language design :rage4: Any changes to the language, e.g. new features stale The issue/PR was marked as stale because it has been open for too long.

Comments

@axic
Copy link
Member

axic commented Nov 29, 2016

While this topic can be fairly big and we have a couple of issues open already here I only suggest a fairly small, non-intrusive addition:

meta(<contract name>)

to return a meta object (similar to block, etc.). This would have the following defined currently:

  • .signatures returns bytes4[] corresponding to the method signatures of the contract
  • .name returns string as the name of the contract

The signatures could be utilised by proxy / filter contracts and for a way to implement interface checking between contracts (along the lines of ethereum/EIPs#165).

Two other possible methods:

  • .pragma(<key>) returns string of the actual pragma value or empty string if not set (or should the return type depend on the pragma type?)
  • .super returns meta[] corresponding to all the direct superclasses
@axic
Copy link
Member Author

axic commented Nov 29, 2016

This could be augmented by compile-time execution of certain pieces of code. It should be possible to execute pure functions during compile time given there's a VM for the intermediate language of the compiler.

@VoR0220
Copy link
Member

VoR0220 commented Nov 29, 2016

Following

@chriseth
Copy link
Contributor

I would prefer type instead of meta and baseContracts instead of super (super has a special meaning). Since we do not yet assign pragmas to contracts and arrays are quite hard to do, I would postpone them.

@axic
Copy link
Member Author

axic commented Mar 17, 2017

Using the above meta programming interface, ethereum/EIPs#165 can be implemented as a library:

contract ERC165 {
    function interfaceID() constant returns (uint)
    {
        bytes4[] sigs = type(this).signatures;
        uint mask = 0;
        for (var i = 0; i < sigs.length; i++)
            mask ^= uint(sigs[i]);
        return mask;
    }
}

contract Test is ERC165 {
  // ...
}

@chriseth
Copy link
Contributor

@axic note that the type of this is always just the current contract (although all function calls are virtual). This means that interfaceID() will only contain the functions defined by ERC165 and not those additionally defined by Test.

@axic
Copy link
Member Author

axic commented Mar 17, 2017

Right, we need templates then 😉

@axic
Copy link
Member Author

axic commented Jul 11, 2017

In line with #1435 / #2473, .signatures should be renamed .selectors and a list of function types could be added, because then the selector can be retrieved on a function.

@axic
Copy link
Member Author

axic commented Aug 1, 2017

I think it can be solved without templates too:

library ERC165 {
    function interfaceID(bytes4[] memory sigs) constant returns (uint)
    {
        uint mask = 0;
        for (var i = 0; i < sigs.length; i++)
            mask ^= uint(sigs[i]);
        return mask;
    }
}

contract Test {
  function interfaceID() constant returns (uint) {
    return ERC165.calculateInterfaceID(type(this).selectors);
  }
}

@axic axic added the feature label Sep 19, 2017
@chriseth
Copy link
Contributor

Now that ERC165 is further towards standardisation - shall we add some kind of high level support for this?

@chriseth chriseth changed the title Meta-programming interface Meta-programming interface - ERC165 Feb 26, 2018
@chriseth chriseth changed the title Meta-programming interface - ERC165 Meta-programming interface - ERC165 support Feb 26, 2018
@axic axic added the language design :rage4: Any changes to the language, e.g. new features label Jul 28, 2018
@axic
Copy link
Member Author

axic commented Jan 10, 2019

Right, we need templates then

An alternate solution to complete templates would be something like Ruby's mixins:

library ERC165 {
    mixin function interfaceID() constant returns (uint)
    {
        bytes4[] memory sigs = type(this).selectors;
        uint mask = 0;
        for (var i = 0; i < sigs.length; i++)
            mask ^= uint(sigs[i]);
        return mask;
    }
}

contract Test {
  mixin ERC165.interfaceID();
}

or

mixin ERC165 {
    function interfaceID() constant returns (uint)
    {
        bytes4[] memory sigs = type(this).selectors;
        uint mask = 0;
        for (var i = 0; i < sigs.length; i++)
            mask ^= uint(sigs[i]);
        return mask;
    }
}

contract Test {
  mixin ERC165;
}

Basically these are very restricted templates: no template parameters are supported, except that this always points to the type including it.

@chriseth
Copy link
Contributor

Are there any more use-cases for that? Otherwise, I have the impression that it is too complicated and also too restricted at the same time.

@axic
Copy link
Member Author

axic commented Jan 10, 2019

The best current solution I think still is this: #1447 (comment)

I am also wondering what are use cases there are now for mixins vs. templates. It Whether we want any of that complexity.

@ekpyron
Copy link
Member

ekpyron commented Jan 10, 2019

As a first impression I'm not a fan of the mixin syntax.
Apart from that:
Why should type(this) always be the type of the containing contract anyways? For that I could use type(C) (where C is the contract name) just as well... Maybe type(this) should only be allowed in internal functions and refer to the calling contract in libraries instead? EDIT: or maybe it shouldn't be allowed at all :-)?

@ekpyron
Copy link
Member

ekpyron commented Jan 10, 2019

The best current solution I think still is this: #1447 (comment)

I am also wondering what are use cases there are now for mixins vs. templates. It Whether we want any of that complexity.

Yes, for this particular case, I think that may be the simplest and best solution indeed.

@axic
Copy link
Member Author

axic commented Feb 25, 2019

Now we have type(C).runtimeCode and type(C).initCode. And #6097 proposes type(C).name.

Updated proposal:

  • .signatures returns string[] corresponding to the method signatures (name and parameter types of function) of the contract
  • .selectors returns bytes4[] corresponding to the method selectors (truncated hash signature) of the contract

I'm not sure .signatures is needed, but .selectors can be used to implement ERC165.

@chriseth
Copy link
Contributor

Might be a waste of memory, but sounds good!

@axic
Copy link
Member Author

axic commented Feb 26, 2019

They are in their current form, however in the future with compile time evaluated expressions all these would only exists during compile time in most of the real use cases.

@github-actions
Copy link

This issue has been marked as stale due to inactivity for the last 90 days.
It will be automatically closed in 7 days.

@github-actions github-actions bot added the stale The issue/PR was marked as stale because it has been open for too long. label Feb 12, 2023
@github-actions
Copy link

Hi everyone! This issue has been automatically closed due to inactivity.
If you think this issue is still relevant in the latest Solidity version and you have something to contribute, feel free to reopen.
However, unless the issue is a concrete proposal that can be implemented, we recommend starting a language discussion on the forum instead.

@github-actions github-actions bot added the closed due inactivity The issue/PR was automatically closed due to inactivity. label Feb 20, 2023
@github-actions github-actions bot closed this as not planned Won't fix, can't repro, duplicate, stale Feb 20, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
closed due inactivity The issue/PR was automatically closed due to inactivity. language design :rage4: Any changes to the language, e.g. new features stale The issue/PR was marked as stale because it has been open for too long.
Projects
None yet
Development

No branches or pull requests

5 participants