Skip to content
This repository has been archived by the owner on Feb 26, 2024. It is now read-only.

Allow version: "pragma" to let you import across incompatible Solidity versions #4439

Open
gnidan opened this issue Nov 17, 2021 · 2 comments

Comments

@gnidan
Copy link
Contributor

gnidan commented Nov 17, 2021

Issue

Truffle's version: "pragma" feature is awesome! It lets you compile your contracts even if they are written for differing Solidity versions.

Problem is, if you import a file with an incompatible version, Truffle just throws an error. In many situations (e.g. importing a library), there's nothing we can do about that...

But there is a common situation that we can handle completely! If the importing file uses the imported file only to reference its contracts externally, then we can ensure this import works perfectly by doing these steps:

  • Compile the imported file, capturing its resulting ABI
  • Pass this ABI into abi-to-sol or into @truffle/resolver's abi-to-sol functionality, specifying to produce Solidity matching the version of the importing file (note: this is blocked by Respect solc version when importing ABI JSON files inside Solidity code #4365, which upgrades abi-to-sol to a version that produces version-specific output)
  • Compile the importing file, having resolver.resolve produce this generated (and version-compatible!) Solidity instead of reading the incompatible imported file from disk.

Doing this would remove a lot of friction for use cases that involve writing contracts to interface externally with other on-chain contracts.

Steps to Reproduce

Create the following Solidity files:

  • A.sol
    // SPDX-License-Identifier: UNLICENSED
    pragma solidity 0.8.10;
    
    import "./B.sol";
    
    contract A {
      B b;
    
      constructor(
        address bAddress
      ) {
        b = B(bAddress);
      }
    
      function run()
        public
        view
        returns (bool)
      {
        Output memory output = b.run(Input({
          a: 44,
          b: "hello"
        }));
    
        return output.result;
      }
    }
  • B.sol
    // SPDX-License-Identifier: UNLICENSED
    pragma solidity 0.7.6;
    pragma abicoder v2;
    
    struct Input {
      uint256 a;
      string b;
    }
    
    struct Output {
      bool result;
    }
    
    contract B {
      function run(Input calldata input)
        external
        pure
        returns (Output memory)
      {
        return Output({
          result: input.a > 0
        });
      }
    }

Then, set version: "pragma" in the solc truffle-config and compile.

Desired behavior

Truffle should observe the incompatible versions and regenerate B.sol on the fly (likely using the abi-to-sol functionality provided by @truffle/resolver). Compilation should just work.

Note that this should work even if B.sol defines a contract with a name other than B; Truffle should look inside B.sol to determine what interface name to produce. This may not be feasible1, however, so perhaps we can treat "source file must match contract name" as an okay initial constraint? Blech.

Actual Results

Right now, the version: "pragma" feature detects the incompatible versions and throws a friendly error about it.

Environment

  • Operating System:
  • Ethereum client:
  • Truffle version (truffle version): v5.4.19
  • node version (node --version):
  • npm version (npm --version):

Footnotes

  1. It might not be feasible because we'd be forced to run abi-to-sol multiple times (once for each ABI produced when compiling a given source), and doing this has high risk of name collisions that would cause compilation to fail.

    The open abi-to-sol issue https://github.com/gnidan/abi-to-sol/issues/41 describes this problem a bit further.

@RatanRSur
Copy link

I see that #4420 made some progess on this. Any idea when it could be in at least an experimental version?

@gnidan
Copy link
Contributor Author

gnidan commented Jul 17, 2022

I see that #4420 made some progess on this. Any idea when it could be in at least an experimental version?

@RatanRSur sorry I missed this. Our plans for implementing this fix rely on producing ABI JSON for the imported contract and generating Solidity interfaces for the importer to use. Since Truffle currently uses the [my personal other] library abi-to-sol for this purpose elsewhere in an experimental capacity (in Truffle, you can import .abi.json files directly!), but that library has a nasty limitation in the way I implemented it, and thus this stays open for now. See the original issue writeup above for a bit more on why this issue is blocked.

Sorry about that, but glad to hear you're interested in this feature! Hopefully I'll make some headway the next time I try to refactor abi-to-sol to address the underlying limitation.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

5 participants