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

Compile external code snippets #1272

Closed
chriseth opened this issue Oct 24, 2016 · 14 comments
Closed

Compile external code snippets #1272

chriseth opened this issue Oct 24, 2016 · 14 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 medium effort Default level of effort medium impact Default level of impact needs design The proposal is too vague to be implemented right away should have We like the idea but it’s not important enough to be a part of the roadmap. stale The issue/PR was marked as stale because it has been open for too long.

Comments

@chriseth
Copy link
Contributor

This is the solidity part of EIP 144

This feature will give users the ability to compile code snippet in the context of an existing contract without necessarily having to combine it with the contract itself.

If the compiler is in a state where source code is parsed and type checked, we can call compileSnippet(code, contract), where code is valid solidity code - either an expression or an internal function - in the context of contract. This function returns EVM bytecode that, when executed, behaves like the snippet.

This should also be supported in the generic json input #1129 where the target contract key could be used for this.

@chriseth
Copy link
Contributor Author

Increasing priority as it seems that go-ethereum just implemented the required RPC interface.

@axic
Copy link
Member

axic commented Feb 1, 2017

An idea how to make this a more integrated language feature:

snippet CrazyBalanceCalculation for Token {
  function() returns (uint) {
    // do magic here
  }
}

A snippet:

  • must have a single base contract it extends (mandated by the for or is keyword)
  • must have a single function without a name, but can have input and output parameters

How this maps into the JSON interface: currently there is an output member contracts for contracts. It would have a separate snippets output member.

@chriseth
Copy link
Contributor Author

chriseth commented Feb 1, 2017

Sounds good! I would prefer a little less syntax, though - we do not really need two nested elements: The name of the snippet can be the name of the function. Perhaps

function CrazyBalanceCalculation() snippet(Token) returns (uint) { ... }

although it should perhaps be a bit more obvious that it is a snippet and pulls in the context from Token.

@axic
Copy link
Member

axic commented Feb 1, 2017

On one side I agree that it looks overkill, but:

  • snippet(Token) looks like a modifier
  • the above layout looks familiar to the users of Solidity (I think)

In the above format the snippet could be extended with named functions which can be called from within the entry point (function()), e.g.:

snippet CrazyBalanceCalculation for Token {
  function() returns (uint) {
    // do magic here
    return heavylifting() * 42;
  }
  function heavylifting() returns (uint) {
  }
}

Although this could easily become complex.

@chriseth
Copy link
Contributor Author

chriseth commented Feb 2, 2017

Note that I really want to get this down to a javascript UI expression that looks something like:

var c = ... ; // the compiled contract, only need to compile it once for the full app
var bal = await c.eval("m_balance[0x123]"); // This is compiled on the fly (but cached)

So the idea is to get seamless interoperability between Solidity and the frontend code.

This means that the name of the snippet does not have to be seen by the programmer and is only relevant to address it in the compiler interface. Oh and I hope that you can soon use inline-defined functions anyway.

So I think we can get this down to expressions by also allowing

snippet $someassignedname for Token {
  m_balance[0x123]
}

and then

snippet $someassignedname2(uint) returns (uint8) for Token {
  return 8 * m_balance[0x123];
}

but also

snippet $someassignedname2 for Token {
  function namedFunction(uint) returns (uint8) {
    return 8 * m_balance[0x123];
  }
}

Perhaps this can be combined with inline functions in general...

@axic
Copy link
Member

axic commented Feb 2, 2017

get this down to a javascript UI expression that looks something like

I think that has no relation, because it is up to solc-js to do the translation.

