Request solidity metadata only for compiler versions 0.4.7 and higher

This commit is contained in:
Steve Waldman 2017-01-28 13:23:26 -08:00
parent 9b9131604c
commit 87a22c400f

View file

@ -25,21 +25,21 @@ import (
"io/ioutil" "io/ioutil"
"os/exec" "os/exec"
"regexp" "regexp"
"strconv"
"strings" "strings"
"sync"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/crypto"
) )
var ( var (
versionRegexp = regexp.MustCompile(`[0-9]+\.[0-9]+\.[0-9]+`) versionRegexp = regexp.MustCompile(`([0-9]+)\.([0-9]+)\.([0-9]+)`)
solcParams = []string{ spmu = &sync.Mutex{} // protects access to mutating _solcParams variable (contents are never mutated)
"--combined-json", "bin,abi,userdoc,devdoc,metadata", _solcParams = []string{} // zero-len means uninitialized, protected by spmu
"--add-std", // include standard lib contracts
"--optimize", // code optimizer switched on
}
) )
type Contract struct { type Contract struct {
Code string `json:"code"` Code string `json:"code"`
Info ContractInfo `json:"info"` Info ContractInfo `json:"info"`
@ -68,6 +68,58 @@ type solcOutput struct {
Version string Version string
} }
func findSolcParams(solc string) []string {
spmu.Lock()
defer spmu.Unlock()
if ( len(_solcParams) != 0 ) {
return _solcParams
} else {
recent, _ := atLeast047(solc) // on err, we default to considering the solidity version recent, see atLeast047
var mbmeta string
if ( recent ) {
mbmeta = ",metadata"
} else {
mbmeta = ""
}
_solcParams = []string{
"--combined-json", "bin,abi,userdoc,devdoc" + mbmeta,
"--add-std", // include standard lib contracts
"--optimize", // code optimizer switched on
}
return _solcParams
}
}
func atLeast047(solc string) (bool, error) {
var (
solidity *Solidity
major int
minor int
patch int
err error
)
solidity, err = SolidityVersion(solc)
if ( err != nil ) {
return true, err
}
matches := versionRegexp.FindStringSubmatch( solidity.Version )
major, err = strconv.Atoi( matches[1] )
if ( err != nil ) {
return true, err
}
minor, err = strconv.Atoi( matches[2] )
if ( err != nil ) {
return true, err
}
patch, err = strconv.Atoi( matches[3] )
if ( err != nil ) {
return true, err
}
return (major > 0 || minor > 4 || patch > 6), nil
}
// SolidityVersion runs solc and parses its version output. // SolidityVersion runs solc and parses its version output.
func SolidityVersion(solc string) (*Solidity, error) { func SolidityVersion(solc string) (*Solidity, error) {
if solc == "" { if solc == "" {
@ -95,10 +147,11 @@ func CompileSolidityString(solc, source string) (map[string]*Contract, error) {
if solc == "" { if solc == "" {
solc = "solc" solc = "solc"
} }
solcParams := findSolcParams(solc)
args := append(solcParams, "--") args := append(solcParams, "--")
cmd := exec.Command(solc, append(args, "-")...) cmd := exec.Command(solc, append(args, "-")...)
cmd.Stdin = strings.NewReader(source) cmd.Stdin = strings.NewReader(source)
return runsolc(cmd, source) return runsolc(cmd, solcParams, source)
} }
// CompileSolidity compiles all given Solidity source files. // CompileSolidity compiles all given Solidity source files.
@ -113,12 +166,13 @@ func CompileSolidity(solc string, sourcefiles ...string) (map[string]*Contract,
if solc == "" { if solc == "" {
solc = "solc" solc = "solc"
} }
solcParams := findSolcParams(solc)
args := append(solcParams, "--") args := append(solcParams, "--")
cmd := exec.Command(solc, append(args, sourcefiles...)...) cmd := exec.Command(solc, append(args, sourcefiles...)...)
return runsolc(cmd, source) return runsolc(cmd, solcParams, source)
} }
func runsolc(cmd *exec.Cmd, source string) (map[string]*Contract, error) { func runsolc(cmd *exec.Cmd, solcParams []string, source string) (map[string]*Contract, error) {
var stderr, stdout bytes.Buffer var stderr, stdout bytes.Buffer
cmd.Stderr = &stderr cmd.Stderr = &stderr
cmd.Stdout = &stdout cmd.Stdout = &stdout