multiple contract source for solidity compiler: returns contract array if multiple contracts. fixes #1023

This commit is contained in:
zelig 2015-05-20 04:11:48 +01:00
parent ea893aca8f
commit b0ae84aa0d
6 changed files with 87 additions and 70 deletions

@ -234,7 +234,7 @@ func TestSignature(t *testing.T) {
// This is a very preliminary test, lacking actual signature verification // This is a very preliminary test, lacking actual signature verification
if err != nil { if err != nil {
t.Errorf("Error runnig js: %v", err) t.Errorf("Error running js: %v", err)
return return
} }
output := val.String() output := val.String()
@ -297,7 +297,7 @@ func TestContract(t *testing.T) {
t.Errorf("%v", err) t.Errorf("%v", err)
} }
} else { } else {
checkEvalJSON(t, repl, `contract = eth.compile.solidity(source)`, string(contractInfo)) checkEvalJSON(t, repl, `contract = eth.compile.solidity(source).test`, string(contractInfo))
} }
checkEvalJSON(t, repl, `contract.code`, `"0x605880600c6000396000f3006000357c010000000000000000000000000000000000000000000000000000000090048063c6888fa114602e57005b603d6004803590602001506047565b8060005260206000f35b60006007820290506053565b91905056"`) checkEvalJSON(t, repl, `contract.code`, `"0x605880600c6000396000f3006000357c010000000000000000000000000000000000000000000000000000000090048063c6888fa114602e57005b603d6004803590602001506047565b8060005260206000f35b60006007820290506053565b91905056"`)
@ -310,7 +310,7 @@ func TestContract(t *testing.T) {
callSetup := `abiDef = JSON.parse('[{"constant":false,"inputs":[{"name":"a","type":"uint256"}],"name":"multiply","outputs":[{"name":"d","type":"uint256"}],"type":"function"}]'); callSetup := `abiDef = JSON.parse('[{"constant":false,"inputs":[{"name":"a","type":"uint256"}],"name":"multiply","outputs":[{"name":"d","type":"uint256"}],"type":"function"}]');
Multiply7 = eth.contract(abiDef); Multiply7 = eth.contract(abiDef);
multiply7 = new Multiply7(contractaddress); multiply7 = Multiply7.at(contractaddress);
` `
// time.Sleep(1500 * time.Millisecond) // time.Sleep(1500 * time.Millisecond)
_, err = repl.re.Run(callSetup) _, err = repl.re.Run(callSetup)

@ -92,7 +92,7 @@ func (sol *Solidity) Version() string {
return sol.version return sol.version
} }
func (sol *Solidity) Compile(source string) (contract *Contract, err error) { func (sol *Solidity) Compile(source string) (contracts map[string]*Contract, err error) {
if len(source) == 0 { if len(source) == 0 {
err = fmt.Errorf("empty source") err = fmt.Errorf("empty source")
@ -123,58 +123,61 @@ func (sol *Solidity) Compile(source string) (contract *Contract, err error) {
err = fmt.Errorf("solc error: missing code output") err = fmt.Errorf("solc error: missing code output")
return return
} }
if len(matches) > 1 {
err = fmt.Errorf("multi-contract sources are not supported")
return
}
_, file := filepath.Split(matches[0])
base := strings.Split(file, ".")[0]
codeFile := filepath.Join(wd, base+".binary") contracts = make(map[string]*Contract)
abiDefinitionFile := filepath.Join(wd, base+".abi") for _, path := range matches {
userDocFile := filepath.Join(wd, base+".docuser") _, file := filepath.Split(path)
developerDocFile := filepath.Join(wd, base+".docdev") base := strings.Split(file, ".")[0]
code, err := ioutil.ReadFile(codeFile) codeFile := filepath.Join(wd, base+".binary")
if err != nil { abiDefinitionFile := filepath.Join(wd, base+".abi")
err = fmt.Errorf("error reading compiler output for code: %v", err) userDocFile := filepath.Join(wd, base+".docuser")
return developerDocFile := filepath.Join(wd, base+".docdev")
}
abiDefinitionJson, err := ioutil.ReadFile(abiDefinitionFile)
if err != nil {
err = fmt.Errorf("error reading compiler output for abiDefinition: %v", err)
return
}
var abiDefinition interface{}
err = json.Unmarshal(abiDefinitionJson, &abiDefinition)
userDocJson, err := ioutil.ReadFile(userDocFile) var code, abiDefinitionJson, userDocJson, developerDocJson []byte
if err != nil { code, err = ioutil.ReadFile(codeFile)
err = fmt.Errorf("error reading compiler output for userDoc: %v", err) if err != nil {
return err = fmt.Errorf("error reading compiler output for code: %v", err)
} return
var userDoc interface{} }
err = json.Unmarshal(userDocJson, &userDoc) abiDefinitionJson, err = ioutil.ReadFile(abiDefinitionFile)
if err != nil {
err = fmt.Errorf("error reading compiler output for abiDefinition: %v", err)
return
}
var abiDefinition interface{}
err = json.Unmarshal(abiDefinitionJson, &abiDefinition)
developerDocJson, err := ioutil.ReadFile(developerDocFile) userDocJson, err = ioutil.ReadFile(userDocFile)
if err != nil { if err != nil {
err = fmt.Errorf("error reading compiler output for developerDoc: %v", err) err = fmt.Errorf("error reading compiler output for userDoc: %v", err)
return return
} }
var developerDoc interface{} var userDoc interface{}
err = json.Unmarshal(developerDocJson, &developerDoc) err = json.Unmarshal(userDocJson, &userDoc)
contract = &Contract{ developerDocJson, err = ioutil.ReadFile(developerDocFile)
Code: "0x" + string(code), if err != nil {
Info: ContractInfo{ err = fmt.Errorf("error reading compiler output for developerDoc: %v", err)
Source: source, return
Language: "Solidity", }
LanguageVersion: languageVersion, var developerDoc interface{}
CompilerVersion: sol.version, err = json.Unmarshal(developerDocJson, &developerDoc)
AbiDefinition: abiDefinition,
UserDoc: userDoc, contract := &Contract{
DeveloperDoc: developerDoc, Code: "0x" + string(code),
}, Info: ContractInfo{
Source: source,
Language: "Solidity",
LanguageVersion: languageVersion,
CompilerVersion: sol.version,
AbiDefinition: abiDefinition,
UserDoc: userDoc,
DeveloperDoc: developerDoc,
},
}
contracts[base] = contract
} }
return return

@ -33,14 +33,18 @@ func TestCompiler(t *testing.T) {
} else if sol.Version() != solcVersion { } else if sol.Version() != solcVersion {
t.Logf("WARNING: a newer version of solc found (%v, expect %v)", sol.Version(), solcVersion) t.Logf("WARNING: a newer version of solc found (%v, expect %v)", sol.Version(), solcVersion)
} }
contract, err := sol.Compile(source) contracts, err := sol.Compile(source)
if err != nil { if err != nil {
t.Errorf("error compiling source. result %v: %v", contract, err) t.Errorf("error compiling source. result %v: %v", contracts, err)
return return
} }
if contract.Code != code { if len(contracts) != 1 {
t.Errorf("wrong code, expected\n%s, got\n%s", code, contract.Code) t.Errorf("one contract expected, got\n%s", len(contracts))
}
if contracts["test"].Code != code {
t.Errorf("wrong code, expected\n%s, got\n%s", code, contracts["test"].Code)
} }
} }
@ -52,9 +56,9 @@ func TestCompileError(t *testing.T) {
} else if sol.Version() != solcVersion { } else if sol.Version() != solcVersion {
t.Logf("WARNING: a newer version of solc found (%v, expect %v)", sol.Version(), solcVersion) t.Logf("WARNING: a newer version of solc found (%v, expect %v)", sol.Version(), solcVersion)
} }
contract, err := sol.Compile(source[2:]) contracts, err := sol.Compile(source[2:])
if err == nil { if err == nil {
t.Errorf("error expected compiling source. got none. result %v", contract) t.Errorf("error expected compiling source. got none. result %v", contracts)
return return
} }
} }

