github.com/0xsequence/ethkit@v1.25.0/cmd/ethkit/abigen.go (about)

     1  package main
     2  
     3  import (
     4  	"fmt"
     5  	"log"
     6  	"os"
     7  	"strings"
     8  
     9  	"github.com/0xsequence/ethkit/ethartifact"
    10  	"github.com/0xsequence/ethkit/go-ethereum/accounts/abi/bind"
    11  	"github.com/spf13/cobra"
    12  )
    13  
    14  func init() {
    15  	abigen := &abigen{}
    16  	cmd := &cobra.Command{
    17  		Use:   "abigen",
    18  		Short: "Generate contract Go client code from an abi or truffle artifacts file",
    19  		Run:   abigen.Run,
    20  	}
    21  
    22  	cmd.Flags().String("artifactsFile", "", "path to truffle contract artifacts file")
    23  	cmd.Flags().String("abiFile", "", "path to abi json file")
    24  	cmd.Flags().String("lang", "", "target language, supported: [go], default=go")
    25  	cmd.Flags().String("pkg", "", "pkg (optional)")
    26  	cmd.Flags().String("type", "", "type (optional)")
    27  	cmd.Flags().String("outFile", "", "outFile (optional), default=stdout")
    28  	cmd.Flags().Bool("includeDeployed", false, "include deployed bytecode on the generated file")
    29  
    30  	rootCmd.AddCommand(cmd)
    31  }
    32  
    33  type abigen struct {
    34  	fArtifactsFile   string
    35  	fAbiFile         string
    36  	fPkg             string
    37  	fType            string
    38  	fOutFile         string
    39  	fIncludeDeployed bool
    40  }
    41  
    42  func (c *abigen) Run(cmd *cobra.Command, args []string) {
    43  	c.fArtifactsFile, _ = cmd.Flags().GetString("artifactsFile")
    44  	c.fAbiFile, _ = cmd.Flags().GetString("abiFile")
    45  	c.fPkg, _ = cmd.Flags().GetString("pkg")
    46  	c.fType, _ = cmd.Flags().GetString("type")
    47  	c.fOutFile, _ = cmd.Flags().GetString("outFile")
    48  	c.fIncludeDeployed, _ = cmd.Flags().GetBool("includeDeployed")
    49  
    50  	if c.fArtifactsFile == "" && c.fAbiFile == "" {
    51  		fmt.Println("error: please pass one of --artifactsFile or --abiFile")
    52  		help(cmd)
    53  		return
    54  	}
    55  
    56  	if c.fAbiFile != "" && c.fPkg == "" {
    57  		fmt.Println("error: please pass --pkg")
    58  		help(cmd)
    59  		return
    60  	}
    61  	if c.fAbiFile != "" && c.fType == "" {
    62  		fmt.Println("error: please pass --pkg")
    63  		help(cmd)
    64  		return
    65  	}
    66  
    67  	var artifact ethartifact.RawArtifact
    68  	var err error
    69  
    70  	if c.fArtifactsFile != "" {
    71  		artifact, err = ethartifact.ParseArtifactFile(c.fArtifactsFile)
    72  		if err != nil {
    73  			log.Fatal(err)
    74  			return
    75  		}
    76  	} else {
    77  		abiData, err := os.ReadFile(c.fAbiFile)
    78  		if err != nil {
    79  			log.Fatal(err)
    80  			return
    81  		}
    82  		artifact = ethartifact.RawArtifact{ABI: abiData}
    83  	}
    84  
    85  	if err := c.generateGo(artifact); err != nil {
    86  		log.Fatal(err)
    87  		return
    88  	}
    89  }
    90  
    91  func (c *abigen) generateGo(artifact ethartifact.RawArtifact) error {
    92  	var (
    93  		abis  []string
    94  		bins  []string
    95  		dbins []string
    96  		types []string
    97  		sigs  []map[string]string
    98  		libs  = make(map[string]string)
    99  		lang  = bind.LangGo
   100  	)
   101  
   102  	if strings.Contains(string(artifact.Bytecode), "//") {
   103  		log.Fatal("Contract has additional library references, which is unsupported at this time.")
   104  	}
   105  
   106  	var pkgName string
   107  	if c.fPkg != "" {
   108  		pkgName = c.fPkg
   109  	} else {
   110  		pkgName = strings.ToLower(artifact.ContractName)
   111  	}
   112  
   113  	var typeName string
   114  	if c.fType != "" {
   115  		typeName = c.fType
   116  	} else {
   117  		typeName = artifact.ContractName
   118  	}
   119  
   120  	types = append(types, typeName)
   121  	abis = append(abis, string(artifact.ABI))
   122  	bins = append(bins, artifact.Bytecode)
   123  	aliases := map[string]string{}
   124  
   125  	if c.fIncludeDeployed {
   126  		dbins = append(dbins, artifact.DeployedBytecode)
   127  
   128  		if strings.Contains(string(artifact.DeployedBytecode), "//") {
   129  			log.Fatal("Contract has additional library references, which is unsupported at this time.")
   130  		}
   131  	} else {
   132  		dbins = append(dbins, "")
   133  	}
   134  
   135  	code, err := bind.Bind(types, abis, bins, dbins, sigs, pkgName, lang, libs, aliases)
   136  	if err != nil {
   137  		return err
   138  	}
   139  
   140  	if c.fOutFile == "" {
   141  		fmt.Println(code)
   142  	} else {
   143  		if err := os.WriteFile(c.fOutFile, []byte(code), 0600); err != nil {
   144  			return err
   145  		}
   146  	}
   147  
   148  	return nil
   149  }