github.com/daethereum/go-dae@v2.2.3+incompatible/common/compiler/solidity.go (about) 1 // Copyright 2015 The go-ethereum Authors 2 // This file is part of the go-ethereum library. 3 // 4 // The go-ethereum library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The go-ethereum library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 16 17 // Package compiler wraps the ABI compilation outputs. 18 package compiler 19 20 import ( 21 "encoding/json" 22 "fmt" 23 ) 24 25 // --combined-output format 26 type solcOutput struct { 27 Contracts map[string]struct { 28 BinRuntime string `json:"bin-runtime"` 29 SrcMapRuntime string `json:"srcmap-runtime"` 30 Bin, SrcMap, Abi, Devdoc, Userdoc, Metadata string 31 Hashes map[string]string 32 } 33 Version string 34 } 35 36 // solidity v.0.8 changes the way ABI, Devdoc and Userdoc are serialized 37 type solcOutputV8 struct { 38 Contracts map[string]struct { 39 BinRuntime string `json:"bin-runtime"` 40 SrcMapRuntime string `json:"srcmap-runtime"` 41 Bin, SrcMap, Metadata string 42 Abi interface{} 43 Devdoc interface{} 44 Userdoc interface{} 45 Hashes map[string]string 46 } 47 Version string 48 } 49 50 // ParseCombinedJSON takes the direct output of a solc --combined-output run and 51 // parses it into a map of string contract name to Contract structs. The 52 // provided source, language and compiler version, and compiler options are all 53 // passed through into the Contract structs. 54 // 55 // The solc output is expected to contain ABI, source mapping, user docs, and dev docs. 56 // 57 // Returns an error if the JSON is malformed or missing data, or if the JSON 58 // embedded within the JSON is malformed. 59 func ParseCombinedJSON(combinedJSON []byte, source string, languageVersion string, compilerVersion string, compilerOptions string) (map[string]*Contract, error) { 60 var output solcOutput 61 if err := json.Unmarshal(combinedJSON, &output); err != nil { 62 // Try to parse the output with the new solidity v.0.8.0 rules 63 return parseCombinedJSONV8(combinedJSON, source, languageVersion, compilerVersion, compilerOptions) 64 } 65 // Compilation succeeded, assemble and return the contracts. 66 contracts := make(map[string]*Contract) 67 for name, info := range output.Contracts { 68 // Parse the individual compilation results. 69 var abi interface{} 70 if err := json.Unmarshal([]byte(info.Abi), &abi); err != nil { 71 return nil, fmt.Errorf("solc: error reading abi definition (%v)", err) 72 } 73 var userdoc, devdoc interface{} 74 json.Unmarshal([]byte(info.Userdoc), &userdoc) 75 json.Unmarshal([]byte(info.Devdoc), &devdoc) 76 77 contracts[name] = &Contract{ 78 Code: "0x" + info.Bin, 79 RuntimeCode: "0x" + info.BinRuntime, 80 Hashes: info.Hashes, 81 Info: ContractInfo{ 82 Source: source, 83 Language: "Solidity", 84 LanguageVersion: languageVersion, 85 CompilerVersion: compilerVersion, 86 CompilerOptions: compilerOptions, 87 SrcMap: info.SrcMap, 88 SrcMapRuntime: info.SrcMapRuntime, 89 AbiDefinition: abi, 90 UserDoc: userdoc, 91 DeveloperDoc: devdoc, 92 Metadata: info.Metadata, 93 }, 94 } 95 } 96 return contracts, nil 97 } 98 99 // parseCombinedJSONV8 parses the direct output of solc --combined-output 100 // and parses it using the rules from solidity v.0.8.0 and later. 101 func parseCombinedJSONV8(combinedJSON []byte, source string, languageVersion string, compilerVersion string, compilerOptions string) (map[string]*Contract, error) { 102 var output solcOutputV8 103 if err := json.Unmarshal(combinedJSON, &output); err != nil { 104 return nil, err 105 } 106 // Compilation succeeded, assemble and return the contracts. 107 contracts := make(map[string]*Contract) 108 for name, info := range output.Contracts { 109 contracts[name] = &Contract{ 110 Code: "0x" + info.Bin, 111 RuntimeCode: "0x" + info.BinRuntime, 112 Hashes: info.Hashes, 113 Info: ContractInfo{ 114 Source: source, 115 Language: "Solidity", 116 LanguageVersion: languageVersion, 117 CompilerVersion: compilerVersion, 118 CompilerOptions: compilerOptions, 119 SrcMap: info.SrcMap, 120 SrcMapRuntime: info.SrcMapRuntime, 121 AbiDefinition: info.Abi, 122 UserDoc: info.Userdoc, 123 DeveloperDoc: info.Devdoc, 124 Metadata: info.Metadata, 125 }, 126 } 127 } 128 return contracts, nil 129 }