Skip to content

Commit

Permalink
Abigen parses artifact in json format
Browse files Browse the repository at this point in the history
  • Loading branch information
ferranbt committed May 7, 2021
1 parent ec1b314 commit e89ce3d
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 25 deletions.
32 changes: 19 additions & 13 deletions abigen/gen.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,13 +50,8 @@ func funcName(str string) string {
return strings.Title(handleSnakeCase(str))
}

func encodeArg(str interface{}) string {
arg, ok := str.(*abi.TupleElem)
if !ok {
panic("bad 1")
}

switch arg.Elem.Kind() {
func encodeSimpleArg(typ *abi.Type) string {
switch typ.Kind() {
case abi.KindAddress:
return "web3.Address"

Expand All @@ -67,20 +62,31 @@ func encodeArg(str interface{}) string {
return "bool"

case abi.KindInt:
return arg.Elem.GoType().String()
return typ.GoType().String()

case abi.KindUInt:
return arg.Elem.GoType().String()
return typ.GoType().String()

case abi.KindFixedBytes:
return fmt.Sprintf("[%d]byte", arg.Elem.Size())
return fmt.Sprintf("[%d]byte", typ.Size())

case abi.KindBytes:
return "[]byte"

case abi.KindSlice:
return "[]" + encodeSimpleArg(typ.Elem())

default:
return fmt.Sprintf("input not done for type: %s", arg.Elem.String())
return fmt.Sprintf("input not done for type: %s", typ.String())
}
}

func encodeArg(str interface{}) string {
arg, ok := str.(*abi.TupleElem)
if !ok {
panic("bad 1")
}
return encodeSimpleArg(arg.Elem)
}

func tupleLen(tuple interface{}) interface{} {
Expand Down Expand Up @@ -206,7 +212,7 @@ func ({{.Ptr}} *{{.Name}}) Contract() *contract.Contract {
// calls
{{range $key, $value := .Abi.Methods}}{{if .Const}}
// {{funcName $key}} calls the {{$key}} method in the solidity contract
func ({{$.Ptr}} *{{$.Name}}) {{funcName $key}}({{range $index, $val := tupleElems .Inputs}}{{if .Name}}{{clean .Name}}{{else}}val{{$index}}{{end}} {{arg .}}, {{end}}block ...web3.BlockNumber) ({{range $index, $val := tupleElems .Outputs}}val{{$index}} {{arg .}}, {{end}}err error) {
func ({{$.Ptr}} *{{$.Name}}) {{funcName $key}}({{range $index, $val := tupleElems .Inputs}}{{if .Name}}{{clean .Name}}{{else}}val{{$index}}{{end}} {{arg .}}, {{end}}block ...web3.BlockNumber) ({{range $index, $val := tupleElems .Outputs}}retval{{$index}} {{arg .}}, {{end}}err error) {
var out map[string]interface{}
{{ $length := tupleLen .Outputs }}{{ if ne $length 0 }}var ok bool{{ end }}
Expand All @@ -216,7 +222,7 @@ func ({{$.Ptr}} *{{$.Name}}) {{funcName $key}}({{range $index, $val := tupleElem
}
// decode outputs
{{range $index, $val := tupleElems .Outputs}}val{{$index}}, ok = out["{{if .Name}}{{.Name}}{{else}}{{$index}}{{end}}"].({{arg .}})
{{range $index, $val := tupleElems .Outputs}}retval{{$index}}, ok = out["{{if .Name}}{{.Name}}{{else}}{{$index}}{{end}}"].({{arg .}})
if !ok {
err = fmt.Errorf("failed to encode output at index {{$index}}")
return
Expand Down
68 changes: 56 additions & 12 deletions abigen/main.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package main

import (
"encoding/json"
"flag"
"fmt"
"io/ioutil"
Expand Down Expand Up @@ -40,21 +41,29 @@ func main() {
os.Exit(0)
}

artifacts, err := process(source, config)
matches, err := filepath.Glob(source)
if err != nil {
fmt.Printf("Failed to parse sources: %v", err)
os.Exit(0)
fmt.Printf("Failed to read files: %v", err)
os.Exit(1)
}
if err := gen(artifacts, config); err != nil {
fmt.Printf("Failed to generate sources: %v", err)
os.Exit(0)
for _, source := range matches {
artifacts, err := process(source, config)
if err != nil {
fmt.Printf("Failed to parse sources: %v", err)
os.Exit(1)
}
if err := gen(artifacts, config); err != nil {
fmt.Printf("Failed to generate sources: %v", err)
os.Exit(1)
}
}
}

const (
vyExt = 0
solExt = 1
abiExt = 2
vyExt = 0
solExt = 1
abiExt = 2
jsonExt = 3
)

func process(sources string, config *config) (map[string]*compiler.Artifact, error) {
Expand All @@ -66,15 +75,17 @@ func process(sources string, config *config) (map[string]*compiler.Artifact, err
prev := -1
for _, f := range files {
var ext int
switch filepath.Ext(f) {
switch extt := filepath.Ext(f); extt {
case ".abi":
ext = abiExt
case ".sol":
ext = solExt
case ".vy", ".py":
ext = vyExt
case ".json":
ext = jsonExt
default:
return nil, fmt.Errorf("file extension not found")
return nil, fmt.Errorf("file extension '%s' not found", extt)
}

if prev == -1 {
Expand All @@ -91,6 +102,8 @@ func process(sources string, config *config) (map[string]*compiler.Artifact, err
return processSolc(files)
case vyExt:
return processVyper(files)
case jsonExt:
return processJson(files)
}

return nil, nil
Expand Down Expand Up @@ -138,7 +151,7 @@ func processAbi(sources []string, config *config) (map[string]*compiler.Artifact
for _, abiPath := range sources {
content, err := ioutil.ReadFile(abiPath)
if err != nil {
return nil, fmt.Errorf("Failed to read abi file (%s): %v", abiPath, err)
return nil, fmt.Errorf("failed to read abi file (%s): %v", abiPath, err)
}

// Use the name of the file to name the contract
Expand All @@ -162,3 +175,34 @@ func processAbi(sources []string, config *config) (map[string]*compiler.Artifact
}
return artifacts, nil
}

type JSONArtifact struct {
Bytecode string `json:"bytecode"`
Abi json.RawMessage `json:"abi"`
}

func processJson(sources []string) (map[string]*compiler.Artifact, error) {
artifacts := map[string]*compiler.Artifact{}

for _, jsonPath := range sources {
content, err := ioutil.ReadFile(jsonPath)
if err != nil {
return nil, fmt.Errorf("failed to read abi file (%s): %v", jsonPath, err)
}

// Use the name of the file to name the contract
_, name := filepath.Split(jsonPath)
name = strings.TrimSuffix(name, ".json")

var art *JSONArtifact
if err := json.Unmarshal(content, &art); err != nil {
return nil, err
}

artifacts[strings.Title(name)] = &compiler.Artifact{
Abi: string(art.Abi),
Bin: "0x" + art.Bytecode,
}
}
return artifacts, nil
}

0 comments on commit e89ce3d

Please sign in to comment.