The single-line query (albeit I'm not sure that single lines will be very useful)

var bal = await c.eval("Token", "m_balance[0x123]");

could be translated to

snippet __snippet123 for Token { function () returns (uint) { return m_balance[0x123]; } }

by solc-js, where __snippet123 is an internal identifier generated by it.

Although I'm not sure it makes sense for the compiler to figure out the type conversions.

@chriseth
Copy link
Contributor Author

chriseth commented Feb 2, 2017

I don't think solc-js can do it, because it does not know the type of the expression. Because of that I think this has to be a compiler feature. On the other hand, web3.js cannot work with the result because it does not know how to decode it without the type.

@axic
Copy link
Member

axic commented Feb 6, 2017

On the other hand, web3.js cannot work with the result because it does not know how to decode it without the type.

Exactly, that's why I'm not sure it should be a single line as above.

Is that too much to write? It is expressive at least.

var c = ... ; // the compiled contract, only need to compile it once for the full app
var bal = await c.eval(`
snippet Bal for Token {
  function() returns (uint) {
    return m_balance[0x123];
  }
}`)

Also I'm not sure these snippets would be single line in the first case, the above example is kind of broken, because getting the balance is usually available as a getter anyway.

@axic axic added feature and removed enhancement labels Sep 18, 2017
@axic
Copy link
Member

axic commented Aug 1, 2018

Removing accepted as I do not think this is fully spec'd.

@axic axic removed the accepted label Aug 1, 2018
@axic axic added this to Inbox in Backlog (breaking) via automation Aug 1, 2018
@axic axic removed the in progress label Aug 2, 2018
@chriseth chriseth added this to Inbox in Backlog (non-breaking) via automation Nov 14, 2018
@axic axic removed this from Inbox in Backlog (breaking) Nov 14, 2018
@chriseth chriseth moved this from Inbox to medium priority in Backlog (non-breaking) Dec 13, 2018
@ekpyron
Copy link
Member

ekpyron commented Aug 8, 2019

This seems to be revived in light of ethereum/go-ethereum#19836, should we continue the syntax discussion here? We'd basically need some syntax to compile the code supplied for such a new eth_call, right? Then solidity code using this syntax could e.g. be compiled via standardjson and then passed on to the eth_call directly? This all sounds pretty cool :-).

Syntax wise I like @axic's proposal - I'd generally think of this as a special kind of "external inheritance". So I'm in favour of

snippet Name for Token {
  // basically any kind of contract function including fallback functions and named functions
}

When actually using this for eth_call we could in fact append a function signature and an argument encoding to the produced bytecode similar to constructor arguments for contracts and that way execute some specific function in the snippet code. That way one could compile one snippet containing a lot of functions with arguments, etc. and call any of them. Code size won't really matter, right?

@chriseth
Copy link
Contributor Author

It would be great if we could also have a short form like snippet Name for Token { return x; } such that the user can just supply the expression x and the compiler can tell the external tool the type of x and so on.

@elenadimitrova elenadimitrova added this to New issues in Solidity via automation May 14, 2020
@elenadimitrova elenadimitrova moved this from New issues to Design Backlog in Solidity May 14, 2020
@chriseth
Copy link
Contributor Author

I'm not so sure anymore we really need the surrounding context to be in text format. I cannot really imagine snippets to be used without a more complex framework that accesses the compiler. Furthermore, if we just use snippet Name for Token as a text fragment in isolation, it would also have to reference the file name.

During the discussion in #10825 it came up that it might be useful to parse snippets in the context of functions (without the need for generating code) and output the AST, so it could be useful to open up the context a bit wider.

If we have more support from a framework, we could specify this as a feature that assumes it is used via standard-json (or maybe even the LSP). This means snippet compilation requests could be a section in the standard-json (or an equivalent in the commandline) that look like:

snippets: [
  {
    context: 45, // AST ID of a contract or function
    text: "m_balances[7]" // implies that the value of the expression is returned
  },
  {
    context: "my//file/name.sol:MyContract.functionName, // AST ID of a contract or function
    text: "x == y" // x and y are function parameters - here we would only parse the expression
  },
  {
    context: "my//file/name.sol:MyContract, // AST ID of a contract
    text: "function bal(address _u) external returns (uint) { return m_balances[_u] * currentInterestRate(); }"
  }
]

@cameel cameel added language design :rage4: Any changes to the language, e.g. new features medium effort Default level of effort medium impact Default level of impact nice to have We don’t see a good reason not to have it but won’t go out of our way to implement it. needs design The proposal is too vague to be implemented right away should have We like the idea but it’s not important enough to be a part of the roadmap. and removed nice to have We don’t see a good reason not to have it but won’t go out of our way to implement it. labels Sep 26, 2022
@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
Solidity automation moved this from Design Backlog to Done 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 medium effort Default level of effort medium impact Default level of impact needs design The proposal is too vague to be implemented right away should have We like the idea but it’s not important enough to be a part of the roadmap. stale The issue/PR was marked as stale because it has been open for too long.
Projects
No open projects
Backlog (non-breaking)
  
medium priority
Solidity
  
Done
Development

No branches or pull requests

5 participants