@@ -13,7 +13,8 @@ import (
1313 "strings"
1414)
1515
16- var versionRegexp = regexp .MustCompile (`([0-9]+)\.([0-9]+)\.([0-9]+)` )
16+ var pragmaRegexp = regexp .MustCompile (`(?m)^\s*pragma\s+solidity\s+([^;]+);` )
17+
1718
1819// Contract contains information about a compiled contract, alongside its code and runtime code.
1920type Contract struct {
@@ -88,27 +89,38 @@ func (s *Solidity) makeArgs() ([]string, error) {
8889 return args , nil
8990}
9091
91- // SolidityVersion runs solc and parses its version output.
9292func SolidityVersion (source string ) (* Solidity , error ) {
93- var err error
94- matches := versionRegexp .FindStringSubmatch (source )
95- if len (matches ) != 4 {
96- return nil , fmt .Errorf ("can't parse solc version %q" , source )
97- }
98- s := & Solidity {Path : "docker" }
99- if s .Major , err = strconv .Atoi (matches [1 ]); err != nil {
100- return nil , err
101- }
102- if s .Minor , err = strconv .Atoi (matches [2 ]); err != nil {
103- return nil , err
104- }
105- if s .Patch , err = strconv .Atoi (matches [3 ]); err != nil {
106- return nil , err
107- }
108- s .Version = strconv .Itoa (s .Major ) + "." + strconv .Itoa (s .Minor ) + "." + strconv .Itoa (s .Patch )
109- return s , nil
93+ var err error
94+ // Extract pragma solidity version from source
95+ matches := pragmaRegexp .FindStringSubmatch (source )
96+ if len (matches ) < 2 {
97+ return nil , fmt .Errorf ("can't find pragma solidity in %q" , source )
98+ }
99+ versionConstraint := strings .TrimSpace (matches [1 ])
100+
101+ // Grab the first explicit version number like 0.8.0
102+ versionNumber := regexp .MustCompile (`([0-9]+)\.([0-9]+)\.([0-9]+)` ).FindString (versionConstraint )
103+ if versionNumber == "" {
104+ return nil , fmt .Errorf ("invalid pragma solidity version: %q" , versionConstraint )
105+ }
106+
107+ parts := strings .Split (versionNumber , "." )
108+ s := & Solidity {Path : "docker" }
109+
110+ if s .Major , err = strconv .Atoi (parts [0 ]); err != nil {
111+ return nil , err
112+ }
113+ if s .Minor , err = strconv .Atoi (parts [1 ]); err != nil {
114+ return nil , err
115+ }
116+ if s .Patch , err = strconv .Atoi (parts [2 ]); err != nil {
117+ return nil , err
118+ }
119+ s .Version = versionNumber
120+ return s , nil
110121}
111122
123+
112124// CompileSolidityString builds and returns all the contracts contained within a source string.
113125func CompileSolidityString (ctx context.Context , source , solcVersion , evmVersion string , optimize bool ) (map [string ]* Contract , error ) {
114126 var s * Solidity
0 commit comments