TezosTaqueria / taqueria

*BETA* Taqueria provides a seamless development workflow to easily build, test and deploy your Tezos applications.
https://taqueria.io
Apache License 2.0
64 stars 20 forks source link

Multi-file smart contract projects can be compiled, tested, and deployed #234

Closed russellmorton closed 2 years ago

russellmorton commented 2 years ago

As a LIGO dapp developer, I want to be able to compile multi-file smart contracts, so that I can compile smart contracts that are split across multiple files.

Options:

Notes from Discussions:

Claude:

  1. Any contract with more than 3-4 entrypoints will be split across different files, so it is important that Taqueria handles it or it won’t be possible to create more complex contracts
  2. The Ligo compiler has a preprocess feature that will glue all the files together in a single file, I am wondering if you couldn’t take advantage of it, Taqueria would only need to know which file has the main function, and if there are multiple files and #include directives at the top of the main file, it could preprocess the contract into a single file that may or may not be available for the user. Instead of asking the developer What files would you like to import as contracts?, it could be What file includes the main function of the contract? and Taqueria does the rest.
  3. Regarding oracles, I tested different contracts these past 2 years that required interactions with oracles, so for development on Flextesa, I created “fake oracles”, contracts that return the same type of value as the oracles on-chain. It has the added benefit of giving control to the developer over the kind of data the oracle returns, which can be neat to test your own contract with different values provided by the oracle.

Jev:

Considerations

Acceptance Criteria

hu3man commented 2 years ago

Closing: Redundant issue

russellmorton commented 2 years ago

Repurposing this issue to track multi-file smart contracts.

russellmorton commented 2 years ago

How do we handle multi-file contracts? What event triggers the generation of contract metadata?

How it works today:

Here's how an end-developer would create a contract for their project: Create a file such as hello.mligo in their contracts folder. To compile, run taq compile, which would invoke the compile task provided by the LIGO plugin. The LIGO plugin just scans the contracts directory for a list of valid file extensions and interprets each file as an atomic contract.

Proposal

Plugins now have the ability to create templates, which are essentially named pieces of programmable content that a plugin defines which are then exposed via the CLI plugin (and later VS Code extension). The LIGO plugin should expose a template called contract, and the end-developer could instantiate that template by running, taq create contract hello.mligo which would result in a new file called contracts/hello.mligo being created in your project: type storage = string type result = operation list * storage type param = string

let main ((param: store) : (param * storage) = ([] : operation list), param Using a different file extension would dictate which content to use (or however the plugin author decides to implement its template content). This is what I meant by programmable content - templates can receive input, either as positional arguments, or as option flags which the plugin can use & interpret when generating the result. When combined with hooks, we can do lots of different things that automate a lot for the end-developer, but I'll come back to that. What I'd like to propose as something for discussion is making the above as one of the two sole means of adding a contract to your project. What's the other way of adding a contract to your project? By running taq import contract [filename/pattern/directory] which uses the filename, pattern or directory provided to create a list of files that are added to the state registry and identified as contracts. Our compiler plugins would then be adjusted to not search for files, but just use the state registry as the source of truth for what contracts are in your project. By using hooks, we can have taq import run whenever taq create contract is invoked. We can then use hooks to run many kinds of automations when the taq import contract task is invoked, whether directly or indirectly: Generate a file with the corresponding metadata Create operations for the following: Validating metadata Compiling the contract Uploading the contract to IPFS Originating the contract (using the IPFS hash as input)

Coming back to our questions

How do we handle multi-file contracts? You can create as many source files you like, but only the files explicitly imported as contracts will be treated as contracts. E.g.: As an end-developer, you create the files A.mligo, B.mligo, and C.mligo. C.mligo is the root of your contract, and references/includes the source code of A.mligo and B.mligo. If you were to run taq compile, you'd see a message, "No contracts found. Have you imported it?" The end-developer would run taq import contract C.mligo to make Taqueria aware of the contract. What event triggers the generation of contract metadata? When a contract is imported.

What other advantages are there to this approach?

We further enforce and imply that the state registry is the single source of truth We can inspect the state registry to determine whether a contract is changed, and only run taq compile when necessary. Because Taqueria is always aware of what contracts are available, and what plugin created them, we can probably do some neat things. For instance, right now when someone runs taq compile` and has both the LIGO and SmartPy plugin installed, the end-developer has to be explicit about what plugin they want to invoke. E.g., taq compile -p ligo would compile all LIGO files. However, now that Taqueria is aware of what plugins were used to create the contracts, we could have taq compile just use the state registry to infer what plugin to use when compiling each contract found

Cons to this approach

Might not be that intuitive when using the CLI. Users might find it more intuitive to just create a file in the contracts directory and expect that Taqueria will be able to find there. Using VS Code, we can probably make this better - for instance, adding a context menu to the contracts directory with an item, "Create contract", or having a watcher prompt the user, "Would you like to import this as a contract?" after they create a file in the contracts directory

russellmorton commented 2 years ago

For reference: https://ecadlabs.slack.com/archives/C036G3SVA4Q/p1655762682645639

russellmorton commented 2 years ago

@mweichert https://github.com/ecadlabs/taqueria/issues/896 for consideration as well.

hu3man commented 2 years ago

Example LIGO multi-file contracts to test: https://gitlab.com/ligolang/contract-catalogue/