tact-lang / tact

Tact compiler main repository
https://tact-lang.org
MIT License
374 stars 104 forks source link

Inconsistent ABI generation for projects with multiple contracts #533

Closed Gusarich closed 2 months ago

Gusarich commented 3 months ago

Found while debugging #516

ABI generation seems to go wrong when the project has multiple contracts. Small reproducable example is below.

Create a new Tact project (doesn't matter Blueprint or not) with two contracts with separate build output directorie specified.

Contract A:

import "@stdlib/deploy";

contract A with Deployable {
    receive() {}
}

Contract B:

import "@stdlib/deploy";
import "./a.tact";

contract B with Deployable {
    receive() {
        require(1 == 1, "1 is not equal to 1");
    }

    get fun test(): Address {
        return contractAddress(initOf A());
    }
}

Now build that project and look at the build directory, which will have separate A and B project builds. Since B depends on A, the A contract will be compiled separately for B project and will be included in that directory. It is completely normal behaviour, but if we look at the resulting ABI of A in both of these directories, it'll differ in the presence of 1 is not equal to 1 error code. This leads to the different compilation results due to hash change in IPFS link to ABI. Same behaviour can be achieved for types ABI field too by defining some struct in B and not in A.

The order of elements in types ABI field can also be shuffled in some cases, but I didn't come up with a small reproducable example. I believe it has something to do with the order of Object items in JS (Objects are used for storing all types during compilation and not Maps).

Gusarich commented 2 months ago

depends on #545

anton-trunov commented 2 months ago

An internal discussion with @Gusarich has lead us to the decision of not to change ABI generation.