@ -355,12 +355,11 @@ func (api *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) err
return err return err
} }
contract, err := solc.Compile(args.Source) contracts, err := solc.Compile(args.Source)
if err != nil { if err != nil {
return err return err
} }
contract.Code = newHexData(contract.Code).String() *reply = contracts
*reply = contract
case "eth_newFilter": case "eth_newFilter":
args := new(BlockFilterArgs) args := new(BlockFilterArgs)

@ -2,14 +2,11 @@ package rpc
import ( import (
"encoding/json" "encoding/json"
// "sync"
"testing"
// "time"
// "fmt"
"io/ioutil"
"strconv" "strconv"
"testing"
"github.com/ethereum/go-ethereum/common/compiler" "github.com/ethereum/go-ethereum/common/compiler"
"github.com/ethereum/go-ethereum/eth"
"github.com/ethereum/go-ethereum/xeth" "github.com/ethereum/go-ethereum/xeth"
) )
@ -58,7 +55,7 @@ func TestCompileSolidity(t *testing.T) {
expLanguageVersion := "0" expLanguageVersion := "0"
expSource := source expSource := source
api := NewEthereumApi(&xeth.XEth{}) api := NewEthereumApi(xeth.NewTest(&eth.Ethereum{}, nil))
var req RpcRequest var req RpcRequest
json.Unmarshal([]byte(jsonstr), &req) json.Unmarshal([]byte(jsonstr), &req)
@ -73,12 +70,18 @@ func TestCompileSolidity(t *testing.T) {
t.Errorf("expected no error, got %v", err) t.Errorf("expected no error, got %v", err)
} }
var contract = compiler.Contract{} var contracts = make(map[string]*compiler.Contract)
err = json.Unmarshal(respjson, &contract) err = json.Unmarshal(respjson, &contracts)
if err != nil { if err != nil {
t.Errorf("expected no error, got %v", err) t.Errorf("expected no error, got %v", err)
} }
if len(contracts) != 1 {
t.Errorf("expected one contract, got %v", len(contracts))
}
contract := contracts["test"]
if contract.Code != expCode { if contract.Code != expCode {
t.Errorf("Expected \n%s got \n%s", expCode, contract.Code) t.Errorf("Expected \n%s got \n%s", expCode, contract.Code)
} }
@ -86,12 +89,15 @@ func TestCompileSolidity(t *testing.T) {
if strconv.Quote(contract.Info.Source) != `"`+expSource+`"` { if strconv.Quote(contract.Info.Source) != `"`+expSource+`"` {
t.Errorf("Expected \n'%s' got \n'%s'", expSource, strconv.Quote(contract.Info.Source)) t.Errorf("Expected \n'%s' got \n'%s'", expSource, strconv.Quote(contract.Info.Source))
} }
if contract.Info.Language != expLanguage { if contract.Info.Language != expLanguage {
t.Errorf("Expected %s got %s", expLanguage, contract.Info.Language) t.Errorf("Expected %s got %s", expLanguage, contract.Info.Language)
} }
if contract.Info.LanguageVersion != expLanguageVersion { if contract.Info.LanguageVersion != expLanguageVersion {
t.Errorf("Expected %s got %s", expLanguageVersion, contract.Info.LanguageVersion) t.Errorf("Expected %s got %s", expLanguageVersion, contract.Info.LanguageVersion)
} }
if contract.Info.CompilerVersion != expCompilerVersion { if contract.Info.CompilerVersion != expCompilerVersion {
t.Errorf("Expected %s got %s", expCompilerVersion, contract.Info.CompilerVersion) t.Errorf("Expected %s got %s", expCompilerVersion, contract.Info.CompilerVersion)
} }
@ -114,8 +120,6 @@ func TestCompileSolidity(t *testing.T) {
if string(abidef) != expAbiDefinition { if string(abidef) != expAbiDefinition {
t.Errorf("Expected \n'%s' got \n'%s'", expAbiDefinition, string(abidef)) t.Errorf("Expected \n'%s' got \n'%s'", expAbiDefinition, string(abidef))
} }
ioutil.WriteFile("/tmp/abidef", []byte(string(abidef)), 0700)
ioutil.WriteFile("/tmp/expabidef", []byte(expAbiDefinition), 0700)
if string(userdoc) != expUserDoc { if string(userdoc) != expUserDoc {
t.Errorf("Expected \n'%s' got \n'%s'", expUserDoc, string(userdoc)) t.Errorf("Expected \n'%s' got \n'%s'", expUserDoc, string(userdoc))

@ -69,6 +69,13 @@ type XEth struct {
agent *miner.RemoteAgent agent *miner.RemoteAgent
} }
func NewTest(eth *eth.Ethereum, frontend Frontend) *XEth {
return &XEth{
backend: eth,
frontend: frontend,
}
}
// New creates an XEth that uses the given frontend. // New creates an XEth that uses the given frontend.
// If a nil Frontend is provided, a default frontend which // If a nil Frontend is provided, a default frontend which
// confirms all transactions will be used. // confirms all transactions will be used.