common/compiler,cmd/abigen: update solidity compiler with library linking options

Signed-off-by: RJ Catalano <rj@monax.io>
This commit is contained in:
RJ Catalano 2017-08-15 11:26:13 -05:00
parent 3a678a15c9
commit a38afe2815
No known key found for this signature in database
GPG key ID: D4AB109D9B5D6386
5 changed files with 123 additions and 3 deletions

View file

@ -32,6 +32,7 @@ var (
abiFlag = flag.String("abi", "", "Path to the Ethereum contract ABI json to bind") abiFlag = flag.String("abi", "", "Path to the Ethereum contract ABI json to bind")
binFlag = flag.String("bin", "", "Path to the Ethereum contract bytecode (generate deploy method)") binFlag = flag.String("bin", "", "Path to the Ethereum contract bytecode (generate deploy method)")
typFlag = flag.String("type", "", "Struct name for the binding (default = package name)") typFlag = flag.String("type", "", "Struct name for the binding (default = package name)")
linkFlag = flag.String("link", "", "Library flag linker for name to addresses in the code")
solFlag = flag.String("sol", "", "Path to the Ethereum contract Solidity source to build and bind") solFlag = flag.String("sol", "", "Path to the Ethereum contract Solidity source to build and bind")
solcFlag = flag.String("solc", "solc", "Solidity compiler to use if source builds are requested") solcFlag = flag.String("solc", "solc", "Solidity compiler to use if source builds are requested")

View file

@ -0,0 +1,6 @@
package compiler
type Compiler interface {
PrepareCommand(files ...string) error
Compile(flags ...func() string) (string, error)
}

17
common/compiler/flags.go Normal file
View file

@ -0,0 +1,17 @@
package compiler
func addStandardAbiAndBin() string {
return "abi,bin,"
}
func addDevDoc() string {
return "devdoc"
}
func addUserDoc() string {
return "userdoc"
}
func addMetadata() string {
return "metadata"
}

View file

@ -23,6 +23,7 @@ import (
"errors" "errors"
"fmt" "fmt"
"io/ioutil" "io/ioutil"
"os"
"os/exec" "os/exec"
"regexp" "regexp"
"strconv" "strconv"
@ -52,6 +53,15 @@ type ContractInfo struct {
type Solidity struct { type Solidity struct {
Path, Version, FullVersion string Path, Version, FullVersion string
Major, Minor, Patch int Major, Minor, Patch int
Files []string
FlagOpts SolcFlagOpts
}
type SolcFlagOpts struct {
Optimize bool
CombinedJson []string
ToLink []string
Version string
} }
// --combined-output format // --combined-output format
@ -136,6 +146,35 @@ func CompileSolidity(solc string, sourcefiles ...string) (map[string]*Contract,
return s.run(cmd, source) return s.run(cmd, source)
} }
func (s *Solidity) GetFiles(sourcefiles ...string) error {
if len(sourcefiles) == 0 {
return errors.New("solc: no source files")
}
for _, file := range sourcefiles {
if _, err := os.Stat(file); os.IsNotExist(err) {
return fmt.Errorf("solc: could not find file %v", file)
}
s.Files = append(s.Files, file)
}
return nil
}
/*func (s *Solidity) Compile(flags ...func() string) (string, error) {
var command []string
for _, flag := range flags {
command := append(command, flag())
}
if len(s.FlagOpts.ToLink) > 0 {
command := append(command, s.linkLibraries())
}
finalCommand := strings.Join(command, "")
exec.Command("solc", finalCommand)
}*/
func (s *Solidity) run(cmd *exec.Cmd, source string) (map[string]*Contract, error) { func (s *Solidity) run(cmd *exec.Cmd, source string) (map[string]*Contract, error) {
var stderr, stdout bytes.Buffer var stderr, stdout bytes.Buffer
cmd.Stderr = &stderr cmd.Stderr = &stderr
@ -182,6 +221,10 @@ func (s *Solidity) run(cmd *exec.Cmd, source string) (map[string]*Contract, erro
return contracts, nil return contracts, nil
} }
func (s *Solidity) linkLibraries() string {
return "--libraries " + strings.Join(s.FlagOpts.ToLink, ",")
}
func slurpFiles(files []string) (string, error) { func slurpFiles(files []string) (string, error) {
var concat bytes.Buffer var concat bytes.Buffer
for _, file := range files { for _, file := range files {

View file

@ -18,6 +18,7 @@ package compiler
import ( import (
"os/exec" "os/exec"
"strings"
"testing" "testing"
) )
@ -30,6 +31,40 @@ contract test {
} }
} }
` `
librarySource = `
library Set {
struct Data { mapping(uint => bool) flags; }
function insert(Data storage self, uint value)
returns (bool)
{
if (self.flags[value])
return false; // already there
self.flags[value] = true;
return true;
}
function remove(Data storage self, uint value)
returns (bool)
{
if (!self.flags[value])
return false; // not there
self.flags[value] = false;
return true;
}
function contains(Data storage self, uint value)
returns (bool)
{
return self.flags[value];
}
}
contract C {
Set.Data knownValues;
function register(uint value) {
require(Set.insert(knownValues, value));
}
}`
) )
func skipWithoutSolc(t *testing.T) { func skipWithoutSolc(t *testing.T) {
@ -75,3 +110,21 @@ func TestCompileError(t *testing.T) {
} }
t.Logf("error: %v", err) t.Logf("error: %v", err)
} }
func TestCompilerLinking(t *testing.T) {
skipWithoutSolc(t)
solc, err := SolidityVersion("")
if err != nil {
t.Fatalf("%v", err)
}
solc.FlagOpts.ToLink = append(solc.FlagOpts.ToLink, "Set:0x692a70d2e424a56d2c6c27aa97d1a86395877b3a")
linkedLibraries := solc.linkLibraries()
testingCase1 := "--libraries Set:0x692a70d2e424a56d2c6c27aa97d1a86395877b3a"
if strings.Compare(linkedLibraries, testingCase1) != 0 {
t.Errorf("expected %v, got %v", linkedLibraries, testingCase1)
}
}