From 8541ddbd951370b2a42df8d82b0633ff0efeba12 Mon Sep 17 00:00:00 2001 From: Martin Holst Swende Date: Mon, 23 May 2022 14:29:23 +0200 Subject: [PATCH] common/compiler, cmd/abigen: remove solc/vyper compiler integration --- cmd/abigen/main.go | 52 +---------- common/compiler/helpers.go | 20 ----- common/compiler/solidity.go | 117 +------------------------ common/compiler/solidity_test.go | 78 ----------------- common/compiler/test.v.py | 3 - common/compiler/test_bad.v.py | 3 - common/compiler/vyper.go | 144 ------------------------------- common/compiler/vyper_test.go | 71 --------------- 8 files changed, 3 insertions(+), 485 deletions(-) delete mode 100644 common/compiler/solidity_test.go delete mode 100644 common/compiler/test.v.py delete mode 100644 common/compiler/test_bad.v.py delete mode 100644 common/compiler/vyper.go delete mode 100644 common/compiler/vyper_test.go diff --git a/cmd/abigen/main.go b/cmd/abigen/main.go index 911aada37..8f255143c 100644 --- a/cmd/abigen/main.go +++ b/cmd/abigen/main.go @@ -21,11 +21,9 @@ import ( "fmt" "io" "os" - "path/filepath" "regexp" "strings" - "github.com/ethereum/go-ethereum/accounts/abi" "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/cmd/utils" "github.com/ethereum/go-ethereum/common/compiler" @@ -59,24 +57,6 @@ var ( Name: "combined-json", Usage: "Path to the combined-json file generated by compiler", } - solFlag = cli.StringFlag{ - Name: "sol", - Usage: "Path to the Ethereum contract Solidity source to build and bind", - } - solcFlag = cli.StringFlag{ - Name: "solc", - Usage: "Solidity compiler to use if source builds are requested", - Value: "solc", - } - vyFlag = cli.StringFlag{ - Name: "vy", - Usage: "Path to the Ethereum contract Vyper source to build and bind", - } - vyperFlag = cli.StringFlag{ - Name: "vyper", - Usage: "Vyper compiler to use if source builds are requested", - Value: "vyper", - } excFlag = cli.StringFlag{ Name: "exc", Usage: "Comma separated types to exclude from binding", @@ -107,10 +87,6 @@ func init() { binFlag, typeFlag, jsonFlag, - solFlag, - solcFlag, - vyFlag, - vyperFlag, excFlag, pkgFlag, outFlag, @@ -122,7 +98,7 @@ func init() { } func abigen(c *cli.Context) error { - utils.CheckExclusive(c, abiFlag, jsonFlag, solFlag, vyFlag) // Only one source can be selected. + utils.CheckExclusive(c, abiFlag, jsonFlag) // Only one source can be selected. if c.GlobalString(pkgFlag.Name) == "" { utils.Fatalf("No destination package specified (--pkg)") } @@ -186,33 +162,9 @@ func abigen(c *cli.Context) error { for _, kind := range strings.Split(c.GlobalString(excFlag.Name), ",") { exclude[strings.ToLower(kind)] = true } - var err error var contracts map[string]*compiler.Contract - switch { - case c.GlobalIsSet(solFlag.Name): - contracts, err = compiler.CompileSolidity(c.GlobalString(solcFlag.Name), c.GlobalString(solFlag.Name)) - if err != nil { - utils.Fatalf("Failed to build Solidity contract: %v", err) - } - case c.GlobalIsSet(vyFlag.Name): - output, err := compiler.CompileVyper(c.GlobalString(vyperFlag.Name), c.GlobalString(vyFlag.Name)) - if err != nil { - utils.Fatalf("Failed to build Vyper contract: %v", err) - } - contracts = make(map[string]*compiler.Contract) - for n, contract := range output { - name := n - // Sanitize the combined json names to match the - // format expected by solidity. - if !strings.Contains(n, ":") { - // Remove extra path components - name = abi.ToCamelCase(strings.TrimSuffix(filepath.Base(name), ".vy")) - } - contracts[name] = contract - } - - case c.GlobalIsSet(jsonFlag.Name): + if c.GlobalIsSet(jsonFlag.Name) { jsonOutput, err := os.ReadFile(c.GlobalString(jsonFlag.Name)) if err != nil { utils.Fatalf("Failed to read combined-json from compiler: %v", err) diff --git a/common/compiler/helpers.go b/common/compiler/helpers.go index 59d242af3..063fc1081 100644 --- a/common/compiler/helpers.go +++ b/common/compiler/helpers.go @@ -17,14 +17,6 @@ // Package compiler wraps the Solidity and Vyper compiler executables (solc; vyper). package compiler -import ( - "bytes" - "os" - "regexp" -) - -var versionRegexp = regexp.MustCompile(`([0-9]+)\.([0-9]+)\.([0-9]+)`) - // Contract contains information about a compiled contract, alongside its code and runtime code. type Contract struct { Code string `json:"code"` @@ -51,15 +43,3 @@ type ContractInfo struct { DeveloperDoc interface{} `json:"developerDoc"` Metadata string `json:"metadata"` } - -func slurpFiles(files []string) (string, error) { - var concat bytes.Buffer - for _, file := range files { - content, err := os.ReadFile(file) - if err != nil { - return "", err - } - concat.Write(content) - } - return concat.String(), nil -} diff --git a/common/compiler/solidity.go b/common/compiler/solidity.go index ffda0193c..ad8a44aa0 100644 --- a/common/compiler/solidity.go +++ b/common/compiler/solidity.go @@ -14,26 +14,14 @@ // You should have received a copy of the GNU Lesser General Public License // along with the go-ethereum library. If not, see . -// Package compiler wraps the Solidity and Vyper compiler executables (solc; vyper). +// Package compiler wraps the ABI compilation outputs. package compiler import ( - "bytes" "encoding/json" - "errors" "fmt" - "os/exec" - "strconv" - "strings" ) -// Solidity contains information about the solidity compiler. -type Solidity struct { - Path, Version, FullVersion string - Major, Minor, Patch int - ExtraAllowedPath []string -} - // --combined-output format type solcOutput struct { Contracts map[string]struct { @@ -59,109 +47,6 @@ type solcOutputV8 struct { Version string } -func (s *Solidity) allowedPaths() string { - paths := []string{".", "./", "../"} // default to support relative paths - if len(s.ExtraAllowedPath) > 0 { - paths = append(paths, s.ExtraAllowedPath...) - } - return strings.Join(paths, ", ") -} - -func (s *Solidity) makeArgs() []string { - p := []string{ - "--combined-json", "bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc", - "--optimize", // code optimizer switched on - "--allow-paths", s.allowedPaths(), - } - if s.Major > 0 || s.Minor > 4 || s.Patch > 6 { - p[1] += ",metadata,hashes" - } - return p -} - -// SolidityVersion runs solc and parses its version output. -func SolidityVersion(solc string) (*Solidity, error) { - if solc == "" { - solc = "solc" - } - var out bytes.Buffer - cmd := exec.Command(solc, "--version") - cmd.Stdout = &out - err := cmd.Run() - if err != nil { - return nil, err - } - matches := versionRegexp.FindStringSubmatch(out.String()) - if len(matches) != 4 { - return nil, fmt.Errorf("can't parse solc version %q", out.String()) - } - s := &Solidity{Path: cmd.Path, FullVersion: out.String(), Version: matches[0]} - if s.Major, err = strconv.Atoi(matches[1]); err != nil { - return nil, err - } - if s.Minor, err = strconv.Atoi(matches[2]); err != nil { - return nil, err - } - if s.Patch, err = strconv.Atoi(matches[3]); err != nil { - return nil, err - } - return s, nil -} - -// CompileSolidityString builds and returns all the contracts contained within a source string. -func CompileSolidityString(solc, source string) (map[string]*Contract, error) { - if len(source) == 0 { - return nil, errors.New("solc: empty source string") - } - s, err := SolidityVersion(solc) - if err != nil { - return nil, err - } - return s.CompileSource(source) -} - -// CompileSolidity compiles all given Solidity source files. -func CompileSolidity(solc string, sourcefiles ...string) (map[string]*Contract, error) { - if len(sourcefiles) == 0 { - return nil, errors.New("solc: no source files") - } - s, err := SolidityVersion(solc) - if err != nil { - return nil, err - } - - return s.CompileFiles(sourcefiles...) -} - -// CompileSource builds and returns all the contracts contained within a source string. -func (s *Solidity) CompileSource(source string) (map[string]*Contract, error) { - args := append(s.makeArgs(), "--") - cmd := exec.Command(s.Path, append(args, "-")...) - cmd.Stdin = strings.NewReader(source) - return s.run(cmd, source) -} - -// CompileFiles compiles all given Solidity source files. -func (s *Solidity) CompileFiles(sourcefiles ...string) (map[string]*Contract, error) { - source, err := slurpFiles(sourcefiles) - if err != nil { - return nil, err - } - args := append(s.makeArgs(), "--") - cmd := exec.Command(s.Path, append(args, sourcefiles...)...) - return s.run(cmd, source) -} - -func (s *Solidity) run(cmd *exec.Cmd, source string) (map[string]*Contract, error) { - var stderr, stdout bytes.Buffer - cmd.Stderr = &stderr - cmd.Stdout = &stdout - 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(), " ")) -} - // ParseCombinedJSON takes the direct output of a solc --combined-output run and // parses it into a map of string contract name to Contract structs. The // provided source, language and compiler version, and compiler options are all diff --git a/common/compiler/solidity_test.go b/common/compiler/solidity_test.go deleted file mode 100644 index 491e3665e..000000000 --- a/common/compiler/solidity_test.go +++ /dev/null @@ -1,78 +0,0 @@ -// Copyright 2015 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package compiler - -import ( - "os/exec" - "testing" -) - -const ( - testSource = ` -pragma solidity >0.0.0; -contract test { - /// @notice Will multiply ` + "`a`" + ` by 7. - function multiply(uint a) public returns(uint d) { - return a * 7; - } -} -` -) - -func skipWithoutSolc(t *testing.T) { - if _, err := exec.LookPath("solc"); err != nil { - t.Skip(err) - } -} - -func TestSolidityCompiler(t *testing.T) { - skipWithoutSolc(t) - - contracts, err := CompileSolidityString("", testSource) - if err != nil { - t.Fatalf("error compiling source. result %v: %v", contracts, err) - } - if len(contracts) != 1 { - t.Errorf("one contract expected, got %d", len(contracts)) - } - c, ok := contracts["test"] - if !ok { - c, ok = contracts[":test"] - if !ok { - t.Fatal("info for contract 'test' not present in result") - } - } - if c.Code == "" { - t.Error("empty code") - } - if c.Info.Source != testSource { - t.Error("wrong source") - } - if c.Info.CompilerVersion == "" { - t.Error("empty version") - } -} - -func TestSolidityCompileError(t *testing.T) { - skipWithoutSolc(t) - - contracts, err := CompileSolidityString("", testSource[4:]) - if err == nil { - t.Errorf("error expected compiling source. got none. result %v", contracts) - } - t.Logf("error: %v", err) -} diff --git a/common/compiler/test.v.py b/common/compiler/test.v.py deleted file mode 100644 index 35af56c8f..000000000 --- a/common/compiler/test.v.py +++ /dev/null @@ -1,3 +0,0 @@ -@public -def test(): - hello: int128 diff --git a/common/compiler/test_bad.v.py b/common/compiler/test_bad.v.py deleted file mode 100644 index 443ef7826..000000000 --- a/common/compiler/test_bad.v.py +++ /dev/null @@ -1,3 +0,0 @@ -lic -def test(): - hello: int128 diff --git a/common/compiler/vyper.go b/common/compiler/vyper.go deleted file mode 100644 index a9bca95e5..000000000 --- a/common/compiler/vyper.go +++ /dev/null @@ -1,144 +0,0 @@ -// Copyright 2019 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -// Package compiler wraps the Solidity and Vyper compiler executables (solc; vyper). -package compiler - -import ( - "bytes" - "encoding/json" - "errors" - "fmt" - "os/exec" - "strconv" - "strings" -) - -// Vyper contains information about the vyper compiler. -type Vyper struct { - Path, Version, FullVersion string - Major, Minor, Patch int -} - -func (s *Vyper) makeArgs() []string { - p := []string{ - "-f", "combined_json", - } - return p -} - -// VyperVersion runs vyper and parses its version output. -func VyperVersion(vyper string) (*Vyper, error) { - if vyper == "" { - vyper = "vyper" - } - var out bytes.Buffer - cmd := exec.Command(vyper, "--version") - cmd.Stdout = &out - err := cmd.Run() - if err != nil { - return nil, err - } - matches := versionRegexp.FindStringSubmatch(out.String()) - if len(matches) != 4 { - return nil, fmt.Errorf("can't parse vyper version %q", out.String()) - } - s := &Vyper{Path: cmd.Path, FullVersion: out.String(), Version: matches[0]} - if s.Major, err = strconv.Atoi(matches[1]); err != nil { - return nil, err - } - if s.Minor, err = strconv.Atoi(matches[2]); err != nil { - return nil, err - } - if s.Patch, err = strconv.Atoi(matches[3]); err != nil { - return nil, err - } - return s, nil -} - -// CompileVyper compiles all given Vyper source files. -func CompileVyper(vyper string, sourcefiles ...string) (map[string]*Contract, error) { - if len(sourcefiles) == 0 { - return nil, errors.New("vyper: no source files") - } - source, err := slurpFiles(sourcefiles) - if err != nil { - return nil, err - } - s, err := VyperVersion(vyper) - if err != nil { - return nil, err - } - args := s.makeArgs() - cmd := exec.Command(s.Path, append(args, sourcefiles...)...) - return s.run(cmd, source) -} - -func (s *Vyper) run(cmd *exec.Cmd, source string) (map[string]*Contract, error) { - var stderr, stdout bytes.Buffer - cmd.Stderr = &stderr - cmd.Stdout = &stdout - if err := cmd.Run(); err != nil { - return nil, fmt.Errorf("vyper: %v\n%s", err, stderr.Bytes()) - } - - return ParseVyperJSON(stdout.Bytes(), source, s.Version, s.Version, strings.Join(s.makeArgs(), " ")) -} - -// ParseVyperJSON takes the direct output of a vyper --f combined_json run and -// parses it into a map of string contract name to Contract structs. The -// provided source, language and compiler version, and compiler options are all -// passed through into the Contract structs. -// -// The vyper output is expected to contain ABI and source mapping. -// -// Returns an error if the JSON is malformed or missing data, or if the JSON -// embedded within the JSON is malformed. -func ParseVyperJSON(combinedJSON []byte, source string, languageVersion string, compilerVersion string, compilerOptions string) (map[string]*Contract, error) { - var output map[string]interface{} - 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 { - // Parse the individual compilation results. - if name == "version" { - continue - } - c := info.(map[string]interface{}) - - contracts[name] = &Contract{ - Code: c["bytecode"].(string), - RuntimeCode: c["bytecode_runtime"].(string), - Info: ContractInfo{ - Source: source, - Language: "Vyper", - LanguageVersion: languageVersion, - CompilerVersion: compilerVersion, - CompilerOptions: compilerOptions, - SrcMap: c["source_map"], - SrcMapRuntime: "", - AbiDefinition: c["abi"], - UserDoc: "", - DeveloperDoc: "", - Metadata: "", - }, - } - } - return contracts, nil -} diff --git a/common/compiler/vyper_test.go b/common/compiler/vyper_test.go deleted file mode 100644 index 7761c92af..000000000 --- a/common/compiler/vyper_test.go +++ /dev/null @@ -1,71 +0,0 @@ -// Copyright 2019 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package compiler - -import ( - "os/exec" - "testing" -) - -func skipWithoutVyper(t *testing.T) { - if _, err := exec.LookPath("vyper"); err != nil { - t.Skip(err) - } -} - -func TestVyperCompiler(t *testing.T) { - skipWithoutVyper(t) - - testSource := []string{"test.v.py"} - source, err := slurpFiles(testSource) - if err != nil { - t.Error("couldn't read test files") - } - contracts, err := CompileVyper("", testSource...) - if err != nil { - t.Fatalf("error compiling test.v.py. result %v: %v", contracts, err) - } - if len(contracts) != 1 { - t.Errorf("one contract expected, got %d", len(contracts)) - } - c, ok := contracts["test.v.py"] - if !ok { - c, ok = contracts[":test"] - if !ok { - t.Fatal("info for contract 'test.v.py' not present in result") - } - } - if c.Code == "" { - t.Error("empty code") - } - if c.Info.Source != source { - t.Error("wrong source") - } - if c.Info.CompilerVersion == "" { - t.Error("empty version") - } -} - -func TestVyperCompileError(t *testing.T) { - skipWithoutVyper(t) - - contracts, err := CompileVyper("", "test_bad.v.py") - if err == nil { - t.Errorf("error expected compiling test_bad.v.py. got none. result %v", contracts) - } - t.Logf("error: %v", err) -}