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

Add Support for Compiling and Deploying First Class Functions #15621

Open
cre-mer opened this issue Dec 6, 2024 · 0 comments
Open

Add Support for Compiling and Deploying First Class Functions #15621

cre-mer opened this issue Dec 6, 2024 · 0 comments
Labels

Comments

@cre-mer
Copy link

cre-mer commented Dec 6, 2024

Abstract

Solidity currently doesn’t support deploying standalone functions as contracts. While Solidity is object-oriented by design, there are valid use cases for pure, stateless functions that could be deployed directly without the overhead of a full contract or library structure. Examples include cryptographic hash computations, verifier functions, or any single-purpose computational logic.

Motivation

The ability to deploy standalone functions would provide several benefits:

  • Cheaper deployment for single-purpose computational logic
  • Reduced gas costs by eliminating overhead such as function dispatcher and smaller calldata
  • Cleaner abstraction for purely functional operations

This would be particularly useful for:

  • ZK proof verifiers
  • Cryptographic operations
  • Pure computational functions
  • Stateless verification logic

Specification

Standalone functions would have the following characteristics:

  • Cannot have state variables
  • Cannot receive ETH
  • Cannot be destroyed
  • Must be pure or view
  • Can only have one function per deployment
  • Must be external

Compilation would generate bytecode that:

  • Skips function selector matching
  • Directly executes the function logic
  • Validate input parameters
  • Returns output

Additional Considerations

While this is currently semi-possible, using a contract that only includes a fallback function, i.e, skipping the function dispatcher, fallback functions are limited in how they can be declared: fallback () external [payable] or fallback (bytes calldata input) external [payable] returns (bytes memory output). The latter declaration allows us even to add custom input and return custom output, however:

  • This adds overhead for developers, who will have to manually encode the input, which is also an error-prone process
  • The return bytes will have to be manually decoded, too, as well as automatically copied into memory, which could add extra costs.

The proposed solution will allow optionally custom input and output parameters and types.

Example

sample-project
├── verifyProof.sol
└── Verifier.sol

verifyProof.sol

function verifyProof(bytes calldata proof) external pure returns (bool) {
    // verification logic
    return true;
}

Verifier.sol

// import the function from a file
import { verifyProof } from "./verifyProof.sol";

contract Verifier {    
    // @param verifyProof the address of the deployed standalone function
    function isValidProof(verifyProof _verifyProof, bytes memory proof) external view returns(bool) {
        return _verifyProof(proof);
    }
}

This gist has an extended example, including a compiled verifyProof.yul file, showing how the function object could look like.

Backwards Compatibility

This feature would be semi-backward compatible. Calling a standalone function, as shown in the example, would not be possible in Solidity. However, this is feasible using low-level calls.

@cre-mer cre-mer added the feature label Dec 6, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant