Skip to content

Commit

Permalink
common/compiler: fix parsing of solc output with solidity v.0.8.0 (et…
Browse files Browse the repository at this point in the history
…hereum#22092)

Solidity 0.8.0 changes the way that output is marshalled. This patch allows to parse both
the legacy format used previously and the new format.

See also https://docs.soliditylang.org/en/breaking/080-breaking-changes.html#interface-changes
  • Loading branch information
MariusVanDerWijden authored and gzliudan committed Dec 19, 2024
1 parent 94f7a94 commit ccd44a8
Showing 1 changed file with 48 additions and 2 deletions.
50 changes: 48 additions & 2 deletions common/compiler/solidity.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,20 @@ type solcOutput struct {
Version string
}

// solidity v.0.8 changes the way ABI, Devdoc and Userdoc are serialized
type solcOutputV8 struct {
Contracts map[string]struct {
BinRuntime string `json:"bin-runtime"`
SrcMapRuntime string `json:"srcmap-runtime"`
Bin, SrcMap, Metadata string
Abi interface{}
Devdoc interface{}
Userdoc interface{}
Hashes map[string]string
}
Version string
}

func (s *Solidity) makeArgs() []string {
p := []string{
"--combined-json", "bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc",
Expand Down Expand Up @@ -125,7 +139,6 @@ func (s *Solidity) run(cmd *exec.Cmd, source string) (map[string]*Contract, erro
if err := cmd.Run(); err != nil {
return nil, fmt.Errorf("solc: %v\n%s", err, stderr.Bytes())
}

return ParseCombinedJSON(stdout.Bytes(), source, s.Version, s.Version, strings.Join(s.makeArgs(), " "))
}

Expand All @@ -141,7 +154,8 @@ func (s *Solidity) run(cmd *exec.Cmd, source string) (map[string]*Contract, erro
func ParseCombinedJSON(combinedJSON []byte, source string, languageVersion string, compilerVersion string, compilerOptions string) (map[string]*Contract, error) {
var output solcOutput
if err := json.Unmarshal(combinedJSON, &output); err != nil {
return nil, err
// Try to parse the output with the new solidity v.0.8.0 rules
return parseCombinedJSONV8(combinedJSON, source, languageVersion, compilerVersion, compilerOptions)
}
// Compilation succeeded, assemble and return the contracts.
contracts := make(map[string]*Contract)
Expand Down Expand Up @@ -176,3 +190,35 @@ func ParseCombinedJSON(combinedJSON []byte, source string, languageVersion strin
}
return contracts, nil
}

// parseCombinedJSONV8 parses the direct output of solc --combined-output
// and parses it using the rules from solidity v.0.8.0 and later.
func parseCombinedJSONV8(combinedJSON []byte, source string, languageVersion string, compilerVersion string, compilerOptions string) (map[string]*Contract, error) {
var output solcOutputV8
if err := json.Unmarshal(combinedJSON, &output); err != nil {
return nil, err
}
// Compilation succeeded, assemble and return the contracts.
contracts := make(map[string]*Contract)
for name, info := range output.Contracts {
contracts[name] = &Contract{
Code: "0x" + info.Bin,
RuntimeCode: "0x" + info.BinRuntime,
Hashes: info.Hashes,
Info: ContractInfo{
Source: source,
Language: "Solidity",
LanguageVersion: languageVersion,
CompilerVersion: compilerVersion,
CompilerOptions: compilerOptions,
SrcMap: info.SrcMap,
SrcMapRuntime: info.SrcMapRuntime,
AbiDefinition: info.Abi,
UserDoc: info.Userdoc,
DeveloperDoc: info.Devdoc,
Metadata: info.Metadata,
},
}
}
return contracts, nil
}

0 comments on commit ccd44a8

Please sign in to comment.