dapple linking design issue
Restructuring classes.json
Currently in case of two contracts with the same name, classes.json "bubbles up" only one name. This is not good. This is not a bit good. Let me explain:
In case I have one contract A which interacts with two different versions of the same contract B. In this scenario I want to test 'integration' and for this, both versions of contract B have to be deployed on chain. Unfortunately only one binary is found in classses.jsos.
A solution could be assigning an identifier to the contract name, like it is done in the dappfile. classes.json would the an object mapping looking like this:
{
"A[<id1>]": { <...> },
"B[<id2>]": { <...> },
"B[ <id3>]": { <...> }
}
As we will see, this solution is insufficient: this is clearer demonstrated with libraries: Imagine both instances on B depend on different versions of a "C" Library. then in both of them a placeholder for the address will be stored: ___C_______ without information, which of the two different libraries to use. Therefore a flat structure lacks this information. A better solution would be a tree structure representing the import files: B[ <id2> ] depends on C[ <id4> ] and therefore the sourcecode file containing C is imported in B. We could represent classes.json in this way:
{
"A[<id1>]": { <...> },
"B[<id2>]": { imports: [ "C[ <id4> ]" ], <...> },
"B[ <id3>]": { imports: [ "C[ <id5> ]" ], <...> },
...
}
At least library linking and deployment could be handled in this way, but looking at this in more detail, I have no clue how to handle this, in special if one contract depends on two different versions of another.
Another useful information to store are the files needed, to recompile the contract. As we already have a flat structure, I'd suggest taking advantage of it and just dumping it inside under files tag which maps file hashes to its source. Also including the hash of the "entrance file" which is needed to recompile the contract inside of a contract object. I'd propose making the contract type id the hash of the entrance source file:
e.g.:
{
contracts: {
"A[<id1>]": { src: <id1 >, <...> },
...
},
files: {
"<id1>": "import \\"./<id2>.sol\\"\\n contract A { ...",
"<id2>: "...",
...
}
And to complete the madness, I'd suggest the hash of a contract file to be its IPFS Hash -- the key which is needed for the source code to be restored from ipfs.
Hmm, maybe we should omit and substitute imports altogether ...
@ryepdx you had the most recent look on the linker. Is this approach appropriate? Is it easy to implement, or nearly impossible?
Hey, sorry for the late reply. I get a ton of Github notifications and so I've taken to ignoring them all. I should cut back on what I'm notified about, apparently.
Your last suggestion is definitely do-able. This is very similar to what the linker already does. In fact, it produces the files structure you give as an example as part of its process. Should then just be a matter of adding that internal variable to the function's output, more or less.
I'll let you know if I think of anything else.