├── testexample └── example │ └── example.go ├── example ├── generate.go ├── example.sol ├── ethgen.go ├── artifacts │ ├── Example.bin │ └── Example.abi.json ├── test │ └── example_test.go └── bindings │ └── example.handlers.go ├── main.go ├── parser ├── README.md ├── parser.go ├── parser_test.go ├── Solidity.tokens ├── SolidityLexer.tokens ├── Solidity.g4 ├── solidity_listener.go └── solidity_base_listener.go ├── .gitignore ├── engine └── engine.go ├── .github └── workflows │ └── test.yml ├── cmd ├── root.go ├── bind.go └── compile.go ├── LICENSE ├── codegen ├── contract.go ├── generate.go ├── fake.go ├── processor.go ├── fake_test.go └── contract_test.go ├── README.md ├── solc ├── compiler.go └── solc.go ├── CLAUDE.md ├── test └── chain.go ├── go.mod └── go.sum /testexample/example/example.go: -------------------------------------------------------------------------------- 1 | package example 2 | 3 | type TestInput struct{} 4 | -------------------------------------------------------------------------------- /example/generate.go: -------------------------------------------------------------------------------- 1 | package example 2 | 3 | type TestInput struct{} 4 | 5 | //go:generate go run ethgen.go 6 | -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "github.com/withtally/synceth/cmd" 5 | ) 6 | 7 | func main() { 8 | cmd.Execute() 9 | } 10 | -------------------------------------------------------------------------------- /parser/README.md: -------------------------------------------------------------------------------- 1 | # Parser 2 | 3 | Golang solidity parser. antlr spec taken from https://github.com/solidity-parser/antlr/blob/master/Solidity.g4 4 | 5 | ## Generating 6 | 7 | ``` 8 | antlr -Dlanguage=Go parser/Solidity.g4 9 | ``` -------------------------------------------------------------------------------- /example/example.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0 2 | pragma solidity ^0.8.3; 3 | 4 | contract Example { 5 | string private _exampleValue = "ethgen"; 6 | event ExampleEvent(string value); 7 | 8 | function exampleValue() public view returns (string memory) { 9 | return _exampleValue; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Binaries for programs and plugins 2 | *.exe 3 | *.exe~ 4 | *.dll 5 | *.so 6 | *.dylib 7 | 8 | # Test binary, built with `go test -c` 9 | *.test 10 | 11 | # Output of the go coverage tool 12 | *.out 13 | coverage.html 14 | 15 | # Go workspace file 16 | go.work 17 | 18 | # IDE files 19 | .vscode/ 20 | .idea/ 21 | 22 | # OS files 23 | .DS_Store 24 | 25 | # Project specific 26 | /ethgen 27 | /example/ethgen 28 | /artifacts/ 29 | /bindings/ -------------------------------------------------------------------------------- /engine/engine.go: -------------------------------------------------------------------------------- 1 | package engine 2 | 3 | import ( 4 | "context" 5 | "math/big" 6 | 7 | "github.com/ethereum/go-ethereum" 8 | "github.com/ethereum/go-ethereum/accounts/abi/bind" 9 | ) 10 | 11 | type Client interface { 12 | ethereum.ChainReader 13 | ethereum.ChainStateReader 14 | ethereum.TransactionReader 15 | bind.ContractBackend 16 | ChainID(ctx context.Context) (*big.Int, error) 17 | BlockNumber(ctx context.Context) (uint64, error) 18 | } 19 | -------------------------------------------------------------------------------- /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: Test and Coverage 2 | 3 | on: 4 | push: 5 | branches: [ main, chore/migrate-go ] 6 | pull_request: 7 | branches: [ main ] 8 | 9 | jobs: 10 | test: 11 | runs-on: ubuntu-latest 12 | 13 | steps: 14 | - uses: actions/checkout@v4 15 | 16 | - name: Set up Go 17 | uses: actions/setup-go@v5 18 | with: 19 | go-version: '1.23.0' 20 | 21 | - name: Install dependencies 22 | run: go mod download 23 | 24 | - name: Run tests 25 | run: go test ./... -------------------------------------------------------------------------------- /cmd/root.go: -------------------------------------------------------------------------------- 1 | package cmd 2 | 3 | import ( 4 | "fmt" 5 | "io/ioutil" 6 | "log" 7 | "os" 8 | 9 | "github.com/urfave/cli/v2" 10 | ) 11 | 12 | func Execute() { 13 | app := cli.NewApp() 14 | app.Name = "ethgen" 15 | app.Usage = compileCmd.Usage 16 | app.Description = "This is a library for generating creating strictly typed ethereum modules." 17 | app.HideVersion = true 18 | app.Before = func(context *cli.Context) error { 19 | if context.Bool("verbose") { 20 | log.SetFlags(0) 21 | } else { 22 | log.SetOutput(ioutil.Discard) 23 | } 24 | return nil 25 | } 26 | 27 | app.Action = compileCmd.Action 28 | app.Commands = []*cli.Command{ 29 | bindCmd, 30 | compileCmd, 31 | } 32 | 33 | if err := app.Run(os.Args); err != nil { 34 | fmt.Fprint(os.Stderr, err.Error()+"\n") 35 | os.Exit(1) 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /cmd/bind.go: -------------------------------------------------------------------------------- 1 | package cmd 2 | 3 | import ( 4 | "path/filepath" 5 | 6 | "github.com/urfave/cli/v2" 7 | "github.com/withtally/synceth/codegen" 8 | ) 9 | 10 | var bindCmd = &cli.Command{ 11 | Name: "bind", 12 | Usage: "create ethereum contract bindings from a abis", 13 | Flags: []cli.Flag{ 14 | &cli.StringFlag{Name: "outdir", Usage: "output directory"}, 15 | &cli.BoolFlag{Name: "fakes", Usage: "generate fakes"}, 16 | &cli.BoolFlag{Name: "handlers", Usage: "write handlers"}, 17 | &cli.BoolFlag{Name: "verbose, v", Usage: "show logs"}, 18 | }, 19 | Action: func(ctx *cli.Context) error { 20 | path, err := filepath.Abs(ctx.Args().First()) 21 | if err != nil { 22 | return err 23 | } 24 | 25 | outdir, err := filepath.Abs(ctx.String("outdir")) 26 | if err != nil { 27 | return err 28 | } 29 | 30 | return codegen.GenerateBindings(path, outdir, &codegen.BindingsConfig{ 31 | Fakes: ctx.Bool("fakes"), 32 | Handlers: codegen.HandlersConfig{ 33 | Generate: ctx.Bool("handlers"), 34 | }, 35 | }) 36 | }, 37 | } 38 | -------------------------------------------------------------------------------- /example/ethgen.go: -------------------------------------------------------------------------------- 1 | //go:build ignore 2 | // +build ignore 3 | 4 | package main 5 | 6 | import ( 7 | "log" 8 | 9 | "github.com/withtally/synceth/codegen" 10 | "github.com/withtally/synceth/example" 11 | testexample "github.com/withtally/synceth/testexample/example" 12 | ) 13 | 14 | func main() { 15 | tea := "testexample" 16 | solversion := "0.8.0" 17 | if err := codegen.GenerateBindings("./artifacts", "./bindings", &codegen.BindingsConfig{ 18 | Fakes: true, 19 | FakesVersion: &solversion, 20 | Handlers: codegen.HandlersConfig{ 21 | Generate: true, 22 | InputTypes: []codegen.InputType{ 23 | { 24 | Name: "tx", Type: &example.TestInput{}, 25 | }, 26 | { 27 | Name: "testtx", Type: &testexample.TestInput{}, Alias: &tea, 28 | }, 29 | }, 30 | }, 31 | Setup: codegen.SetupConfig{ 32 | InputTypes: []codegen.InputType{ 33 | { 34 | Name: "i", Type: &example.TestInput{}, 35 | }, 36 | }, 37 | }, 38 | }); err != nil { 39 | log.Fatalf("running ethgen codegen: %v", err) 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /parser/parser.go: -------------------------------------------------------------------------------- 1 | package parser 2 | 3 | import ( 4 | "strings" 5 | 6 | "github.com/Masterminds/semver/v3" 7 | "github.com/antlr/antlr4/runtime/Go/antlr" 8 | ) 9 | 10 | type solidityListener struct { 11 | *BaseSolidityListener 12 | Constraints []string 13 | } 14 | 15 | func (s *solidityListener) EnterVersionConstraint(ctx *VersionConstraintContext) { 16 | s.Constraints = append(s.Constraints, ctx.GetText()) 17 | } 18 | 19 | type VersionConstraint struct { 20 | semver.Constraints 21 | } 22 | 23 | func NewVersionConstraint(data string) (*VersionConstraint, error) { 24 | input := antlr.NewInputStream(data) 25 | lexer := NewSolidityLexer(input) 26 | stream := antlr.NewCommonTokenStream(lexer, 0) 27 | p := NewSolidityParser(stream) 28 | p.BuildParseTrees = true 29 | tree := p.SourceUnit() 30 | l := solidityListener{} 31 | antlr.ParseTreeWalkerDefault.Walk(&l, tree) 32 | 33 | s := strings.Join(l.Constraints, ",") 34 | c, err := semver.NewConstraint(s) 35 | if err != nil { 36 | return nil, err 37 | } 38 | 39 | return &VersionConstraint{*c}, nil 40 | } 41 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Tally 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /example/artifacts/Example.bin: -------------------------------------------------------------------------------- 1 | 0x60c0604052600660808190526532ba3433b2b760d11b60a0908152610027916000919061003a565b5034801561003457600080fd5b5061010e565b828054610046906100d3565b90600052602060002090601f01602090048101928261006857600085556100ae565b82601f1061008157805160ff19168380011785556100ae565b828001600101855582156100ae579182015b828111156100ae578251825591602001919060010190610093565b506100ba9291506100be565b5090565b5b808211156100ba57600081556001016100bf565b600181811c908216806100e757607f821691505b6020821081141561010857634e487b7160e01b600052602260045260246000fd5b50919050565b6101a68061011d6000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c8063d8f7c4cf14610030575b600080fd5b61003861004e565b60405161004591906100e0565b60405180910390f35b60606000805461005d90610135565b80601f016020809104026020016040519081016040528092919081815260200182805461008990610135565b80156100d65780601f106100ab576101008083540402835291602001916100d6565b820191906000526020600020905b8154815290600101906020018083116100b957829003601f168201915b5050505050905090565b600060208083528351808285015260005b8181101561010d578581018301518582016040015282016100f1565b8181111561011f576000604083870101525b50601f01601f1916929092016040019392505050565b600181811c9082168061014957607f821691505b6020821081141561016a57634e487b7160e01b600052602260045260246000fd5b5091905056fea2646970667358221220d432acfc601a55b38872c4482f4ff23a49d4b5ed1caa9f6ba25dbf74dff0072364736f6c634300080a0033 -------------------------------------------------------------------------------- /codegen/contract.go: -------------------------------------------------------------------------------- 1 | package codegen 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | "strings" 7 | 8 | "github.com/ethereum/go-ethereum/crypto" 9 | "github.com/withtally/synceth/solc" 10 | ) 11 | 12 | const ( 13 | SolidityBase = "https://github.com/ethereum/solidity/releases/download/" 14 | SolidityLinux = "solc-static-linux" 15 | SolidityMacos = "solc-macos" 16 | ) 17 | 18 | type ContractMetadata struct { 19 | ABIs []string 20 | Bins []string 21 | Types []string 22 | Sigs []map[string]string 23 | Libs map[string]string 24 | } 25 | 26 | func ParseContract(src string) (ContractMetadata, error) { 27 | var ( 28 | abis []string 29 | bins []string 30 | types []string 31 | sigs []map[string]string 32 | libs = make(map[string]string) 33 | ) 34 | 35 | contracts, err := solc.CompileSolidityString(src) 36 | if err != nil { 37 | return ContractMetadata{}, fmt.Errorf("compiling: %w", err) 38 | } 39 | 40 | for n, c := range contracts { 41 | abi, err := json.Marshal(c.Info.AbiDefinition) 42 | if err != nil { 43 | return ContractMetadata{}, fmt.Errorf("marshalling abi: %w", err) 44 | } 45 | 46 | abis = append(abis, string(abi)) 47 | bins = append(bins, c.Code) 48 | sigs = append(sigs, c.Hashes) 49 | nameParts := strings.Split(n, ":") 50 | types = append(types, nameParts[len(nameParts)-1]) 51 | libPattern := crypto.Keccak256Hash([]byte(n)).String()[2:36] 52 | libs[libPattern] = nameParts[len(nameParts)-1] 53 | } 54 | 55 | return ContractMetadata{ 56 | ABIs: abis, 57 | Bins: bins, 58 | Types: types, 59 | Sigs: sigs, 60 | Libs: libs, 61 | }, nil 62 | } 63 | -------------------------------------------------------------------------------- /parser/parser_test.go: -------------------------------------------------------------------------------- 1 | package parser 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | 7 | "github.com/Masterminds/semver/v3" 8 | ) 9 | 10 | func TestVersionConstraint(t *testing.T) { 11 | type match struct { 12 | version string 13 | err bool 14 | } 15 | 16 | for _, tc := range []struct { 17 | pragma string 18 | matches []match 19 | }{ 20 | {pragma: "^0.5.16", matches: []match{ 21 | {"0.5.16", false}, 22 | {"0.5.104", false}, 23 | {"0.5.15", true}, 24 | {"0.6.0", true}, 25 | }}, 26 | {pragma: ">=0.4.16 <0.9.0", matches: []match{ 27 | {"0.4.16", false}, 28 | {"0.8.104", false}, 29 | {"0.6.0", false}, 30 | {"0.9.9", true}, 31 | }}, 32 | {pragma: "=0.7.6", matches: []match{ 33 | {"0.7.6", false}, 34 | {"0.5.16", true}, 35 | {"0.7.7", true}, 36 | }}, 37 | } { 38 | c, err := NewVersionConstraint(fmt.Sprintf(` 39 | pragma solidity %s; 40 | 41 | contract Test {} 42 | `, tc.pragma)) 43 | if err != nil { 44 | t.Fatalf("parsing pargma: %v", err) 45 | } 46 | 47 | for _, m := range tc.matches { 48 | v, err := semver.NewVersion(m.version) 49 | if err != nil { 50 | t.Errorf("parsing match version %s: %v", m.version, err) 51 | break 52 | } 53 | 54 | ok := c.Check(v) 55 | if !m.err && !ok { 56 | t.Errorf("validating constraints %s for version %s: %v", tc.pragma, m.version, err) 57 | } else if m.err && ok { 58 | t.Errorf("constraint %s validation should fail for version %s", tc.pragma, m.version) 59 | } 60 | 61 | if !m.err && !ok { 62 | t.Errorf("validating constraints %s for version %s: %v", tc.pragma, m.version, err) 63 | } 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /example/artifacts/Example.abi.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "anonymous": false, 4 | "inputs": [ 5 | { 6 | "indexed": false, 7 | "internalType": "string", 8 | "name": "value", 9 | "type": "string" 10 | } 11 | ], 12 | "name": "ExampleEvent", 13 | "type": "event" 14 | }, 15 | { 16 | "inputs": [], 17 | "name": "exampleValue", 18 | "outputs": [ 19 | { 20 | "internalType": "string", 21 | "name": "", 22 | "type": "string" 23 | } 24 | ], 25 | "stateMutability": "view", 26 | "type": "function" 27 | }, 28 | { 29 | "anonymous": false, 30 | "inputs": [ 31 | { 32 | "indexed": false, 33 | "internalType": "bytes32", 34 | "name": "withdrawalRoot", 35 | "type": "bytes32" 36 | }, 37 | { 38 | "components": [ 39 | { 40 | "internalType": "address", 41 | "name": "staker", 42 | "type": "address" 43 | }, 44 | { 45 | "internalType": "address", 46 | "name": "delegatedTo", 47 | "type": "address" 48 | }, 49 | { 50 | "internalType": "address", 51 | "name": "withdrawer", 52 | "type": "address" 53 | }, 54 | { 55 | "internalType": "uint256", 56 | "name": "nonce", 57 | "type": "uint256" 58 | }, 59 | { 60 | "internalType": "uint32", 61 | "name": "startBlock", 62 | "type": "uint32" 63 | }, 64 | { 65 | "internalType": "contract IStrategy[]", 66 | "name": "strategies", 67 | "type": "address[]" 68 | }, 69 | { 70 | "internalType": "uint256[]", 71 | "name": "shares", 72 | "type": "uint256[]" 73 | } 74 | ], 75 | "indexed": false, 76 | "internalType": "struct IDelegationManager.Withdrawal", 77 | "name": "withdrawal", 78 | "type": "tuple" 79 | } 80 | ], 81 | "name": "WithdrawalQueued", 82 | "type": "event" 83 | } 84 | ] 85 | -------------------------------------------------------------------------------- /example/test/example_test.go: -------------------------------------------------------------------------------- 1 | package test 2 | 3 | import ( 4 | "context" 5 | "testing" 6 | 7 | "github.com/withtally/synceth/example/bindings" 8 | "github.com/withtally/synceth/test" 9 | ) 10 | 11 | func TestExample(t *testing.T) { 12 | ctx := context.Background() 13 | 14 | // Create eth signer. 15 | auth, err := test.NewAuth(ctx) 16 | if err != nil { 17 | t.Fatalf("Creating auth: %v", err) 18 | } 19 | 20 | eth := test.NewSimulatedBackend(t, auth) 21 | 22 | _, _, c, err := bindings.DeployExample(auth, eth) 23 | if err != nil { 24 | t.Fatalf("Failed to deploy contract: %v", err) 25 | } 26 | 27 | // Commit block to the blockchain. 28 | eth.Commit() 29 | 30 | want := "ethgen" 31 | got, err := c.ExampleValue(nil) 32 | if err != nil { 33 | t.Fatalf("Calling ExampleValue: %v", err) 34 | } 35 | 36 | if got != want { 37 | t.Errorf("ExampleValue got: %s, want: %s", got, want) 38 | } 39 | } 40 | 41 | func TestFakeExample(t *testing.T) { 42 | ctx := context.Background() 43 | 44 | // Create eth signer. 45 | auth, err := test.NewAuth(ctx) 46 | if err != nil { 47 | t.Fatalf("Creating auth: %v", err) 48 | } 49 | 50 | eth := test.NewSimulatedBackend(t, auth) 51 | 52 | _, _, c, err := bindings.DeployFakeExample(auth, eth) 53 | if err != nil { 54 | t.Fatalf("Failed to deploy contract: %v", err) 55 | } 56 | 57 | // Commit the deployment 58 | eth.Commit() 59 | 60 | // Set return value for `exampleValue` 61 | tx, err := c.FakeSetExampleValue(auth, "notethgen") 62 | if err != nil { 63 | t.Fatalf("Failed to set example value: %v", err) 64 | } 65 | 66 | // Commit block to include the transaction 67 | eth.Commit() 68 | 69 | // Wait for transaction receipt to ensure it's mined 70 | receipt, err := eth.TransactionReceipt(ctx, tx.Hash()) 71 | if err != nil { 72 | t.Fatalf("Failed to get transaction receipt: %v", err) 73 | } 74 | if receipt.Status != 1 { 75 | t.Fatalf("Transaction failed with status: %d", receipt.Status) 76 | } 77 | 78 | want := "notethgen" 79 | got, err := c.ExampleValue(nil) 80 | if err != nil { 81 | t.Fatalf("Calling ExampleValue: %v", err) 82 | } 83 | 84 | if got != want { 85 | t.Errorf("ExampleValue got: %s, want: %s", got, want) 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ethgen - A smart contract development toolchain for Go 2 | 3 | A simple yet powerful toolchain for Go based smart contract development 4 | 5 | - Compile solidity contracts and generate `.abi` and `.bin` artifacts. 6 | - Solidity compiler resolution and management. 7 | - Generate golang bindings from contract artifacts. 8 | - Generate contract fakes for smart contract testing. 9 | - Generate event handlers for smart contract indexing. 10 | 11 | ## Compiling smart contracts 12 | 13 | Create a `generate.go` file and add the following: 14 | 15 | ``` 16 | //go:generate go run -mod=mod github.com/withtally/synceth compile --outdir ./artifacts ./solidity 17 | ``` 18 | 19 | ## Generating bindings 20 | 21 | Create a `generate.go` file and add the following: 22 | 23 | ``` 24 | //go:generate go run -mod=mod github.com/withtally/synceth bind --handlers --fakes --outdir ./bindings ./artifacts 25 | ``` 26 | 27 | ## Using Fakes 28 | 29 | When `--fakes` is specified for binding generation, smart contract fakes will be generated based on the abi. A smart contract fake implements the full abi interface and adds additional methods for easily setting function return values and emitting events. 30 | 31 | For example, a contract like: 32 | 33 | ```solidity 34 | contract Example { 35 | event ExampleEvent(string value); 36 | function getValue() public returns (string value); 37 | } 38 | ``` 39 | 40 | Will generate a fake with interface: 41 | 42 | ```solidity 43 | contract FakeExample { 44 | event ExampleEvent(string value); 45 | function exampleValue() public returns (string value); 46 | 47 | function fakeSetExampleValue(string value); 48 | function fakeEmitExampleEvent(string value); 49 | } 50 | ``` 51 | 52 | The fake methods can be used to set the return value of the `exampleValue` function and to easily emit the `ExampleEvent`. 53 | 54 | Using the fake: 55 | 56 | ```go 57 | address, tx, c, err := bindings.DeployFakeExample(auth, eth) 58 | if err != nil { 59 | t.Fatalf("Deploying contract: %v", err) 60 | } 61 | 62 | if _, err := c.FakeSetExampleValue(auth, "tally"); err != nil { 63 | t.Fatalf("Setting value: %v", err) 64 | } 65 | 66 | eth.Commit() 67 | 68 | v, err := c.exampleValue(nil) 69 | if err != nil { 70 | t.Fatalf("Getting value: %v", err) 71 | } 72 | 73 | println(v) // tally 74 | ``` 75 | -------------------------------------------------------------------------------- /cmd/compile.go: -------------------------------------------------------------------------------- 1 | package cmd 2 | 3 | import ( 4 | "bytes" 5 | "encoding/json" 6 | "fmt" 7 | "io/ioutil" 8 | "os" 9 | "path/filepath" 10 | 11 | "github.com/urfave/cli/v2" 12 | "github.com/withtally/synceth/codegen" 13 | ) 14 | 15 | var compileCmd = &cli.Command{ 16 | Name: "compile", 17 | Usage: "compile ethereum contract bindings", 18 | Flags: []cli.Flag{ 19 | &cli.StringFlag{Name: "outdir", Usage: "output directory"}, 20 | &cli.BoolFlag{Name: "abis", Usage: "write abis"}, 21 | &cli.BoolFlag{Name: "handlers", Usage: "write handlers"}, 22 | &cli.BoolFlag{Name: "verbose, v", Usage: "show logs"}, 23 | }, 24 | Action: func(ctx *cli.Context) error { 25 | path, err := filepath.Abs(ctx.Args().First()) 26 | if err != nil { 27 | return err 28 | } 29 | 30 | outdir, err := filepath.Abs(ctx.String("outdir")) 31 | if err != nil { 32 | return err 33 | } 34 | 35 | if err := os.MkdirAll(outdir, os.ModePerm); err != nil { 36 | return err 37 | } 38 | 39 | if err := os.Chdir(path); err != nil { 40 | return fmt.Errorf("changing working directory: %w", err) 41 | } 42 | 43 | if err := filepath.Walk(path, 44 | func(path string, info os.FileInfo, err error) error { 45 | if err != nil { 46 | return err 47 | } 48 | if info.IsDir() { 49 | return nil 50 | } 51 | 52 | if matched, err := filepath.Match("*.sol", filepath.Base(path)); err != nil { 53 | return err 54 | } else if matched { 55 | dir, _ := filepath.Split(path) 56 | 57 | if outdir == "" { 58 | outdir = dir 59 | } 60 | 61 | buf, err := ioutil.ReadFile(path) 62 | if err != nil { 63 | return fmt.Errorf("reading solidity: %w", err) 64 | } 65 | 66 | md, err := codegen.ParseContract(string(buf)) 67 | if err != nil { 68 | return err 69 | } 70 | 71 | for i, t := range md.Types { 72 | var pretty bytes.Buffer 73 | if err := json.Indent(&pretty, []byte(md.ABIs[i]), "", "\t"); err != nil { 74 | return fmt.Errorf("prettifying abi: %w", err) 75 | } 76 | 77 | if err := ioutil.WriteFile(filepath.Join(outdir, t+".abi"), pretty.Bytes(), 0600); err != nil { 78 | return fmt.Errorf("writing abi: %w", err) 79 | } 80 | 81 | if err := ioutil.WriteFile(filepath.Join(outdir, t+".bin"), []byte(md.Bins[i]), 0600); err != nil { 82 | return fmt.Errorf("writing bin: %w", err) 83 | } 84 | } 85 | } 86 | return nil 87 | }, 88 | ); err != nil { 89 | return err 90 | } 91 | return nil 92 | }, 93 | } 94 | -------------------------------------------------------------------------------- /solc/compiler.go: -------------------------------------------------------------------------------- 1 | package solc 2 | 3 | import ( 4 | "bytes" 5 | "errors" 6 | "fmt" 7 | "os/exec" 8 | "regexp" 9 | "strconv" 10 | "strings" 11 | 12 | "github.com/ethereum/go-ethereum/common/compiler" 13 | ) 14 | 15 | var versionRegexp = regexp.MustCompile(`([0-9]+)\.([0-9]+)\.([0-9]+)`) 16 | 17 | 18 | // Solidity contains information about the solidity compiler. 19 | type Solidity struct { 20 | Path, Version, FullVersion string 21 | Major, Minor, Patch int 22 | } 23 | 24 | 25 | func (s *Solidity) makeArgs() []string { 26 | p := []string{ 27 | "--combined-json", "bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc", 28 | "--optimize", // code optimizer switched on 29 | "--allow-paths", "., ./, ../", // default to support relative paths 30 | } 31 | if s.Major > 0 || s.Minor > 4 || s.Patch > 6 { 32 | p[1] += ",metadata,hashes" 33 | } 34 | return p 35 | } 36 | 37 | // SolidityVersion runs solc and parses its version output. 38 | func SolidityVersion(solc string) (*Solidity, error) { 39 | if solc == "" { 40 | solc = "solc" 41 | } 42 | var out bytes.Buffer 43 | cmd := exec.Command(solc, "--version") 44 | cmd.Stdout = &out 45 | err := cmd.Run() 46 | if err != nil { 47 | return nil, err 48 | } 49 | matches := versionRegexp.FindStringSubmatch(out.String()) 50 | if len(matches) != 4 { 51 | return nil, fmt.Errorf("can't parse solc version %q", out.String()) 52 | } 53 | s := &Solidity{Path: cmd.Path, FullVersion: out.String(), Version: matches[0]} 54 | if s.Major, err = strconv.Atoi(matches[1]); err != nil { 55 | return nil, err 56 | } 57 | if s.Minor, err = strconv.Atoi(matches[2]); err != nil { 58 | return nil, err 59 | } 60 | if s.Patch, err = strconv.Atoi(matches[3]); err != nil { 61 | return nil, err 62 | } 63 | return s, nil 64 | } 65 | 66 | // compileSolidityString builds and returns all the contracts contained within a source string. 67 | func compileSolidityString(solc, source string) (map[string]*compiler.Contract, error) { 68 | if len(source) == 0 { 69 | return nil, errors.New("solc: empty source string") 70 | } 71 | s, err := SolidityVersion(solc) 72 | if err != nil { 73 | return nil, err 74 | } 75 | args := append(s.makeArgs(), "--") 76 | cmd := exec.Command(s.Path, append(args, "-")...) 77 | cmd.Stdin = strings.NewReader(source) 78 | return s.run(cmd, source) 79 | } 80 | 81 | func (s *Solidity) run(cmd *exec.Cmd, source string) (map[string]*compiler.Contract, error) { 82 | var stderr, stdout bytes.Buffer 83 | cmd.Stderr = &stderr 84 | cmd.Stdout = &stdout 85 | if err := cmd.Run(); err != nil { 86 | return nil, fmt.Errorf("solc: %v\n%s", err, stderr.Bytes()) 87 | } 88 | return compiler.ParseCombinedJSON(stdout.Bytes(), source, s.Version, s.Version, strings.Join(s.makeArgs(), " ")) 89 | } 90 | 91 | -------------------------------------------------------------------------------- /CLAUDE.md: -------------------------------------------------------------------------------- 1 | # CLAUDE.md 2 | 3 | This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. 4 | 5 | ## Project Overview 6 | 7 | synceth (also known as ethgen) is a smart contract development toolchain for Go that provides compilation, binding generation, and testing utilities for Ethereum smart contracts. 8 | 9 | ## Essential Commands 10 | 11 | ### Development 12 | ```bash 13 | # Run all tests (builds ethgen binary and runs example tests) 14 | task test 15 | 16 | # Run tests for a specific package 17 | go test ./example/test/... 18 | 19 | # Run all tests 20 | go test ./... 21 | 22 | # Format code 23 | go fmt ./... 24 | 25 | # Vet code 26 | go vet ./... 27 | ``` 28 | 29 | ### Code Generation Workflow 30 | ```bash 31 | # 1. Compile Solidity contracts to artifacts (.abi.json, .bin) 32 | go run . compile --outdir ./artifacts ./path/to/contracts 33 | 34 | # 2. Generate Go bindings from artifacts 35 | go run . bind --handlers --fakes --outdir ./bindings ./artifacts 36 | ``` 37 | 38 | ## Architecture Overview 39 | 40 | ### Core Components 41 | 42 | 1. **Parser (parser/)**: ANTLR-based Solidity parser that analyzes contract structure 43 | - Entry: `parser/parse.go` - Parses Solidity files into AST 44 | - Grammar: `parser/Solidity.g4` - Defines Solidity syntax 45 | 46 | 2. **Compiler Integration (solc/)**: Manages Solidity compiler versions 47 | - `solc/resolver.go` - Resolves and downloads compiler versions 48 | - `solc/compile.go` - Handles compilation process 49 | 50 | 3. **Code Generation (codegen/)**: Generates Go code from contract artifacts 51 | - `codegen/contract.go` - Main contract binding generation 52 | - `codegen/fake.go` - Test fake generation with setter/emitter methods 53 | - `codegen/processor.go` - Processes artifacts and coordinates generation 54 | 55 | 4. **CLI (cmd/)**: Command-line interface implementations 56 | - `cmd/compile.go` - Compile command implementation 57 | - `cmd/bind.go` - Bind command with --handlers and --fakes flags 58 | - `cmd/root.go` - CLI configuration and command registration 59 | 60 | ### Key Design Patterns 61 | 62 | 1. **Fake Contracts**: For testing, generates contracts with additional methods: 63 | - `fakeSet[MethodName]()` - Set return values for view/pure functions 64 | - `fakeEmit[EventName]()` - Programmatically emit events 65 | - Supports struct types as of recent updates 66 | 67 | 2. **Event Handlers**: Generated with `--handlers` flag, creates typed event handler interfaces for indexing 68 | 69 | 3. **Compiler Resolution**: Automatically downloads and manages Solidity compiler versions based on pragma statements 70 | 71 | ### Testing Approach 72 | 73 | Tests use simulated blockchain backend (`test.NewSimulatedBackend`) with deployed contracts. See `example/test/example_test.go` for patterns: 74 | - Deploy contracts using generated bindings 75 | - Use `eth.Commit()` to mine blocks 76 | - Test fakes by setting return values before calling methods -------------------------------------------------------------------------------- /test/chain.go: -------------------------------------------------------------------------------- 1 | package test 2 | 3 | import ( 4 | "context" 5 | "math/big" 6 | "testing" 7 | 8 | "github.com/ethereum/go-ethereum/accounts/abi/bind" 9 | "github.com/ethereum/go-ethereum/accounts/abi/bind/backends" 10 | "github.com/ethereum/go-ethereum/common" 11 | "github.com/ethereum/go-ethereum/consensus/ethash" 12 | "github.com/ethereum/go-ethereum/core" 13 | "github.com/ethereum/go-ethereum/core/rawdb" 14 | "github.com/ethereum/go-ethereum/core/types" 15 | "github.com/ethereum/go-ethereum/crypto" 16 | "github.com/ethereum/go-ethereum/eth" 17 | "github.com/ethereum/go-ethereum/eth/ethconfig" 18 | "github.com/ethereum/go-ethereum/ethclient" 19 | "github.com/ethereum/go-ethereum/node" 20 | "github.com/ethereum/go-ethereum/params" 21 | ) 22 | 23 | var ( 24 | TestKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") 25 | ) 26 | 27 | func NewAuth(ctx context.Context) (*bind.TransactOpts, error) { 28 | auth, err := bind.NewKeyedTransactorWithChainID(TestKey, big.NewInt(1337)) 29 | if err != nil { 30 | return nil, err 31 | } 32 | 33 | auth.Context = ctx 34 | return auth, nil 35 | } 36 | 37 | func NewTestChain(t testing.TB, auth *bind.TransactOpts) *ethclient.Client { 38 | t.Helper() 39 | 40 | address := auth.From 41 | db := rawdb.NewMemoryDatabase() 42 | genesis := &core.Genesis{ 43 | Config: params.AllEthashProtocolChanges, 44 | Alloc: core.GenesisAlloc{address: {Balance: big.NewInt(10000000000000000)}}, 45 | ExtraData: []byte("test genesis"), 46 | Timestamp: 9000, 47 | BaseFee: big.NewInt(params.InitialBaseFee), 48 | } 49 | generate := func(i int, g *core.BlockGen) { 50 | g.OffsetTime(5) 51 | g.SetExtra([]byte("test")) 52 | } 53 | gblock := genesis.ToBlock() 54 | engine := ethash.NewFaker() 55 | blocks, _ := core.GenerateChain(params.AllEthashProtocolChanges, gblock, engine, db, 1, generate) 56 | blocks = append([]*types.Block{gblock}, blocks...) 57 | 58 | // Create node 59 | n, err := node.New(&node.Config{}) 60 | if err != nil { 61 | t.Fatalf("can't create new node: %v", err) 62 | } 63 | // Create Ethereum Service 64 | config := ðconfig.Config{Genesis: genesis} 65 | ethservice, err := eth.New(n, config) 66 | if err != nil { 67 | t.Fatalf("can't create new ethereum service: %v", err) 68 | } 69 | // Import the test chain. 70 | if err := n.Start(); err != nil { 71 | t.Fatalf("can't start test node: %v", err) 72 | } 73 | if _, err := ethservice.BlockChain().InsertChain(blocks[1:]); err != nil { 74 | t.Fatalf("can't import test blocks: %v", err) 75 | } 76 | 77 | rpc := n.Attach() 78 | 79 | client := ethclient.NewClient(rpc) 80 | 81 | t.Cleanup(func() { 82 | client.Close() 83 | }) 84 | 85 | return client 86 | } 87 | 88 | // GETH's simulated backend is missing a few methods from the ethclient that we use. 89 | // This backend augments the simulated backend with those methods to simplify testing. 90 | type SimulatedBackend struct { 91 | *backends.SimulatedBackend 92 | } 93 | 94 | func NewSimulatedBackend(t testing.TB, auth *bind.TransactOpts) *SimulatedBackend { 95 | t.Helper() 96 | address := auth.From 97 | genesisAlloc := map[common.Address]core.GenesisAccount{ 98 | address: { 99 | Balance: big.NewInt(10000000000000000), 100 | }, 101 | } 102 | 103 | be := backends.NewSimulatedBackend(genesisAlloc, 10000000) 104 | 105 | // Commit an empty block to avoid negative indexer start blocks. 106 | be.Commit() 107 | return &SimulatedBackend{ 108 | be, 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /codegen/generate.go: -------------------------------------------------------------------------------- 1 | package codegen 2 | 3 | import ( 4 | "errors" 5 | "fmt" 6 | "io/ioutil" 7 | "os" 8 | "path/filepath" 9 | "strings" 10 | 11 | "github.com/ethereum/go-ethereum/accounts/abi/bind" 12 | ) 13 | 14 | type InputType struct { 15 | Name string 16 | Alias *string 17 | Type interface{} 18 | } 19 | 20 | type HandlersConfig struct { 21 | Generate bool 22 | InputTypes []InputType 23 | } 24 | 25 | type SetupConfig struct { 26 | InputTypes []InputType 27 | } 28 | 29 | type BindingsConfig struct { 30 | Fakes bool 31 | FakesVersion *string 32 | Handlers HandlersConfig 33 | Setup SetupConfig 34 | } 35 | 36 | func GenerateBindings(path string, outdir string, config *BindingsConfig) error { 37 | if err := os.MkdirAll(outdir, os.ModePerm); err != nil { 38 | return err 39 | } 40 | 41 | if err := filepath.Walk(path, 42 | func(path string, info os.FileInfo, err error) error { 43 | if err != nil { 44 | return err 45 | } 46 | if info.IsDir() { 47 | return nil 48 | } 49 | 50 | if matched, err := filepath.Match("*.abi.json", filepath.Base(path)); err != nil { 51 | return err 52 | } else if matched { 53 | dir, fn := filepath.Split(path) 54 | typ := strings.TrimSuffix(fn, ".abi.json") 55 | name := strings.ToLower(typ) 56 | pkg := strings.ToLower(filepath.Base(outdir)) 57 | 58 | if outdir == "" { 59 | pkg = filepath.Base(dir) 60 | outdir = dir 61 | } 62 | 63 | abi, err := ioutil.ReadFile(path) 64 | if err != nil { 65 | return fmt.Errorf("reading abi: %w", err) 66 | } 67 | 68 | bin, err := ioutil.ReadFile(filepath.Join(dir, typ+".bin")) 69 | if errors.Is(err, os.ErrNotExist) { 70 | bin = []byte{} 71 | } else if err != nil { 72 | return fmt.Errorf("reading abi: %w", err) 73 | } 74 | 75 | abis := []string{string(abi)} 76 | types := []string{typ} 77 | bins := []string{string(bin)} 78 | 79 | // We generate handlers first to avoid generating them for 80 | // fakes created below. 81 | if config.Handlers.Generate { 82 | handler, err := GenerateProcessor(types, abis, pkg, config.Handlers.InputTypes, config.Setup.InputTypes) 83 | if errors.Is(err, ErrNoEvents) { 84 | return nil 85 | } else if err != nil { 86 | return fmt.Errorf("generating handler: %w", err) 87 | } 88 | 89 | if err := ioutil.WriteFile(filepath.Join(outdir, name+".handlers.go"), []byte(handler), 0600); err != nil { 90 | return fmt.Errorf("writing handler: %w", err) 91 | } 92 | } 93 | 94 | if config.Fakes { 95 | fake, err := GenerateFake(types[0], abis[0], config.FakesVersion) 96 | if err != nil { 97 | return fmt.Errorf("generating fake: %w", err) 98 | } 99 | 100 | md, err := ParseContract(string(fake)) 101 | if err != nil { 102 | return err 103 | } 104 | 105 | types = append(types, md.Types...) 106 | bins = append(bins, md.Bins...) 107 | abis = append(abis, md.ABIs...) 108 | } 109 | 110 | // Generate the contract binding 111 | src, err := bind.Bind(types, abis, bins, nil, pkg, nil, nil) 112 | if err != nil { 113 | return fmt.Errorf("binding abi: %w", err) 114 | } 115 | 116 | if err := ioutil.WriteFile(filepath.Join(outdir, name+".go"), []byte(src), 0600); err != nil { 117 | return fmt.Errorf("writing ABI binding: %w", err) 118 | } 119 | } 120 | return nil 121 | }, 122 | ); err != nil { 123 | return err 124 | } 125 | 126 | return nil 127 | } 128 | -------------------------------------------------------------------------------- /parser/Solidity.tokens: -------------------------------------------------------------------------------- 1 | T__0=1 2 | T__1=2 3 | T__2=3 4 | T__3=4 5 | T__4=5 6 | T__5=6 7 | T__6=7 8 | T__7=8 9 | T__8=9 10 | T__9=10 11 | T__10=11 12 | T__11=12 13 | T__12=13 14 | T__13=14 15 | T__14=15 16 | T__15=16 17 | T__16=17 18 | T__17=18 19 | T__18=19 20 | T__19=20 21 | T__20=21 22 | T__21=22 23 | T__22=23 24 | T__23=24 25 | T__24=25 26 | T__25=26 27 | T__26=27 28 | T__27=28 29 | T__28=29 30 | T__29=30 31 | T__30=31 32 | T__31=32 33 | T__32=33 34 | T__33=34 35 | T__34=35 36 | T__35=36 37 | T__36=37 38 | T__37=38 39 | T__38=39 40 | T__39=40 41 | T__40=41 42 | T__41=42 43 | T__42=43 44 | T__43=44 45 | T__44=45 46 | T__45=46 47 | T__46=47 48 | T__47=48 49 | T__48=49 50 | T__49=50 51 | T__50=51 52 | T__51=52 53 | T__52=53 54 | T__53=54 55 | T__54=55 56 | T__55=56 57 | T__56=57 58 | T__57=58 59 | T__58=59 60 | T__59=60 61 | T__60=61 62 | T__61=62 63 | T__62=63 64 | T__63=64 65 | T__64=65 66 | T__65=66 67 | T__66=67 68 | T__67=68 69 | T__68=69 70 | T__69=70 71 | T__70=71 72 | T__71=72 73 | T__72=73 74 | T__73=74 75 | T__74=75 76 | T__75=76 77 | T__76=77 78 | T__77=78 79 | T__78=79 80 | T__79=80 81 | T__80=81 82 | T__81=82 83 | T__82=83 84 | T__83=84 85 | T__84=85 86 | T__85=86 87 | T__86=87 88 | T__87=88 89 | T__88=89 90 | T__89=90 91 | T__90=91 92 | T__91=92 93 | T__92=93 94 | T__93=94 95 | T__94=95 96 | T__95=96 97 | T__96=97 98 | Int=98 99 | Uint=99 100 | Byte=100 101 | Fixed=101 102 | Ufixed=102 103 | BooleanLiteral=103 104 | DecimalNumber=104 105 | HexNumber=105 106 | NumberUnit=106 107 | HexLiteralFragment=107 108 | ReservedKeyword=108 109 | AnonymousKeyword=109 110 | BreakKeyword=110 111 | ConstantKeyword=111 112 | ImmutableKeyword=112 113 | ContinueKeyword=113 114 | LeaveKeyword=114 115 | ExternalKeyword=115 116 | IndexedKeyword=116 117 | InternalKeyword=117 118 | PayableKeyword=118 119 | PrivateKeyword=119 120 | PublicKeyword=120 121 | VirtualKeyword=121 122 | PureKeyword=122 123 | TypeKeyword=123 124 | ViewKeyword=124 125 | ConstructorKeyword=125 126 | FallbackKeyword=126 127 | ReceiveKeyword=127 128 | Identifier=128 129 | StringLiteralFragment=129 130 | VersionLiteral=130 131 | WS=131 132 | COMMENT=132 133 | LINE_COMMENT=133 134 | 'pragma'=1 135 | ';'=2 136 | '||'=3 137 | '^'=4 138 | '~'=5 139 | '>='=6 140 | '>'=7 141 | '<'=8 142 | '<='=9 143 | '='=10 144 | 'as'=11 145 | 'import'=12 146 | '*'=13 147 | 'from'=14 148 | '{'=15 149 | ','=16 150 | '}'=17 151 | 'abstract'=18 152 | 'contract'=19 153 | 'interface'=20 154 | 'library'=21 155 | 'is'=22 156 | '('=23 157 | ')'=24 158 | 'error'=25 159 | 'using'=26 160 | 'for'=27 161 | 'struct'=28 162 | 'modifier'=29 163 | 'function'=30 164 | 'returns'=31 165 | 'event'=32 166 | 'enum'=33 167 | '['=34 168 | ']'=35 169 | 'address'=36 170 | '.'=37 171 | 'mapping'=38 172 | '=>'=39 173 | 'memory'=40 174 | 'storage'=41 175 | 'calldata'=42 176 | 'if'=43 177 | 'else'=44 178 | 'try'=45 179 | 'catch'=46 180 | 'while'=47 181 | 'unchecked'=48 182 | 'assembly'=49 183 | 'do'=50 184 | 'return'=51 185 | 'throw'=52 186 | 'emit'=53 187 | 'revert'=54 188 | 'var'=55 189 | 'bool'=56 190 | 'string'=57 191 | 'byte'=58 192 | '++'=59 193 | '--'=60 194 | 'new'=61 195 | ':'=62 196 | '+'=63 197 | '-'=64 198 | 'after'=65 199 | 'delete'=66 200 | '!'=67 201 | '**'=68 202 | '/'=69 203 | '%'=70 204 | '<<'=71 205 | '>>'=72 206 | '&'=73 207 | '|'=74 208 | '=='=75 209 | '!='=76 210 | '&&'=77 211 | '?'=78 212 | '|='=79 213 | '^='=80 214 | '&='=81 215 | '<<='=82 216 | '>>='=83 217 | '+='=84 218 | '-='=85 219 | '*='=86 220 | '/='=87 221 | '%='=88 222 | 'let'=89 223 | ':='=90 224 | '=:'=91 225 | 'switch'=92 226 | 'case'=93 227 | 'default'=94 228 | '->'=95 229 | 'callback'=96 230 | 'override'=97 231 | 'anonymous'=109 232 | 'break'=110 233 | 'constant'=111 234 | 'immutable'=112 235 | 'continue'=113 236 | 'leave'=114 237 | 'external'=115 238 | 'indexed'=116 239 | 'internal'=117 240 | 'payable'=118 241 | 'private'=119 242 | 'public'=120 243 | 'virtual'=121 244 | 'pure'=122 245 | 'type'=123 246 | 'view'=124 247 | 'constructor'=125 248 | 'fallback'=126 249 | 'receive'=127 250 | -------------------------------------------------------------------------------- /parser/SolidityLexer.tokens: -------------------------------------------------------------------------------- 1 | T__0=1 2 | T__1=2 3 | T__2=3 4 | T__3=4 5 | T__4=5 6 | T__5=6 7 | T__6=7 8 | T__7=8 9 | T__8=9 10 | T__9=10 11 | T__10=11 12 | T__11=12 13 | T__12=13 14 | T__13=14 15 | T__14=15 16 | T__15=16 17 | T__16=17 18 | T__17=18 19 | T__18=19 20 | T__19=20 21 | T__20=21 22 | T__21=22 23 | T__22=23 24 | T__23=24 25 | T__24=25 26 | T__25=26 27 | T__26=27 28 | T__27=28 29 | T__28=29 30 | T__29=30 31 | T__30=31 32 | T__31=32 33 | T__32=33 34 | T__33=34 35 | T__34=35 36 | T__35=36 37 | T__36=37 38 | T__37=38 39 | T__38=39 40 | T__39=40 41 | T__40=41 42 | T__41=42 43 | T__42=43 44 | T__43=44 45 | T__44=45 46 | T__45=46 47 | T__46=47 48 | T__47=48 49 | T__48=49 50 | T__49=50 51 | T__50=51 52 | T__51=52 53 | T__52=53 54 | T__53=54 55 | T__54=55 56 | T__55=56 57 | T__56=57 58 | T__57=58 59 | T__58=59 60 | T__59=60 61 | T__60=61 62 | T__61=62 63 | T__62=63 64 | T__63=64 65 | T__64=65 66 | T__65=66 67 | T__66=67 68 | T__67=68 69 | T__68=69 70 | T__69=70 71 | T__70=71 72 | T__71=72 73 | T__72=73 74 | T__73=74 75 | T__74=75 76 | T__75=76 77 | T__76=77 78 | T__77=78 79 | T__78=79 80 | T__79=80 81 | T__80=81 82 | T__81=82 83 | T__82=83 84 | T__83=84 85 | T__84=85 86 | T__85=86 87 | T__86=87 88 | T__87=88 89 | T__88=89 90 | T__89=90 91 | T__90=91 92 | T__91=92 93 | T__92=93 94 | T__93=94 95 | T__94=95 96 | T__95=96 97 | T__96=97 98 | Int=98 99 | Uint=99 100 | Byte=100 101 | Fixed=101 102 | Ufixed=102 103 | BooleanLiteral=103 104 | DecimalNumber=104 105 | HexNumber=105 106 | NumberUnit=106 107 | HexLiteralFragment=107 108 | ReservedKeyword=108 109 | AnonymousKeyword=109 110 | BreakKeyword=110 111 | ConstantKeyword=111 112 | ImmutableKeyword=112 113 | ContinueKeyword=113 114 | LeaveKeyword=114 115 | ExternalKeyword=115 116 | IndexedKeyword=116 117 | InternalKeyword=117 118 | PayableKeyword=118 119 | PrivateKeyword=119 120 | PublicKeyword=120 121 | VirtualKeyword=121 122 | PureKeyword=122 123 | TypeKeyword=123 124 | ViewKeyword=124 125 | ConstructorKeyword=125 126 | FallbackKeyword=126 127 | ReceiveKeyword=127 128 | Identifier=128 129 | StringLiteralFragment=129 130 | VersionLiteral=130 131 | WS=131 132 | COMMENT=132 133 | LINE_COMMENT=133 134 | 'pragma'=1 135 | ';'=2 136 | '||'=3 137 | '^'=4 138 | '~'=5 139 | '>='=6 140 | '>'=7 141 | '<'=8 142 | '<='=9 143 | '='=10 144 | 'as'=11 145 | 'import'=12 146 | '*'=13 147 | 'from'=14 148 | '{'=15 149 | ','=16 150 | '}'=17 151 | 'abstract'=18 152 | 'contract'=19 153 | 'interface'=20 154 | 'library'=21 155 | 'is'=22 156 | '('=23 157 | ')'=24 158 | 'error'=25 159 | 'using'=26 160 | 'for'=27 161 | 'struct'=28 162 | 'modifier'=29 163 | 'function'=30 164 | 'returns'=31 165 | 'event'=32 166 | 'enum'=33 167 | '['=34 168 | ']'=35 169 | 'address'=36 170 | '.'=37 171 | 'mapping'=38 172 | '=>'=39 173 | 'memory'=40 174 | 'storage'=41 175 | 'calldata'=42 176 | 'if'=43 177 | 'else'=44 178 | 'try'=45 179 | 'catch'=46 180 | 'while'=47 181 | 'unchecked'=48 182 | 'assembly'=49 183 | 'do'=50 184 | 'return'=51 185 | 'throw'=52 186 | 'emit'=53 187 | 'revert'=54 188 | 'var'=55 189 | 'bool'=56 190 | 'string'=57 191 | 'byte'=58 192 | '++'=59 193 | '--'=60 194 | 'new'=61 195 | ':'=62 196 | '+'=63 197 | '-'=64 198 | 'after'=65 199 | 'delete'=66 200 | '!'=67 201 | '**'=68 202 | '/'=69 203 | '%'=70 204 | '<<'=71 205 | '>>'=72 206 | '&'=73 207 | '|'=74 208 | '=='=75 209 | '!='=76 210 | '&&'=77 211 | '?'=78 212 | '|='=79 213 | '^='=80 214 | '&='=81 215 | '<<='=82 216 | '>>='=83 217 | '+='=84 218 | '-='=85 219 | '*='=86 220 | '/='=87 221 | '%='=88 222 | 'let'=89 223 | ':='=90 224 | '=:'=91 225 | 'switch'=92 226 | 'case'=93 227 | 'default'=94 228 | '->'=95 229 | 'callback'=96 230 | 'override'=97 231 | 'anonymous'=109 232 | 'break'=110 233 | 'constant'=111 234 | 'immutable'=112 235 | 'continue'=113 236 | 'leave'=114 237 | 'external'=115 238 | 'indexed'=116 239 | 'internal'=117 240 | 'payable'=118 241 | 'private'=119 242 | 'public'=120 243 | 'virtual'=121 244 | 'pure'=122 245 | 'type'=123 246 | 'view'=124 247 | 'constructor'=125 248 | 'fallback'=126 249 | 'receive'=127 250 | -------------------------------------------------------------------------------- /example/bindings/example.handlers.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/withtally/synceth, DO NOT EDIT. 2 | 3 | package bindings 4 | 5 | import ( 6 | "context" 7 | "fmt" 8 | "strings" 9 | 10 | "github.com/ethereum/go-ethereum" 11 | "github.com/ethereum/go-ethereum/accounts/abi" 12 | "github.com/ethereum/go-ethereum/accounts/abi/bind" 13 | "github.com/ethereum/go-ethereum/common" 14 | "github.com/ethereum/go-ethereum/core/types" 15 | 16 | "github.com/withtally/synceth/example" 17 | 18 | testexample "github.com/withtally/synceth/testexample/example" 19 | ) 20 | 21 | type ExampleProcessor interface { 22 | Setup(ctx context.Context, address common.Address, eth interface { 23 | ethereum.ChainReader 24 | ethereum.ChainStateReader 25 | ethereum.TransactionReader 26 | bind.ContractBackend 27 | }, i *example.TestInput) error 28 | Initialize(ctx context.Context, start uint64, tx *example.TestInput, testtx *testexample.TestInput) error 29 | 30 | ProcessExampleEvent(ctx context.Context, e ExampleExampleEvent) (func(tx *example.TestInput, testtx *testexample.TestInput) error, error) 31 | 32 | ProcessWithdrawalQueued(ctx context.Context, e ExampleWithdrawalQueued) (func(tx *example.TestInput, testtx *testexample.TestInput) error, error) 33 | 34 | mustEmbedBaseExampleProcessor() 35 | } 36 | 37 | type BaseExampleProcessor struct { 38 | Address common.Address 39 | ABI abi.ABI 40 | Contract *Example 41 | Eth interface { 42 | ethereum.ChainReader 43 | ethereum.ChainStateReader 44 | ethereum.TransactionReader 45 | bind.ContractBackend 46 | } 47 | } 48 | 49 | func (h *BaseExampleProcessor) Setup(ctx context.Context, address common.Address, eth interface { 50 | ethereum.ChainReader 51 | ethereum.ChainStateReader 52 | ethereum.TransactionReader 53 | bind.ContractBackend 54 | }, i *example.TestInput) error { 55 | contract, err := NewExample(address, eth) 56 | if err != nil { 57 | return fmt.Errorf("new Example: %w", err) 58 | } 59 | 60 | abi, err := abi.JSON(strings.NewReader(string(ExampleABI))) 61 | if err != nil { 62 | return fmt.Errorf("parsing Example abi: %w", err) 63 | } 64 | 65 | h.Address = address 66 | h.ABI = abi 67 | h.Contract = contract 68 | h.Eth = eth 69 | return nil 70 | } 71 | 72 | func (h *BaseExampleProcessor) ProcessElement(p interface{}) func(context.Context, types.Log) (func(*example.TestInput, *testexample.TestInput) error, error) { 73 | return func(ctx context.Context, vLog types.Log) (func(*example.TestInput, *testexample.TestInput) error, error) { 74 | switch vLog.Topics[0].Hex() { 75 | 76 | case h.ABI.Events["ExampleEvent"].ID.Hex(): 77 | e := ExampleExampleEvent{} 78 | if err := h.UnpackLog(&e, "ExampleEvent", vLog); err != nil { 79 | return nil, fmt.Errorf("unpacking ExampleEvent: %w", err) 80 | } 81 | 82 | e.Raw = vLog 83 | cb, err := p.(ExampleProcessor).ProcessExampleEvent(ctx, e) 84 | if err != nil { 85 | return nil, fmt.Errorf("processing ExampleEvent: %w", err) 86 | } 87 | 88 | return cb, nil 89 | 90 | case h.ABI.Events["WithdrawalQueued"].ID.Hex(): 91 | e := ExampleWithdrawalQueued{} 92 | if err := h.UnpackLog(&e, "WithdrawalQueued", vLog); err != nil { 93 | return nil, fmt.Errorf("unpacking WithdrawalQueued: %w", err) 94 | } 95 | 96 | e.Raw = vLog 97 | cb, err := p.(ExampleProcessor).ProcessWithdrawalQueued(ctx, e) 98 | if err != nil { 99 | return nil, fmt.Errorf("processing WithdrawalQueued: %w", err) 100 | } 101 | 102 | return cb, nil 103 | 104 | } 105 | return func(*example.TestInput, *testexample.TestInput) error { return nil }, nil 106 | } 107 | } 108 | 109 | func (h *BaseExampleProcessor) UnpackLog(out interface{}, event string, log types.Log) error { 110 | if len(log.Data) > 0 { 111 | if err := h.ABI.UnpackIntoInterface(out, event, log.Data); err != nil { 112 | return err 113 | } 114 | } 115 | var indexed abi.Arguments 116 | for _, arg := range h.ABI.Events[event].Inputs { 117 | if arg.Indexed { 118 | indexed = append(indexed, arg) 119 | } 120 | } 121 | return abi.ParseTopics(out, indexed, log.Topics[1:]) 122 | } 123 | 124 | func (h *BaseExampleProcessor) Initialize(ctx context.Context, start uint64, tx *example.TestInput, testtx *testexample.TestInput) error { 125 | return nil 126 | } 127 | 128 | func (h *BaseExampleProcessor) ProcessExampleEvent(ctx context.Context, e ExampleExampleEvent) (func(tx *example.TestInput, testtx *testexample.TestInput) error, error) { 129 | return func(tx *example.TestInput, testtx *testexample.TestInput) error { return nil }, nil 130 | } 131 | 132 | func (h *BaseExampleProcessor) ProcessWithdrawalQueued(ctx context.Context, e ExampleWithdrawalQueued) (func(tx *example.TestInput, testtx *testexample.TestInput) error, error) { 133 | return func(tx *example.TestInput, testtx *testexample.TestInput) error { return nil }, nil 134 | } 135 | 136 | func (h *BaseExampleProcessor) mustEmbedBaseExampleProcessor() {} 137 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/withtally/synceth 2 | 3 | go 1.23.0 4 | 5 | toolchain go1.23.10 6 | 7 | require ( 8 | github.com/Masterminds/semver/v3 v3.1.1 9 | github.com/antlr/antlr4/runtime/Go/antlr v0.0.0-20210826220005-b48c857c3a0e 10 | github.com/ethereum/go-ethereum v1.16.0 11 | github.com/shibukawa/configdir v0.0.0-20170330084843-e180dbdc8da0 12 | github.com/stretchr/testify v1.10.0 13 | github.com/urfave/cli/v2 v2.27.5 14 | ) 15 | 16 | require ( 17 | github.com/DataDog/zstd v1.5.2 // indirect 18 | github.com/Microsoft/go-winio v0.6.2 // indirect 19 | github.com/StackExchange/wmi v1.2.1 // indirect 20 | github.com/VictoriaMetrics/fastcache v1.12.2 // indirect 21 | github.com/beorn7/perks v1.0.1 // indirect 22 | github.com/bits-and-blooms/bitset v1.20.0 // indirect 23 | github.com/cespare/xxhash/v2 v2.3.0 // indirect 24 | github.com/cockroachdb/errors v1.11.3 // indirect 25 | github.com/cockroachdb/fifo v0.0.0-20240606204812-0bbfbd93a7ce // indirect 26 | github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b // indirect 27 | github.com/cockroachdb/pebble v1.1.5 // indirect 28 | github.com/cockroachdb/redact v1.1.5 // indirect 29 | github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 // indirect 30 | github.com/consensys/gnark-crypto v0.18.0 // indirect 31 | github.com/cpuguy83/go-md2man/v2 v2.0.5 // indirect 32 | github.com/crate-crypto/go-eth-kzg v1.3.0 // indirect 33 | github.com/crate-crypto/go-ipa v0.0.0-20240724233137-53bbb0ceb27a // indirect 34 | github.com/davecgh/go-spew v1.1.1 // indirect 35 | github.com/deckarep/golang-set/v2 v2.6.0 // indirect 36 | github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 // indirect 37 | github.com/ethereum/c-kzg-4844/v2 v2.1.0 // indirect 38 | github.com/ethereum/go-verkle v0.2.2 // indirect 39 | github.com/ferranbt/fastssz v0.1.2 // indirect 40 | github.com/fsnotify/fsnotify v1.6.0 // indirect 41 | github.com/getsentry/sentry-go v0.27.0 // indirect 42 | github.com/go-ole/go-ole v1.3.0 // indirect 43 | github.com/gofrs/flock v0.12.1 // indirect 44 | github.com/gogo/protobuf v1.3.2 // indirect 45 | github.com/golang-jwt/jwt/v4 v4.5.1 // indirect 46 | github.com/golang/protobuf v1.5.4 // indirect 47 | github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb // indirect 48 | github.com/google/go-cmp v0.6.0 // indirect 49 | github.com/google/uuid v1.3.0 // indirect 50 | github.com/gorilla/websocket v1.4.2 // indirect 51 | github.com/hashicorp/go-bexpr v0.1.10 // indirect 52 | github.com/holiman/billy v0.0.0-20240216141850-2abb0c79d3c4 // indirect 53 | github.com/holiman/bloomfilter/v2 v2.0.3 // indirect 54 | github.com/holiman/uint256 v1.3.2 // indirect 55 | github.com/huin/goupnp v1.3.0 // indirect 56 | github.com/jackpal/go-nat-pmp v1.0.2 // indirect 57 | github.com/klauspost/compress v1.16.0 // indirect 58 | github.com/klauspost/cpuid/v2 v2.0.9 // indirect 59 | github.com/kr/pretty v0.3.1 // indirect 60 | github.com/kr/text v0.2.0 // indirect 61 | github.com/mattn/go-colorable v0.1.13 // indirect 62 | github.com/mattn/go-isatty v0.0.20 // indirect 63 | github.com/mattn/go-runewidth v0.0.13 // indirect 64 | github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect 65 | github.com/minio/sha256-simd v1.0.0 // indirect 66 | github.com/mitchellh/mapstructure v1.4.1 // indirect 67 | github.com/mitchellh/pointerstructure v1.2.0 // indirect 68 | github.com/olekukonko/tablewriter v0.0.5 // indirect 69 | github.com/pion/dtls/v2 v2.2.7 // indirect 70 | github.com/pion/logging v0.2.2 // indirect 71 | github.com/pion/stun/v2 v2.0.0 // indirect 72 | github.com/pion/transport/v2 v2.2.1 // indirect 73 | github.com/pion/transport/v3 v3.0.1 // indirect 74 | github.com/pkg/errors v0.9.1 // indirect 75 | github.com/pmezard/go-difflib v1.0.0 // indirect 76 | github.com/prometheus/client_golang v1.15.0 // indirect 77 | github.com/prometheus/client_model v0.3.0 // indirect 78 | github.com/prometheus/common v0.42.0 // indirect 79 | github.com/prometheus/procfs v0.9.0 // indirect 80 | github.com/rivo/uniseg v0.2.0 // indirect 81 | github.com/rogpeppe/go-internal v1.12.0 // indirect 82 | github.com/rs/cors v1.7.0 // indirect 83 | github.com/russross/blackfriday/v2 v2.1.0 // indirect 84 | github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible // indirect 85 | github.com/supranational/blst v0.3.14 // indirect 86 | github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 // indirect 87 | github.com/tklauser/go-sysconf v0.3.12 // indirect 88 | github.com/tklauser/numcpus v0.6.1 // indirect 89 | github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 // indirect 90 | golang.org/x/crypto v0.36.0 // indirect 91 | golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa // indirect 92 | golang.org/x/sync v0.12.0 // indirect 93 | golang.org/x/sys v0.31.0 // indirect 94 | golang.org/x/text v0.23.0 // indirect 95 | golang.org/x/time v0.9.0 // indirect 96 | google.golang.org/protobuf v1.34.2 // indirect 97 | gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect 98 | gopkg.in/yaml.v2 v2.4.0 // indirect 99 | gopkg.in/yaml.v3 v3.0.1 // indirect 100 | ) 101 | -------------------------------------------------------------------------------- /solc/solc.go: -------------------------------------------------------------------------------- 1 | package solc 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | "io" 7 | "io/ioutil" 8 | "log" 9 | "net/http" 10 | "net/url" 11 | "os" 12 | "path/filepath" 13 | "runtime" 14 | "sort" 15 | 16 | "github.com/Masterminds/semver/v3" 17 | "github.com/ethereum/go-ethereum/common/compiler" 18 | "github.com/shibukawa/configdir" 19 | "github.com/withtally/synceth/parser" 20 | ) 21 | 22 | // See: https://docs.soliditylang.org/en/latest/installing-solidity.html#static-binaries 23 | const solcBaseURL = "https://binaries.soliditylang.org/" 24 | 25 | var platforms = map[string]string{ 26 | "emscripten": "emscripten", 27 | "linux": "linux", 28 | "darwin": "macosx", 29 | "windows": "windows", 30 | } 31 | 32 | var architectures = map[string]string{ 33 | "wasm": "wasm32", 34 | "amd64": "amd64", 35 | } 36 | 37 | var ( 38 | cache = configdir.New("withtally", "ethgen").QueryCacheFolder() 39 | buildsFn = "builds.json" 40 | builds []Build 41 | ) 42 | 43 | type Build struct { 44 | Path string `json:"path,omitempty"` 45 | Version *semver.Version `json:"version,omitempty"` 46 | Build string `json:"build,omitempty"` 47 | Keccak256 string `json:"keccak256,omitempty"` 48 | Sha256 string `json:"sha256,omitempty"` 49 | } 50 | 51 | type list struct { 52 | Builds []Build `json:"builds,omitempty"` 53 | } 54 | 55 | func init() { 56 | b, err := cache.ReadFile(buildsFn) 57 | if os.IsNotExist(err) { 58 | return 59 | } else if err != nil { 60 | log.Fatalf("reading builds.json: %v", err) 61 | } 62 | 63 | if err := json.Unmarshal(b, &builds); err != nil { 64 | log.Fatalf("unmarshalling builds.json: %v", err) 65 | } 66 | } 67 | 68 | func local(vc *parser.VersionConstraint) Build { 69 | sort.Slice(builds, func(i, j int) bool { 70 | return builds[i].Version.GreaterThan(builds[j].Version) 71 | }) 72 | 73 | for i := len(builds) - 1; i >= 0; i-- { 74 | if vc.Check(builds[i].Version) { 75 | return builds[i] 76 | } 77 | } 78 | 79 | return Build{} 80 | } 81 | 82 | func fetch(b Build) (Build, error) { 83 | uri, err := url.Parse(solcBaseURL) 84 | if err != nil { 85 | return Build{}, fmt.Errorf("parsing soliditylang url: %w", err) 86 | } 87 | 88 | log.Printf("Fetching solc compiler: %s\n", b.Path) 89 | uri.Path = filepath.Join(platforms[runtime.GOOS]+"-"+architectures[runtime.GOARCH], b.Path) 90 | res, err := http.Get(uri.String()) 91 | if err != nil { 92 | return Build{}, fmt.Errorf("create solc get request: %w", err) 93 | } 94 | defer res.Body.Close() 95 | 96 | buf, err := io.ReadAll(res.Body) 97 | if err != nil { 98 | return Build{}, fmt.Errorf("reding list.json: %w", err) 99 | } 100 | 101 | if res.StatusCode != http.StatusOK { 102 | return Build{}, fmt.Errorf("get request: %s", string(buf)) 103 | } 104 | 105 | if err := cache.CreateParentDir(b.Path); err != nil { 106 | return Build{}, err 107 | } 108 | 109 | if err := ioutil.WriteFile(filepath.Join(cache.Path, b.Path), buf, 0555); err != nil { 110 | return Build{}, fmt.Errorf("writing solc: %w", err) 111 | } 112 | 113 | builds = append(builds, b) 114 | 115 | marshalled, err := json.Marshal(builds) 116 | if err != nil { 117 | return Build{}, fmt.Errorf("marshalling builds.json: %w", err) 118 | } 119 | 120 | if err := cache.WriteFile("builds.json", marshalled); err != nil { 121 | return Build{}, fmt.Errorf("writing builds.json: %w", err) 122 | } 123 | 124 | return b, nil 125 | } 126 | 127 | func resolve(vc *parser.VersionConstraint) (Build, error) { 128 | b := local(vc) 129 | if b.Version != nil { 130 | return b, nil 131 | } 132 | 133 | uri, err := url.Parse(solcBaseURL) 134 | if err != nil { 135 | return Build{}, fmt.Errorf("parsing soliditylang url: %w", err) 136 | } 137 | 138 | platform, ok := platforms[runtime.GOOS] 139 | if !ok { 140 | return Build{}, fmt.Errorf("platform not supported: %s", runtime.GOOS) 141 | } 142 | 143 | arch, ok := architectures[runtime.GOARCH] 144 | if !ok { 145 | return Build{}, fmt.Errorf("architecture not supported: %s", runtime.GOARCH) 146 | } 147 | 148 | uri.Path = filepath.Join(platform+"-"+arch, "list.json") 149 | res, err := http.Get(uri.String()) 150 | if err != nil { 151 | return Build{}, fmt.Errorf("create solc list get request: %w", err) 152 | } 153 | defer res.Body.Close() 154 | 155 | body, err := ioutil.ReadAll(res.Body) 156 | if err != nil { 157 | return Build{}, fmt.Errorf("reading solc list get response: %w", err) 158 | } 159 | 160 | if res.StatusCode != http.StatusOK { 161 | return Build{}, fmt.Errorf("get request: %s", string(body)) 162 | } 163 | 164 | var ls list 165 | if err := json.Unmarshal(body, &ls); err != nil { 166 | return Build{}, fmt.Errorf("unmarshaling solc list: %w", err) 167 | } 168 | 169 | sort.Slice(ls.Builds, func(i, j int) bool { 170 | return ls.Builds[i].Version.GreaterThan(ls.Builds[j].Version) 171 | }) 172 | 173 | for _, b := range ls.Builds { 174 | if vc.Check(b.Version) { 175 | return fetch(b) 176 | } 177 | } 178 | 179 | return Build{}, fmt.Errorf("cant satisfy version constraint: %s", vc.String()) 180 | } 181 | 182 | func CompileSolidityString(src string) (map[string]*compiler.Contract, error) { 183 | c, err := parser.NewVersionConstraint(src) 184 | if err != nil { 185 | return nil, fmt.Errorf("parsing solidity version: %w", err) 186 | } 187 | 188 | b, err := resolve(c) 189 | if err != nil { 190 | return nil, fmt.Errorf("resolving compiler: %w", err) 191 | } 192 | 193 | return compileSolidityString(filepath.Join(cache.Path, b.Path), src) 194 | } 195 | -------------------------------------------------------------------------------- /codegen/fake.go: -------------------------------------------------------------------------------- 1 | package codegen 2 | 3 | import ( 4 | "bytes" 5 | "fmt" 6 | "strings" 7 | "text/template" 8 | 9 | "github.com/ethereum/go-ethereum/accounts/abi" 10 | ) 11 | 12 | const tmplFake = ` 13 | // Code generated by github.com/withtally/synceth, DO NOT EDIT. 14 | 15 | pragma solidity {{.Version}}; 16 | 17 | contract Fake{{.Type}} { 18 | {{range .ABI.Events}} 19 | {{range .Inputs}} 20 | {{if needsStruct .}} 21 | {{structDefinition .}} 22 | {{end}} 23 | {{end}} 24 | 25 | event {{.RawName}}({{(event .Inputs)}}); 26 | function fakeEmit{{.RawName}}({{fakeEmitInputs .Inputs}}) public { 27 | {{fakeEmitHelper .RawName .Inputs}} 28 | } 29 | {{end}} 30 | 31 | {{range .ABI.Methods}} 32 | {{if not (hasStuct .)}} 33 | {{$ns := (toCamel .RawName)}} 34 | {{$hasOutputs := gt (len .Outputs) 0}} 35 | {{if $hasOutputs}} 36 | {{(outputVars $ns .Outputs)}} 37 | function fakeSet{{(toCamel .RawName)}}({{(outputInputs $ns .Outputs)}}) public { 38 | {{(outputVarAssignments $ns .Outputs)}} 39 | } 40 | {{end}} 41 | 42 | function {{.RawName}}({{$s := separator ", "}}{{range .Inputs}}{{call $s}}{{if $hasOutputs}}{{.Name}} {{end}}{{(location .Type.String)}}{{end}}) public view{{if $hasOutputs}} returns ({{(outputs .Outputs)}}){{end}} { 43 | {{if $hasOutputs}}return ( 44 | {{$s := separator ", "}} 45 | {{range $i, $o := .Outputs}} 46 | {{call $s}}_{{(output $ns (.Type.String) .Name $i)}} 47 | {{end}} 48 | );{{end}} 49 | } 50 | {{end}} 51 | {{end}} 52 | } 53 | ` 54 | 55 | func separator(s string) func() string { 56 | i := -1 57 | return func() string { 58 | i++ 59 | if i == 0 { 60 | return "" 61 | } 62 | return s 63 | } 64 | } 65 | 66 | func location(s string) string { 67 | if s == "string" || s == "bytes" || strings.HasSuffix(s, "[]") { 68 | return s + " memory" 69 | } 70 | return s 71 | } 72 | 73 | func event(args []abi.Argument) string { 74 | out := "" 75 | for i, a := range args { 76 | if i > 0 { 77 | out += ", " 78 | } 79 | 80 | if len(a.Type.TupleElems) > 0 { 81 | structName := structs[a.Type.String()] 82 | 83 | out += fmt.Sprintf("%s %s", structName, a.Name) 84 | // TODO: support return structs 85 | } else { 86 | indexed := "" 87 | if a.Indexed { 88 | indexed = "indexed " 89 | } 90 | out += fmt.Sprintf("%s %s%s", a.Type.String(), indexed, a.Name) 91 | } 92 | } 93 | return out 94 | } 95 | 96 | func output(ns, typ, n string, i int) string { 97 | if n == "" { 98 | return fmt.Sprintf("ret%s%s%d", strings.Replace(typ, "[]", "Array", 1), ns, i) 99 | } 100 | return fmt.Sprintf("%s%s%s", strings.Replace(typ, "[]", "Array", 1), ns, n) 101 | } 102 | 103 | func outputInputs(ns string, args []abi.Argument) string { 104 | out := "" 105 | for i, a := range args { 106 | if len(a.Type.TupleElems) > 0 { 107 | // TODO: support return structs 108 | } else { 109 | if i > 0 { 110 | out += ", " 111 | } 112 | out += fmt.Sprintf("%s %s", location(a.Type.String()), output(ns, a.Type.String(), a.Name, i)) 113 | } 114 | } 115 | return out 116 | } 117 | 118 | func outputVars(ns string, args []abi.Argument) string { 119 | out := "" 120 | for i, a := range args { 121 | if len(a.Type.TupleElems) > 0 { 122 | // TODO: support return structs 123 | } else { 124 | out += fmt.Sprintf("%s private _%s;\n", a.Type.String(), output(ns, a.Type.String(), a.Name, i)) 125 | } 126 | } 127 | return out 128 | } 129 | 130 | func outputVarAssignments(ns string, args []abi.Argument) string { 131 | out := "" 132 | for i, a := range args { 133 | if len(a.Type.TupleElems) > 0 { 134 | // TODO: support return structspkg 135 | } else { 136 | out += fmt.Sprintf("_%s = %s;\n", output(ns, a.Type.String(), a.Name, i), output(ns, a.Type.String(), a.Name, i)) 137 | } 138 | } 139 | return out 140 | } 141 | 142 | func outputs(args []abi.Argument) string { 143 | out := "" 144 | for i, a := range args { 145 | if len(a.Type.TupleElems) > 0 { 146 | // TODO: support return structs 147 | } else { 148 | if i > 0 { 149 | out += ", " 150 | } 151 | out += fmt.Sprintf("%s", location(a.Type.String())) 152 | } 153 | } 154 | return out 155 | } 156 | 157 | func hasStuct(m abi.Method) bool { 158 | for _, in := range m.Inputs { 159 | if len(in.Type.TupleElems) > 0 { 160 | return true 161 | } 162 | } 163 | 164 | for _, out := range m.Outputs { 165 | if len(out.Type.TupleElems) > 0 { 166 | return true 167 | } 168 | } 169 | 170 | return false 171 | } 172 | 173 | func fakeEmitInputs(args []abi.Argument) string { 174 | out := "" 175 | 176 | for i, a := range args { 177 | if i != 0 { 178 | out += ", " 179 | } 180 | if needsStruct(a) { 181 | structName := structs[a.Type.String()] 182 | 183 | out += fmt.Sprintf("%s memory %s", structName, a.Name) 184 | } else { 185 | out += fmt.Sprintf("%s %s", location(a.Type.String()), a.Name) 186 | } 187 | } 188 | 189 | return out 190 | } 191 | 192 | func fakeEmitHelper(eventName string, args []abi.Argument) string { 193 | out := fmt.Sprintf("emit %s(", eventName) 194 | s := separator(", ") 195 | for _, a := range args { 196 | out += fmt.Sprintf("%s%s", s(), a.Name) 197 | } 198 | out += ");" 199 | return out 200 | } 201 | 202 | var structs = make(map[string]string) 203 | 204 | func structDefinition(a abi.Argument) string { 205 | structName := strings.ToUpper(a.Name[:1]) + a.Name[1:] 206 | 207 | out := fmt.Sprintf("struct %s {", structName) 208 | 209 | for i, component := range a.Type.TupleElems { 210 | out += "\n" 211 | // For nested tuples, just use the field name without the tuple notation 212 | if component.T == abi.TupleTy { 213 | out += fmt.Sprintf("string %s;", a.Type.TupleRawNames[i]) 214 | } else { 215 | out += fmt.Sprintf("%s %s;", component.String(), a.Type.TupleRawNames[i]) 216 | } 217 | } 218 | 219 | out += "\n}" 220 | 221 | structs[a.Type.String()] = structName 222 | 223 | return out 224 | } 225 | 226 | func needsStruct(a abi.Argument) bool { 227 | if len(a.Type.TupleElems) > 0 { 228 | return true 229 | } 230 | 231 | return false 232 | } 233 | 234 | type tmplFakeData struct { 235 | Type string 236 | ABI abi.ABI 237 | Version string 238 | } 239 | 240 | func GenerateFake(typ string, cABI string, solversionOverride *string) (string, error) { 241 | evmABI, err := abi.JSON(strings.NewReader(cABI)) 242 | if err != nil { 243 | return "", fmt.Errorf("parsing abi: %w", err) 244 | } 245 | 246 | solversion := "^0.8.3" 247 | if solversionOverride != nil { 248 | solversion = *solversionOverride 249 | } 250 | 251 | data := &tmplFakeData{ 252 | Type: abi.ToCamelCase(typ), 253 | ABI: evmABI, 254 | Version: solversion, 255 | } 256 | 257 | buffer := new(bytes.Buffer) 258 | tmpl := template.Must(template.New("").Funcs(template.FuncMap{ 259 | "event": event, 260 | "hasStuct": hasStuct, 261 | "outputInputs": outputInputs, 262 | "outputs": outputs, 263 | "outputVars": outputVars, 264 | "outputVarAssignments": outputVarAssignments, 265 | "location": location, 266 | "output": output, 267 | "toCamel": abi.ToCamelCase, 268 | "separator": separator, 269 | "fakeEmitInputs": fakeEmitInputs, 270 | "fakeEmitHelper": fakeEmitHelper, 271 | "structDefinition": structDefinition, 272 | "needsStruct": needsStruct, 273 | }).Parse(tmplFake)) 274 | if err := tmpl.Execute(buffer, data); err != nil { 275 | return "", err 276 | } 277 | 278 | return string(buffer.Bytes()), nil 279 | } 280 | -------------------------------------------------------------------------------- /codegen/processor.go: -------------------------------------------------------------------------------- 1 | package codegen 2 | 3 | import ( 4 | "bytes" 5 | "errors" 6 | "fmt" 7 | "go/format" 8 | "reflect" 9 | "strings" 10 | "text/template" 11 | 12 | "github.com/ethereum/go-ethereum/accounts/abi" 13 | ) 14 | 15 | var ErrNoEvents = errors.New("no events") 16 | 17 | const tmplProcessor = ` 18 | // Code generated by github.com/withtally/synceth, DO NOT EDIT. 19 | 20 | package {{.Package}} 21 | 22 | import ( 23 | "context" 24 | "fmt" 25 | "strings" 26 | 27 | "github.com/ethereum/go-ethereum" 28 | "github.com/ethereum/go-ethereum/accounts/abi" 29 | "github.com/ethereum/go-ethereum/accounts/abi/bind" 30 | "github.com/ethereum/go-ethereum/common" 31 | "github.com/ethereum/go-ethereum/core/types" 32 | 33 | {{range $type := .InputTypes}} 34 | {{generateAlias .Alias}} "{{.PkgPath}}" 35 | {{end}} 36 | ) 37 | 38 | {{range $handler := .Processors}} 39 | type {{.Type}}Processor interface { 40 | Setup(ctx context.Context, address common.Address, eth interface { 41 | ethereum.ChainReader 42 | ethereum.ChainStateReader 43 | ethereum.TransactionReader 44 | bind.ContractBackend 45 | }, {{$s := separator ", "}}{{range $type := $.SetupInputTypes}}{{call $s}}{{$type.Name}} {{formatPointer $type.Kind}}{{$type.Ident}}{{end}}) error 46 | Initialize(ctx context.Context, start uint64, {{$s := separator ", "}}{{range $type := $.InputTypes}}{{call $s}}{{$type.Name}} {{formatPointer $type.Kind}}{{$type.Ident}}{{end}}) error 47 | {{range .Events}} 48 | Process{{.Normalized.Name}}(ctx context.Context, e {{$handler.Type}}{{.Normalized.Name}}) (func({{$s := separator ", "}}{{range $type := $.InputTypes}}{{call $s}}{{$type.Name}} {{formatPointer $type.Kind}}{{$type.Ident}}{{end}}) error, error) 49 | {{end}} 50 | mustEmbedBase{{.Type}}Processor() 51 | } 52 | 53 | type Base{{.Type}}Processor struct { 54 | Address common.Address 55 | ABI abi.ABI 56 | Contract *{{.Type}} 57 | Eth interface { 58 | ethereum.ChainReader 59 | ethereum.ChainStateReader 60 | ethereum.TransactionReader 61 | bind.ContractBackend 62 | } 63 | } 64 | 65 | func (h *Base{{.Type}}Processor) Setup(ctx context.Context, address common.Address, eth interface { 66 | ethereum.ChainReader 67 | ethereum.ChainStateReader 68 | ethereum.TransactionReader 69 | bind.ContractBackend 70 | }, {{$s := separator ", "}}{{range $type := $.SetupInputTypes}}{{call $s}}{{$type.Name}} {{formatPointer $type.Kind}}{{$type.Ident}}{{end}}) error { 71 | contract, err := New{{.Type}}(address, eth) 72 | if err != nil { 73 | return fmt.Errorf("new {{.Type}}: %w", err) 74 | } 75 | 76 | abi, err := abi.JSON(strings.NewReader(string({{.Type}}ABI))) 77 | if err != nil { 78 | return fmt.Errorf("parsing {{.Type}} abi: %w", err) 79 | } 80 | 81 | h.Address = address 82 | h.ABI = abi 83 | h.Contract = contract 84 | h.Eth = eth 85 | return nil 86 | } 87 | 88 | func (h *Base{{.Type}}Processor) ProcessElement(p interface{}) func(context.Context, types.Log) (func({{$s := separator ", "}}{{range $type := $.InputTypes}}{{call $s}}{{formatPointer $type.Kind}}{{$type.Ident}}{{end}}) error, error) { 89 | return func(ctx context.Context, vLog types.Log) (func({{$s := separator ", "}}{{range $type := $.InputTypes}}{{call $s}}{{formatPointer $type.Kind}}{{$type.Ident}}{{end}}) error, error) { 90 | switch vLog.Topics[0].Hex() { 91 | {{range .Events}} 92 | case h.ABI.Events["{{.Normalized.Name}}"].ID.Hex(): 93 | e := {{$handler.Type}}{{.Normalized.Name}}{} 94 | if err := h.UnpackLog(&e, "{{.Normalized.Name}}", vLog); err != nil { 95 | return nil, fmt.Errorf("unpacking {{.Normalized.Name}}: %w", err) 96 | } 97 | 98 | e.Raw = vLog 99 | cb, err := p.({{$handler.Type}}Processor).Process{{.Normalized.Name}}(ctx, e); 100 | if err != nil { 101 | return nil, fmt.Errorf("processing {{.Normalized.Name}}: %w", err) 102 | } 103 | 104 | return cb, nil 105 | {{end}} 106 | } 107 | return func({{$s := separator ", "}}{{range $type := $.InputTypes}}{{call $s}}{{formatPointer $type.Kind}}{{$type.Ident}}{{end}}) error { return nil }, nil 108 | } 109 | } 110 | 111 | func (h *Base{{$handler.Type}}Processor) UnpackLog(out interface{}, event string, log types.Log) error { 112 | if len(log.Data) > 0 { 113 | if err := h.ABI.UnpackIntoInterface(out, event, log.Data); err != nil { 114 | return err 115 | } 116 | } 117 | var indexed abi.Arguments 118 | for _, arg := range h.ABI.Events[event].Inputs { 119 | if arg.Indexed { 120 | indexed = append(indexed, arg) 121 | } 122 | } 123 | return abi.ParseTopics(out, indexed, log.Topics[1:]) 124 | } 125 | 126 | func (h *Base{{$handler.Type}}Processor) Initialize(ctx context.Context, start uint64, {{$s := separator ", "}}{{range $type := $.InputTypes}}{{call $s}}{{$type.Name}} {{formatPointer $type.Kind}}{{$type.Ident}}{{end}}) error { 127 | return nil 128 | } 129 | 130 | {{range .Events}} 131 | func (h *Base{{$handler.Type}}Processor) Process{{.Normalized.Name}}(ctx context.Context, e {{$handler.Type}}{{.Normalized.Name}}) (func({{$s := separator ", "}}{{range $type := $.InputTypes}}{{call $s}}{{$type.Name}} {{formatPointer $type.Kind}}{{$type.Ident}}{{end}}) error, error) { 132 | return func({{$s := separator ", "}}{{range $type := $.InputTypes}}{{call $s}}{{$type.Name}} {{formatPointer $type.Kind}}{{$type.Ident}}{{end}}) error { return nil }, nil 133 | } 134 | {{end}} 135 | 136 | func (h *Base{{$handler.Type}}Processor) mustEmbedBase{{$handler.Type}}Processor() {} 137 | {{end}} 138 | ` 139 | 140 | type tmplEventData struct { 141 | Original abi.Event // Original event as parsed by the abi package 142 | Normalized abi.Event // Normalized version of the parsed fields 143 | } 144 | 145 | type tmplProcessorData struct { 146 | Type string 147 | Events map[string]*tmplEventData 148 | } 149 | 150 | type inputType struct { 151 | Alias *string 152 | Name string 153 | Ident string 154 | Kind reflect.Kind 155 | PkgPath string 156 | } 157 | 158 | type tmplData struct { 159 | Package string 160 | InputTypes []inputType 161 | SetupInputTypes []inputType 162 | Processors map[string]*tmplProcessorData 163 | } 164 | 165 | func GenerateProcessor(types []string, abis []string, pkg string, inputs []InputType, setupInputs []InputType) (string, error) { 166 | var handlers = make(map[string]*tmplProcessorData) 167 | var n int 168 | 169 | var inputTypes []inputType 170 | for _, v := range inputs { 171 | t := reflect.TypeOf(v.Type) 172 | tv := indirect(t) 173 | 174 | i := tv.String() 175 | if v.Alias != nil { 176 | s := strings.Split(i, ".") 177 | i = fmt.Sprintf("%s.%s", *v.Alias, s[1]) 178 | } 179 | 180 | inputTypes = append(inputTypes, inputType{ 181 | Alias: v.Alias, 182 | Kind: t.Kind(), 183 | Name: v.Name, 184 | Ident: i, 185 | PkgPath: tv.PkgPath(), 186 | }) 187 | } 188 | 189 | var setupInputTypes []inputType 190 | for _, v := range setupInputs { 191 | t := reflect.TypeOf(v.Type) 192 | tv := indirect(t) 193 | 194 | i := tv.String() 195 | if v.Alias != nil { 196 | s := strings.Split(i, ".") 197 | i = fmt.Sprintf("%s.%s", *v.Alias, s[1]) 198 | } 199 | 200 | setupInputTypes = append(setupInputTypes, inputType{ 201 | Alias: v.Alias, 202 | Kind: t.Kind(), 203 | Name: v.Name, 204 | Ident: i, 205 | PkgPath: tv.PkgPath(), 206 | }) 207 | } 208 | 209 | for i, typ := range types { 210 | var events = make(map[string]*tmplEventData) 211 | evmABI, err := abi.JSON(strings.NewReader(abis[i])) 212 | if err != nil { 213 | return "", fmt.Errorf("parsing abi: %w", err) 214 | } 215 | 216 | for _, original := range evmABI.Events { 217 | // Skip anonymous events as they don't support explicit filtering 218 | if original.Anonymous { 219 | continue 220 | } 221 | // Normalize the event for capital cases and non-anonymous outputs 222 | normalized := original 223 | normalized.Name = abi.ToCamelCase(original.Name) 224 | 225 | events[original.Name] = &tmplEventData{Original: original, Normalized: normalized} 226 | } 227 | 228 | if len(events) > 0 { 229 | handlers[typ] = &tmplProcessorData{ 230 | Type: abi.ToCamelCase(typ), 231 | Events: events, 232 | } 233 | n++ 234 | } 235 | } 236 | 237 | if n == 0 { 238 | return "", ErrNoEvents 239 | } 240 | 241 | data := &tmplData{ 242 | InputTypes: inputTypes, 243 | SetupInputTypes: setupInputTypes, 244 | Package: pkg, 245 | Processors: handlers, 246 | } 247 | 248 | buffer := new(bytes.Buffer) 249 | tmpl := template.Must(template.New("").Funcs(template.FuncMap{ 250 | "formatPointer": formatPointer, 251 | "separator": separator, 252 | "generateAlias": generateAlias, 253 | }).Parse(tmplProcessor)) 254 | if err := tmpl.Execute(buffer, data); err != nil { 255 | return "", err 256 | } 257 | 258 | handler, err := format.Source(buffer.Bytes()) 259 | if err != nil { 260 | return "", err 261 | } 262 | 263 | return string(handler), nil 264 | } 265 | 266 | // indirect returns the type at the end of indirection. 267 | func indirect(t reflect.Type) reflect.Type { 268 | for t.Kind() == reflect.Ptr { 269 | t = t.Elem() 270 | } 271 | return t 272 | } 273 | 274 | func formatPointer(k reflect.Kind) string { 275 | if k == reflect.Ptr { 276 | return "*" 277 | } 278 | 279 | return "" 280 | } 281 | 282 | func generateAlias(alias *string) string { 283 | if alias != nil { 284 | return fmt.Sprintf("%s ", *alias) 285 | } 286 | 287 | return "" 288 | } 289 | -------------------------------------------------------------------------------- /codegen/fake_test.go: -------------------------------------------------------------------------------- 1 | package codegen 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/stretchr/testify/assert" 7 | "github.com/stretchr/testify/require" 8 | ) 9 | 10 | // TestGenerateFake comprehensively tests the GenerateFake function with various scenarios. 11 | // This consolidated test covers: 12 | // - Basic function generation with view/pure functions 13 | // - Event generation with fakeEmit functions 14 | // - Error handling for invalid ABIs 15 | // - Custom Solidity version support 16 | // - Functions with multiple outputs 17 | // - Functions with inputs (parameters ignored in fake) 18 | // - Events with indexed parameters 19 | // - Memory keyword handling for reference types 20 | // - Anonymous events 21 | // - Struct definitions in events 22 | // - Functions with no outputs 23 | // - Edge cases where functions with structs are skipped 24 | // - Empty ABI generation 25 | // - Complex nested struct scenarios 26 | func TestGenerateFake(t *testing.T) { 27 | tests := []struct { 28 | name string 29 | typ string 30 | abi string 31 | version *string 32 | expectedOutput string 33 | wantErr bool 34 | errContains string 35 | }{ 36 | { 37 | name: "basic_view_function", 38 | typ: "SimpleView", 39 | abi: `[{ 40 | "name": "getValue", 41 | "type": "function", 42 | "stateMutability": "view", 43 | "inputs": [], 44 | "outputs": [{"name": "", "type": "uint256"}] 45 | }]`, 46 | expectedOutput: ` 47 | // Code generated by github.com/withtally/synceth, DO NOT EDIT. 48 | 49 | pragma solidity ^0.8.3; 50 | 51 | contract FakeSimpleView { 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | uint256 private _retuint256GetValue0; 60 | 61 | function fakeSetGetValue(uint256 retuint256GetValue0) public { 62 | _retuint256GetValue0 = retuint256GetValue0; 63 | 64 | } 65 | 66 | 67 | function getValue() public view returns (uint256) { 68 | return ( 69 | 70 | 71 | _retuint256GetValue0 72 | 73 | ); 74 | } 75 | 76 | 77 | } 78 | `, 79 | }, 80 | { 81 | name: "event_generation", 82 | typ: "EventContract", 83 | abi: `[{ 84 | "name": "DataStored", 85 | "type": "event", 86 | "inputs": [{"name": "data", "type": "bytes32"}] 87 | }]`, 88 | expectedOutput: ` 89 | // Code generated by github.com/withtally/synceth, DO NOT EDIT. 90 | 91 | pragma solidity ^0.8.3; 92 | 93 | contract FakeEventContract { 94 | 95 | 96 | 97 | 98 | 99 | event DataStored(bytes32 data); 100 | function fakeEmitDataStored(bytes32 data) public { 101 | emit DataStored(data); 102 | } 103 | 104 | 105 | 106 | } 107 | `, 108 | }, 109 | { 110 | name: "invalid_abi", 111 | typ: "Invalid", 112 | abi: `invalid json`, 113 | wantErr: true, 114 | errContains: "parsing abi", 115 | }, 116 | { 117 | name: "custom_solidity_version", 118 | typ: "Custom", 119 | abi: `[]`, 120 | version: stringPtr("0.8.19"), 121 | expectedOutput: ` 122 | // Code generated by github.com/withtally/synceth, DO NOT EDIT. 123 | 124 | pragma solidity 0.8.19; 125 | 126 | contract FakeCustom { 127 | 128 | 129 | 130 | } 131 | `, 132 | }, 133 | { 134 | name: "function_with_multiple_outputs", 135 | typ: "MultiOutput", 136 | abi: `[{ 137 | "name": "getValues", 138 | "type": "function", 139 | "stateMutability": "view", 140 | "inputs": [], 141 | "outputs": [ 142 | {"name": "a", "type": "uint256"}, 143 | {"name": "b", "type": "bool"} 144 | ] 145 | }]`, 146 | expectedOutput: ` 147 | // Code generated by github.com/withtally/synceth, DO NOT EDIT. 148 | 149 | pragma solidity ^0.8.3; 150 | 151 | contract FakeMultiOutput { 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | uint256 private _uint256GetValuesa; 160 | bool private _boolGetValuesb; 161 | 162 | function fakeSetGetValues(uint256 uint256GetValuesa, bool boolGetValuesb) public { 163 | _uint256GetValuesa = uint256GetValuesa; 164 | _boolGetValuesb = boolGetValuesb; 165 | 166 | } 167 | 168 | 169 | function getValues() public view returns (uint256, bool) { 170 | return ( 171 | 172 | 173 | _uint256GetValuesa 174 | 175 | , _boolGetValuesb 176 | 177 | ); 178 | } 179 | 180 | 181 | } 182 | `, 183 | }, 184 | { 185 | name: "function_with_inputs", 186 | typ: "WithInputs", 187 | abi: `[{ 188 | "name": "calculate", 189 | "type": "function", 190 | "stateMutability": "pure", 191 | "inputs": [ 192 | {"name": "x", "type": "uint256"}, 193 | {"name": "y", "type": "uint256"} 194 | ], 195 | "outputs": [{"name": "result", "type": "uint256"}] 196 | }]`, 197 | expectedOutput: ` 198 | // Code generated by github.com/withtally/synceth, DO NOT EDIT. 199 | 200 | pragma solidity ^0.8.3; 201 | 202 | contract FakeWithInputs { 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | uint256 private _uint256Calculateresult; 211 | 212 | function fakeSetCalculate(uint256 uint256Calculateresult) public { 213 | _uint256Calculateresult = uint256Calculateresult; 214 | 215 | } 216 | 217 | 218 | function calculate(x uint256, y uint256) public view returns (uint256) { 219 | return ( 220 | 221 | 222 | _uint256Calculateresult 223 | 224 | ); 225 | } 226 | 227 | 228 | } 229 | `, 230 | }, 231 | { 232 | name: "event_with_indexed_params", 233 | typ: "IndexedEvent", 234 | abi: `[{ 235 | "name": "Transfer", 236 | "type": "event", 237 | "inputs": [ 238 | {"name": "from", "type": "address", "indexed": true}, 239 | {"name": "to", "type": "address", "indexed": true}, 240 | {"name": "value", "type": "uint256", "indexed": false} 241 | ] 242 | }]`, 243 | expectedOutput: ` 244 | // Code generated by github.com/withtally/synceth, DO NOT EDIT. 245 | 246 | pragma solidity ^0.8.3; 247 | 248 | contract FakeIndexedEvent { 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | event Transfer(address indexed from, address indexed to, uint256 value); 259 | function fakeEmitTransfer(address from, address to, uint256 value) public { 260 | emit Transfer(from, to, value); 261 | } 262 | 263 | 264 | 265 | } 266 | `, 267 | }, 268 | { 269 | name: "function_with_memory_params", 270 | typ: "MemoryParams", 271 | abi: `[{ 272 | "name": "setData", 273 | "type": "function", 274 | "stateMutability": "nonpayable", 275 | "inputs": [ 276 | {"name": "data", "type": "string"}, 277 | {"name": "values", "type": "uint256[]"} 278 | ], 279 | "outputs": [] 280 | }]`, 281 | expectedOutput: ` 282 | // Code generated by github.com/withtally/synceth, DO NOT EDIT. 283 | 284 | pragma solidity ^0.8.3; 285 | 286 | contract FakeMemoryParams { 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | function setData(string memory, uint256[] memory) public view { 296 | 297 | } 298 | 299 | 300 | } 301 | `, 302 | }, 303 | { 304 | name: "anonymous_event", 305 | typ: "AnonEvent", 306 | abi: `[{ 307 | "name": "Anonymous", 308 | "type": "event", 309 | "anonymous": true, 310 | "inputs": [{"name": "data", "type": "bytes32"}] 311 | }]`, 312 | expectedOutput: ` 313 | // Code generated by github.com/withtally/synceth, DO NOT EDIT. 314 | 315 | pragma solidity ^0.8.3; 316 | 317 | contract FakeAnonEvent { 318 | 319 | 320 | 321 | 322 | 323 | event Anonymous(bytes32 data); 324 | function fakeEmitAnonymous(bytes32 data) public { 325 | emit Anonymous(data); 326 | } 327 | 328 | 329 | 330 | } 331 | `, 332 | }, 333 | { 334 | name: "struct_in_event", 335 | typ: "StructCheck", 336 | abi: `[{ 337 | "name": "StructEvent", 338 | "type": "event", 339 | "inputs": [{ 340 | "name": "data", 341 | "type": "tuple", 342 | "components": [ 343 | {"name": "id", "type": "uint256"}, 344 | {"name": "value", "type": "string"} 345 | ] 346 | }] 347 | }]`, 348 | expectedOutput: ` 349 | // Code generated by github.com/withtally/synceth, DO NOT EDIT. 350 | 351 | pragma solidity ^0.8.3; 352 | 353 | contract FakeStructCheck { 354 | 355 | 356 | 357 | struct Data { 358 | uint256 id; 359 | string value; 360 | } 361 | 362 | 363 | 364 | event StructEvent(Data data); 365 | function fakeEmitStructEvent(Data memory data) public { 366 | emit StructEvent(data); 367 | } 368 | 369 | 370 | 371 | } 372 | `, 373 | }, 374 | { 375 | name: "function_no_outputs", 376 | typ: "NoOutputs", 377 | abi: `[{ 378 | "name": "doSomething", 379 | "type": "function", 380 | "stateMutability": "nonpayable", 381 | "inputs": [], 382 | "outputs": [] 383 | }]`, 384 | expectedOutput: ` 385 | // Code generated by github.com/withtally/synceth, DO NOT EDIT. 386 | 387 | pragma solidity ^0.8.3; 388 | 389 | contract FakeNoOutputs { 390 | 391 | 392 | 393 | 394 | 395 | 396 | 397 | 398 | function doSomething() public view { 399 | 400 | } 401 | 402 | 403 | } 404 | `, 405 | }, 406 | { 407 | name: "function_with_struct_output_skipped", 408 | typ: "HasStruct", 409 | abi: `[{ 410 | "name": "getValue", 411 | "type": "function", 412 | "stateMutability": "view", 413 | "inputs": [], 414 | "outputs": [{ 415 | "name": "data", 416 | "type": "tuple", 417 | "components": [ 418 | {"name": "id", "type": "uint256"}, 419 | {"name": "name", "type": "string"} 420 | ] 421 | }] 422 | }]`, 423 | expectedOutput: ` 424 | // Code generated by github.com/withtally/synceth, DO NOT EDIT. 425 | 426 | pragma solidity ^0.8.3; 427 | 428 | contract FakeHasStruct { 429 | 430 | 431 | 432 | 433 | 434 | } 435 | `, 436 | }, 437 | { 438 | name: "function_with_struct_input_skipped", 439 | typ: "StructInput", 440 | abi: `[{ 441 | "name": "process", 442 | "type": "function", 443 | "stateMutability": "nonpayable", 444 | "inputs": [{ 445 | "name": "data", 446 | "type": "tuple", 447 | "components": [ 448 | {"name": "value", "type": "uint256"} 449 | ] 450 | }], 451 | "outputs": [] 452 | }]`, 453 | expectedOutput: ` 454 | // Code generated by github.com/withtally/synceth, DO NOT EDIT. 455 | 456 | pragma solidity ^0.8.3; 457 | 458 | contract FakeStructInput { 459 | 460 | 461 | 462 | 463 | 464 | } 465 | `, 466 | }, 467 | { 468 | name: "empty_abi", 469 | typ: "Valid", 470 | abi: `[]`, 471 | expectedOutput: ` 472 | // Code generated by github.com/withtally/synceth, DO NOT EDIT. 473 | 474 | pragma solidity ^0.8.3; 475 | 476 | contract FakeValid { 477 | 478 | 479 | 480 | } 481 | `, 482 | }, 483 | { 484 | name: "complex_nested_structs", 485 | typ: "StructDef", 486 | abi: `[{ 487 | "name": "ComplexEvent", 488 | "type": "event", 489 | "inputs": [{ 490 | "name": "data", 491 | "type": "tuple", 492 | "components": [ 493 | {"name": "id", "type": "uint256"}, 494 | { 495 | "name": "nested", 496 | "type": "tuple", 497 | "components": [ 498 | {"name": "value", "type": "string"} 499 | ] 500 | } 501 | ] 502 | }] 503 | }]`, 504 | expectedOutput: ` 505 | // Code generated by github.com/withtally/synceth, DO NOT EDIT. 506 | 507 | pragma solidity ^0.8.3; 508 | 509 | contract FakeStructDef { 510 | 511 | 512 | 513 | struct Data { 514 | uint256 id; 515 | string nested; 516 | } 517 | 518 | 519 | 520 | event ComplexEvent(Data data); 521 | function fakeEmitComplexEvent(Data memory data) public { 522 | emit ComplexEvent(data); 523 | } 524 | 525 | 526 | 527 | } 528 | `, 529 | }, 530 | } 531 | 532 | for _, tt := range tests { 533 | t.Run(tt.name, func(t *testing.T) { 534 | output, err := GenerateFake(tt.typ, tt.abi, tt.version) 535 | if tt.wantErr { 536 | require.Error(t, err) 537 | if tt.errContains != "" { 538 | assert.Contains(t, err.Error(), tt.errContains) 539 | } 540 | } else { 541 | require.NoError(t, err) 542 | assert.Equal(t, tt.expectedOutput, output, "Output mismatch for test case: %s", tt.name) 543 | } 544 | }) 545 | } 546 | } 547 | 548 | // TestFakeHelperFunctions tests the utility functions used in fake generation. 549 | // These helper functions handle string manipulation and type detection: 550 | // 1. separator() - Generates comma separators for function parameters 551 | // 2. location() - Determines memory/storage/calldata location for types 552 | // 3. output() - Generates variable names for return values 553 | // Testing these ensures consistent code generation. 554 | func TestFakeHelperFunctions(t *testing.T) { 555 | t.Run("separator", func(t *testing.T) { 556 | // Test separator() which creates a closure that returns empty string on first call, 557 | // then the separator string on subsequent calls (for comma-separated lists) 558 | sep := separator("") 559 | assert.Equal(t, "", sep()) // First call: empty 560 | assert.Equal(t, "", sep()) // Second call: empty (separator is "") 561 | 562 | sep2 := separator(", ") 563 | assert.Equal(t, "", sep2()) // First call: empty 564 | assert.Equal(t, ", ", sep2()) // Second call: returns separator 565 | }) 566 | 567 | t.Run("location", func(t *testing.T) { 568 | // Test location() function which adds 'memory' keyword for reference types 569 | assert.Equal(t, "uint256", location("uint256")) // Value types: no memory keyword 570 | assert.Equal(t, "bool", location("bool")) 571 | assert.Equal(t, "address", location("address")) 572 | assert.Equal(t, "string memory", location("string")) // Reference types: add memory 573 | assert.Equal(t, "bytes memory", location("bytes")) 574 | assert.Equal(t, "uint256[] memory", location("uint256[]")) // Arrays: add memory 575 | assert.Equal(t, "SomeStruct", location("SomeStruct")) // Structs: no memory (handled elsewhere) 576 | }) 577 | 578 | t.Run("output_function", func(t *testing.T) { 579 | // Test with empty name 580 | result := output("MyFunc", "uint256", "", 0) 581 | assert.Equal(t, "retuint256MyFunc0", result) 582 | 583 | // Test with name 584 | result = output("MyFunc", "uint256", "value", 0) 585 | assert.Equal(t, "uint256MyFuncvalue", result) 586 | 587 | // Test with array type 588 | result = output("MyFunc", "uint256[]", "values", 1) 589 | assert.Equal(t, "uint256ArrayMyFuncvalues", result) 590 | }) 591 | } 592 | 593 | // Helper function for string pointers 594 | func stringPtr(s string) *string { 595 | return &s 596 | } 597 | -------------------------------------------------------------------------------- /codegen/contract_test.go: -------------------------------------------------------------------------------- 1 | package codegen 2 | 3 | import ( 4 | "encoding/json" 5 | "strings" 6 | "testing" 7 | 8 | "github.com/ethereum/go-ethereum/crypto" 9 | "github.com/stretchr/testify/assert" 10 | "github.com/stretchr/testify/require" 11 | ) 12 | 13 | // TestParseContract_ValidContracts tests ParseContract with various valid Solidity contracts 14 | func TestParseContract_ValidContracts(t *testing.T) { 15 | tests := []struct { 16 | name string 17 | source string 18 | expectedTypes []string 19 | expectedABIElements map[string][]string // contract name -> expected ABI element names 20 | validateLibs func(t *testing.T, libs map[string]string) 21 | skipIfNoCompiler bool 22 | }{ 23 | { 24 | name: "simple_storage_contract", 25 | source: ` 26 | pragma solidity ^0.8.0; 27 | 28 | contract SimpleStorage { 29 | uint256 public value; 30 | 31 | function setValue(uint256 _value) public { 32 | value = _value; 33 | } 34 | 35 | function getValue() public view returns (uint256) { 36 | return value; 37 | } 38 | } 39 | `, 40 | expectedTypes: []string{"SimpleStorage"}, 41 | expectedABIElements: map[string][]string{ 42 | "SimpleStorage": {"value", "setValue", "getValue"}, 43 | }, 44 | validateLibs: func(t *testing.T, libs map[string]string) { 45 | assert.Len(t, libs, 1) 46 | for pattern, name := range libs { 47 | assert.Equal(t, "SimpleStorage", name) 48 | assert.Len(t, pattern, 34) // Keccak256 hash truncated 49 | } 50 | }, 51 | }, 52 | { 53 | name: "multiple_contracts", 54 | source: ` 55 | pragma solidity ^0.8.0; 56 | 57 | contract ContractA { 58 | uint256 public a; 59 | } 60 | 61 | contract ContractB { 62 | string public b; 63 | } 64 | `, 65 | expectedTypes: []string{"ContractA", "ContractB"}, 66 | expectedABIElements: map[string][]string{ 67 | "ContractA": {"a"}, 68 | "ContractB": {"b"}, 69 | }, 70 | validateLibs: func(t *testing.T, libs map[string]string) { 71 | assert.Len(t, libs, 2) 72 | foundA, foundB := false, false 73 | for _, name := range libs { 74 | if name == "ContractA" { 75 | foundA = true 76 | } 77 | if name == "ContractB" { 78 | foundB = true 79 | } 80 | } 81 | assert.True(t, foundA, "ContractA not found in libs") 82 | assert.True(t, foundB, "ContractB not found in libs") 83 | }, 84 | }, 85 | { 86 | name: "contract_with_events", 87 | source: ` 88 | pragma solidity ^0.8.0; 89 | 90 | contract EventContract { 91 | event ValueChanged(uint256 indexed oldValue, uint256 indexed newValue); 92 | event OwnerChanged(address indexed oldOwner, address indexed newOwner); 93 | 94 | uint256 public value; 95 | address public owner; 96 | 97 | constructor() { 98 | owner = msg.sender; 99 | } 100 | 101 | function updateValue(uint256 newValue) public { 102 | uint256 oldValue = value; 103 | value = newValue; 104 | emit ValueChanged(oldValue, newValue); 105 | } 106 | } 107 | `, 108 | expectedTypes: []string{"EventContract"}, 109 | expectedABIElements: map[string][]string{ 110 | "EventContract": {"ValueChanged", "OwnerChanged", "value", "owner", "updateValue"}, 111 | }, 112 | validateLibs: func(t *testing.T, libs map[string]string) { 113 | assert.Len(t, libs, 1) 114 | }, 115 | }, 116 | { 117 | name: "library_contract", 118 | source: ` 119 | pragma solidity ^0.8.0; 120 | 121 | library SafeMath { 122 | function add(uint256 a, uint256 b) internal pure returns (uint256) { 123 | uint256 c = a + b; 124 | require(c >= a, "SafeMath: addition overflow"); 125 | return c; 126 | } 127 | 128 | function sub(uint256 a, uint256 b) internal pure returns (uint256) { 129 | require(b <= a, "SafeMath: subtraction overflow"); 130 | return a - b; 131 | } 132 | } 133 | `, 134 | expectedTypes: []string{"SafeMath"}, 135 | expectedABIElements: map[string][]string{ 136 | "SafeMath": {}, // Libraries typically have empty external ABI 137 | }, 138 | validateLibs: func(t *testing.T, libs map[string]string) { 139 | assert.Len(t, libs, 1) 140 | for _, name := range libs { 141 | assert.Equal(t, "SafeMath", name) 142 | } 143 | }, 144 | }, 145 | { 146 | name: "empty_contract", 147 | source: ` 148 | pragma solidity ^0.8.0; 149 | 150 | contract Empty { 151 | } 152 | `, 153 | expectedTypes: []string{"Empty"}, 154 | expectedABIElements: map[string][]string{ 155 | "Empty": {}, 156 | }, 157 | validateLibs: func(t *testing.T, libs map[string]string) { 158 | assert.Len(t, libs, 1) 159 | }, 160 | }, 161 | } 162 | 163 | for _, tt := range tests { 164 | t.Run(tt.name, func(t *testing.T) { 165 | // Try to parse the contract 166 | metadata, err := ParseContract(tt.source) 167 | 168 | // If compilation fails, it might be due to missing solc compiler 169 | if err != nil { 170 | if strings.Contains(err.Error(), "resolving compiler") || 171 | strings.Contains(err.Error(), "executable file not found") { 172 | t.Skip("Skipping test - Solidity compiler not available") 173 | } 174 | require.NoError(t, err) 175 | } 176 | 177 | // Validate types 178 | assert.ElementsMatch(t, tt.expectedTypes, metadata.Types) 179 | 180 | // Validate counts 181 | assert.Len(t, metadata.ABIs, len(tt.expectedTypes)) 182 | assert.Len(t, metadata.Bins, len(tt.expectedTypes)) 183 | assert.Len(t, metadata.Sigs, len(tt.expectedTypes)) 184 | 185 | // Validate ABIs are valid JSON and contain expected elements 186 | for i, abiStr := range metadata.ABIs { 187 | var abi []interface{} 188 | err := json.Unmarshal([]byte(abiStr), &abi) 189 | require.NoError(t, err, "ABI at index %d should be valid JSON", i) 190 | 191 | // Check if this ABI contains expected elements 192 | contractType := metadata.Types[i] 193 | if expectedElements, ok := tt.expectedABIElements[contractType]; ok { 194 | abiElementNames := extractABIElementNames(abi) 195 | for _, expected := range expectedElements { 196 | assert.Contains(t, abiElementNames, expected, 197 | "Contract %s ABI should contain element %s", contractType, expected) 198 | } 199 | } 200 | } 201 | 202 | // Validate bytecode is not empty (except for libraries/interfaces) 203 | for i, bin := range metadata.Bins { 204 | if bin != "" { 205 | assert.True(t, strings.HasPrefix(bin, "0x") || len(bin) > 0, 206 | "Contract %s should have valid bytecode", metadata.Types[i]) 207 | } 208 | } 209 | 210 | // Validate library patterns 211 | if tt.validateLibs != nil { 212 | tt.validateLibs(t, metadata.Libs) 213 | } 214 | }) 215 | } 216 | } 217 | 218 | // TestParseContract_InvalidSolidity tests ParseContract with invalid Solidity code 219 | func TestParseContract_InvalidSolidity(t *testing.T) { 220 | tests := []struct { 221 | name string 222 | source string 223 | errorContains string 224 | }{ 225 | { 226 | name: "invalid_syntax", 227 | source: "This is not valid Solidity code", 228 | errorContains: "parsing solidity version", 229 | }, 230 | { 231 | name: "missing_pragma", 232 | source: "contract Test {}", 233 | errorContains: "parsing solidity version", 234 | }, 235 | { 236 | name: "syntax_error", 237 | source: ` 238 | pragma solidity ^0.8.0; 239 | 240 | contract SyntaxError { 241 | function broken( 242 | } 243 | `, 244 | errorContains: "compiling:", 245 | }, 246 | } 247 | 248 | for _, tt := range tests { 249 | t.Run(tt.name, func(t *testing.T) { 250 | _, err := ParseContract(tt.source) 251 | 252 | // Skip if compiler is not available 253 | if err != nil && strings.Contains(err.Error(), "resolving compiler") { 254 | t.Skip("Skipping test - Solidity compiler not available") 255 | } 256 | 257 | require.Error(t, err) 258 | assert.Contains(t, err.Error(), tt.errorContains) 259 | }) 260 | } 261 | } 262 | 263 | // TestParseContract_LibraryPatternGeneration tests the library pattern generation 264 | func TestParseContract_LibraryPatternGeneration(t *testing.T) { 265 | source := ` 266 | pragma solidity ^0.8.0; 267 | 268 | contract TestContract { 269 | uint256 public value; 270 | } 271 | ` 272 | 273 | metadata, err := ParseContract(source) 274 | if err != nil { 275 | if strings.Contains(err.Error(), "resolving compiler") { 276 | t.Skip("Skipping test - Solidity compiler not available") 277 | } 278 | require.NoError(t, err) 279 | } 280 | 281 | // Check library pattern generation 282 | require.Len(t, metadata.Libs, 1) 283 | 284 | for pattern, name := range metadata.Libs { 285 | assert.Equal(t, "TestContract", name) 286 | assert.Len(t, pattern, 34) // Keccak256 truncated to 34 chars 287 | 288 | // Verify the pattern is a valid hex string 289 | assert.Regexp(t, "^[0-9a-f]{34}$", pattern) 290 | 291 | // Verify the pattern is correctly generated from the full contract name 292 | // The full name should be something like "source.sol:TestContract" 293 | // We can't know the exact filename, but we can verify the pattern generation logic 294 | for fullName := range map[string]bool{ 295 | "test.sol:TestContract": true, 296 | "source.sol:TestContract": true, 297 | ":TestContract": true, 298 | } { 299 | hash := crypto.Keccak256Hash([]byte(fullName)).String()[2:36] 300 | if hash == pattern { 301 | // Found a match, the pattern is correctly generated 302 | return 303 | } 304 | } 305 | } 306 | } 307 | 308 | // TestContractMetadata tests the ContractMetadata struct 309 | func TestContractMetadata(t *testing.T) { 310 | // Test zero value 311 | var metadata ContractMetadata 312 | assert.Nil(t, metadata.ABIs) 313 | assert.Nil(t, metadata.Bins) 314 | assert.Nil(t, metadata.Types) 315 | assert.Nil(t, metadata.Sigs) 316 | assert.Nil(t, metadata.Libs) 317 | 318 | // Test with initialized values 319 | metadata = ContractMetadata{ 320 | ABIs: []string{`[{"name":"test","type":"function"}]`}, 321 | Bins: []string{"0x608060405234801561001057600080fd5b50"}, 322 | Types: []string{"TestContract"}, 323 | Sigs: []map[string]string{{"test()": "0x12345678"}}, 324 | Libs: map[string]string{"abcdef": "TestLib"}, 325 | } 326 | 327 | assert.Len(t, metadata.ABIs, 1) 328 | assert.Len(t, metadata.Bins, 1) 329 | assert.Len(t, metadata.Types, 1) 330 | assert.Len(t, metadata.Sigs, 1) 331 | assert.Len(t, metadata.Libs, 1) 332 | } 333 | 334 | // TestParseContract_ComplexScenarios tests more complex contract scenarios 335 | func TestParseContract_ComplexScenarios(t *testing.T) { 336 | tests := []struct { 337 | name string 338 | source string 339 | }{ 340 | { 341 | name: "inheritance", 342 | source: ` 343 | pragma solidity ^0.8.0; 344 | 345 | contract Base { 346 | uint256 public baseValue; 347 | } 348 | 349 | contract Derived is Base { 350 | uint256 public derivedValue; 351 | 352 | function setValues(uint256 _base, uint256 _derived) public { 353 | baseValue = _base; 354 | derivedValue = _derived; 355 | } 356 | } 357 | `, 358 | }, 359 | { 360 | name: "abstract_contract", 361 | source: ` 362 | pragma solidity ^0.8.0; 363 | 364 | abstract contract AbstractToken { 365 | function totalSupply() public view virtual returns (uint256); 366 | } 367 | 368 | contract ConcreteToken is AbstractToken { 369 | uint256 private _totalSupply; 370 | 371 | function totalSupply() public view override returns (uint256) { 372 | return _totalSupply; 373 | } 374 | } 375 | `, 376 | }, 377 | { 378 | name: "interface", 379 | source: ` 380 | pragma solidity ^0.8.0; 381 | 382 | interface IERC20 { 383 | function transfer(address to, uint256 amount) external returns (bool); 384 | function balanceOf(address account) external view returns (uint256); 385 | } 386 | 387 | contract Token is IERC20 { 388 | mapping(address => uint256) private balances; 389 | 390 | function transfer(address to, uint256 amount) external override returns (bool) { 391 | balances[msg.sender] -= amount; 392 | balances[to] += amount; 393 | return true; 394 | } 395 | 396 | function balanceOf(address account) external view override returns (uint256) { 397 | return balances[account]; 398 | } 399 | } 400 | `, 401 | }, 402 | } 403 | 404 | for _, tt := range tests { 405 | t.Run(tt.name, func(t *testing.T) { 406 | metadata, err := ParseContract(tt.source) 407 | 408 | if err != nil { 409 | if strings.Contains(err.Error(), "resolving compiler") { 410 | t.Skip("Skipping test - Solidity compiler not available") 411 | } 412 | require.NoError(t, err) 413 | } 414 | 415 | // Just verify it parses successfully and returns metadata 416 | assert.NotEmpty(t, metadata.Types) 417 | assert.NotEmpty(t, metadata.ABIs) 418 | assert.Len(t, metadata.Types, len(metadata.ABIs)) 419 | assert.Len(t, metadata.Types, len(metadata.Bins)) 420 | assert.Len(t, metadata.Types, len(metadata.Sigs)) 421 | }) 422 | } 423 | } 424 | 425 | // Helper function to extract ABI element names 426 | func extractABIElementNames(abi []interface{}) []string { 427 | var names []string 428 | for _, element := range abi { 429 | if m, ok := element.(map[string]interface{}); ok { 430 | if name, ok := m["name"].(string); ok && name != "" { 431 | names = append(names, name) 432 | } 433 | } 434 | } 435 | return names 436 | } 437 | 438 | // BenchmarkParseContract benchmarks the ParseContract function 439 | func BenchmarkParseContract(b *testing.B) { 440 | source := ` 441 | pragma solidity ^0.8.0; 442 | 443 | contract BenchmarkContract { 444 | uint256 public value; 445 | mapping(address => uint256) public balances; 446 | 447 | event Transfer(address indexed from, address indexed to, uint256 value); 448 | 449 | function setValue(uint256 _value) public { 450 | value = _value; 451 | } 452 | 453 | function transfer(address to, uint256 amount) public returns (bool) { 454 | require(balances[msg.sender] >= amount, "Insufficient balance"); 455 | balances[msg.sender] -= amount; 456 | balances[to] += amount; 457 | emit Transfer(msg.sender, to, amount); 458 | return true; 459 | } 460 | } 461 | ` 462 | 463 | // Run once to check if compiler is available 464 | _, err := ParseContract(source) 465 | if err != nil { 466 | if strings.Contains(err.Error(), "resolving compiler") { 467 | b.Skip("Skipping benchmark - Solidity compiler not available") 468 | } 469 | b.Fatal(err) 470 | } 471 | 472 | b.ResetTimer() 473 | for i := 0; i < b.N; i++ { 474 | _, err := ParseContract(source) 475 | if err != nil { 476 | b.Fatal(err) 477 | } 478 | } 479 | } -------------------------------------------------------------------------------- /parser/Solidity.g4: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Gonçalo Sá 2 | // Copyright 2016-2019 Federico Bond 3 | // Licensed under the MIT license. See LICENSE file in the project root for details. 4 | 5 | grammar Solidity; 6 | 7 | sourceUnit 8 | : ( 9 | pragmaDirective 10 | | importDirective 11 | | contractDefinition 12 | | enumDefinition 13 | | structDefinition 14 | | functionDefinition 15 | | fileLevelConstant 16 | | customErrorDefinition 17 | )* EOF ; 18 | 19 | pragmaDirective 20 | : 'pragma' pragmaName pragmaValue ';' ; 21 | 22 | pragmaName 23 | : identifier ; 24 | 25 | pragmaValue 26 | : version | expression ; 27 | 28 | version 29 | : versionConstraint ('||'? versionConstraint)* ; 30 | 31 | versionOperator 32 | : '^' | '~' | '>=' | '>' | '<' | '<=' | '=' ; 33 | 34 | versionConstraint 35 | : versionOperator? VersionLiteral 36 | | versionOperator? DecimalNumber ; 37 | 38 | importDeclaration 39 | : identifier ('as' identifier)? ; 40 | 41 | importDirective 42 | : 'import' importPath ('as' identifier)? ';' 43 | | 'import' ('*' | identifier) ('as' identifier)? 'from' importPath ';' 44 | | 'import' '{' importDeclaration ( ',' importDeclaration )* '}' 'from' importPath ';' ; 45 | 46 | importPath : StringLiteralFragment ; 47 | 48 | contractDefinition 49 | : 'abstract'? ( 'contract' | 'interface' | 'library' ) identifier 50 | ( 'is' inheritanceSpecifier (',' inheritanceSpecifier )* )? 51 | '{' contractPart* '}' ; 52 | 53 | inheritanceSpecifier 54 | : userDefinedTypeName ( '(' expressionList? ')' )? ; 55 | 56 | contractPart 57 | : stateVariableDeclaration 58 | | usingForDeclaration 59 | | structDefinition 60 | | modifierDefinition 61 | | functionDefinition 62 | | eventDefinition 63 | | enumDefinition 64 | | customErrorDefinition; 65 | 66 | stateVariableDeclaration 67 | : typeName 68 | ( PublicKeyword | InternalKeyword | PrivateKeyword | ConstantKeyword | ImmutableKeyword | overrideSpecifier )* 69 | identifier ('=' expression)? ';' ; 70 | 71 | fileLevelConstant 72 | : typeName ConstantKeyword identifier '=' expression ';' ; 73 | 74 | customErrorDefinition 75 | : 'error' identifier parameterList ';' ; 76 | 77 | usingForDeclaration 78 | : 'using' identifier 'for' ('*' | typeName) ';' ; 79 | 80 | structDefinition 81 | : 'struct' identifier 82 | '{' ( variableDeclaration ';' (variableDeclaration ';')* )? '}' ; 83 | 84 | modifierDefinition 85 | : 'modifier' identifier parameterList? ( VirtualKeyword | overrideSpecifier )* ( ';' | block ) ; 86 | 87 | modifierInvocation 88 | : identifier ( '(' expressionList? ')' )? ; 89 | 90 | functionDefinition 91 | : functionDescriptor parameterList modifierList returnParameters? ( ';' | block ) ; 92 | 93 | functionDescriptor 94 | : 'function' identifier? 95 | | ConstructorKeyword 96 | | FallbackKeyword 97 | | ReceiveKeyword ; 98 | 99 | returnParameters 100 | : 'returns' parameterList ; 101 | 102 | modifierList 103 | : (ExternalKeyword | PublicKeyword | InternalKeyword | PrivateKeyword | VirtualKeyword | stateMutability | modifierInvocation | overrideSpecifier )* ; 104 | 105 | eventDefinition 106 | : 'event' identifier eventParameterList AnonymousKeyword? ';' ; 107 | 108 | enumValue 109 | : identifier ; 110 | 111 | enumDefinition 112 | : 'enum' identifier '{' enumValue? (',' enumValue)* '}' ; 113 | 114 | parameterList 115 | : '(' ( parameter (',' parameter)* )? ')' ; 116 | 117 | parameter 118 | : typeName storageLocation? identifier? ; 119 | 120 | eventParameterList 121 | : '(' ( eventParameter (',' eventParameter)* )? ')' ; 122 | 123 | eventParameter 124 | : typeName IndexedKeyword? identifier? ; 125 | 126 | functionTypeParameterList 127 | : '(' ( functionTypeParameter (',' functionTypeParameter)* )? ')' ; 128 | 129 | functionTypeParameter 130 | : typeName storageLocation? ; 131 | 132 | variableDeclaration 133 | : typeName storageLocation? identifier ; 134 | 135 | typeName 136 | : elementaryTypeName 137 | | userDefinedTypeName 138 | | mapping 139 | | typeName '[' expression? ']' 140 | | functionTypeName 141 | | 'address' 'payable' ; 142 | 143 | userDefinedTypeName 144 | : identifier ( '.' identifier )* ; 145 | 146 | mappingKey 147 | : elementaryTypeName 148 | | userDefinedTypeName ; 149 | 150 | mapping 151 | : 'mapping' '(' mappingKey '=>' typeName ')' ; 152 | 153 | functionTypeName 154 | : 'function' functionTypeParameterList 155 | ( InternalKeyword | ExternalKeyword | stateMutability )* 156 | ( 'returns' functionTypeParameterList )? ; 157 | 158 | storageLocation 159 | : 'memory' | 'storage' | 'calldata'; 160 | 161 | stateMutability 162 | : PureKeyword | ConstantKeyword | ViewKeyword | PayableKeyword ; 163 | 164 | block 165 | : '{' statement* '}' ; 166 | 167 | statement 168 | : ifStatement 169 | | tryStatement 170 | | whileStatement 171 | | forStatement 172 | | block 173 | | inlineAssemblyStatement 174 | | doWhileStatement 175 | | continueStatement 176 | | breakStatement 177 | | returnStatement 178 | | throwStatement 179 | | emitStatement 180 | | simpleStatement 181 | | uncheckedStatement 182 | | revertStatement; 183 | 184 | expressionStatement 185 | : expression ';' ; 186 | 187 | ifStatement 188 | : 'if' '(' expression ')' statement ( 'else' statement )? ; 189 | 190 | tryStatement : 'try' expression returnParameters? block catchClause+ ; 191 | 192 | // In reality catch clauses still are not processed as below 193 | // the identifier can only be a set string: "Error". But plans 194 | // of the Solidity team include possible expansion so we'll 195 | // leave this as is, befitting with the Solidity docs. 196 | catchClause : 'catch' ( identifier? parameterList )? block ; 197 | 198 | whileStatement 199 | : 'while' '(' expression ')' statement ; 200 | 201 | simpleStatement 202 | : ( variableDeclarationStatement | expressionStatement ) ; 203 | 204 | uncheckedStatement 205 | : 'unchecked' block ; 206 | 207 | forStatement 208 | : 'for' '(' ( simpleStatement | ';' ) ( expressionStatement | ';' ) expression? ')' statement ; 209 | 210 | inlineAssemblyStatement 211 | : 'assembly' StringLiteralFragment? assemblyBlock ; 212 | 213 | doWhileStatement 214 | : 'do' statement 'while' '(' expression ')' ';' ; 215 | 216 | continueStatement 217 | : 'continue' ';' ; 218 | 219 | breakStatement 220 | : 'break' ';' ; 221 | 222 | returnStatement 223 | : 'return' expression? ';' ; 224 | 225 | throwStatement 226 | : 'throw' ';' ; 227 | 228 | emitStatement 229 | : 'emit' functionCall ';' ; 230 | 231 | revertStatement 232 | : 'revert' functionCall ';' ; 233 | 234 | variableDeclarationStatement 235 | : ( 'var' identifierList | variableDeclaration | '(' variableDeclarationList ')' ) ( '=' expression )? ';'; 236 | 237 | variableDeclarationList 238 | : variableDeclaration? (',' variableDeclaration? )* ; 239 | 240 | identifierList 241 | : '(' ( identifier? ',' )* identifier? ')' ; 242 | 243 | elementaryTypeName 244 | : 'address' | 'bool' | 'string' | 'var' | Int | Uint | 'byte' | Byte | Fixed | Ufixed ; 245 | 246 | Int 247 | : 'int' | 'int8' | 'int16' | 'int24' | 'int32' | 'int40' | 'int48' | 'int56' | 'int64' | 'int72' | 'int80' | 'int88' | 'int96' | 'int104' | 'int112' | 'int120' | 'int128' | 'int136' | 'int144' | 'int152' | 'int160' | 'int168' | 'int176' | 'int184' | 'int192' | 'int200' | 'int208' | 'int216' | 'int224' | 'int232' | 'int240' | 'int248' | 'int256' ; 248 | 249 | Uint 250 | : 'uint' | 'uint8' | 'uint16' | 'uint24' | 'uint32' | 'uint40' | 'uint48' | 'uint56' | 'uint64' | 'uint72' | 'uint80' | 'uint88' | 'uint96' | 'uint104' | 'uint112' | 'uint120' | 'uint128' | 'uint136' | 'uint144' | 'uint152' | 'uint160' | 'uint168' | 'uint176' | 'uint184' | 'uint192' | 'uint200' | 'uint208' | 'uint216' | 'uint224' | 'uint232' | 'uint240' | 'uint248' | 'uint256' ; 251 | 252 | Byte 253 | : 'bytes' | 'bytes1' | 'bytes2' | 'bytes3' | 'bytes4' | 'bytes5' | 'bytes6' | 'bytes7' | 'bytes8' | 'bytes9' | 'bytes10' | 'bytes11' | 'bytes12' | 'bytes13' | 'bytes14' | 'bytes15' | 'bytes16' | 'bytes17' | 'bytes18' | 'bytes19' | 'bytes20' | 'bytes21' | 'bytes22' | 'bytes23' | 'bytes24' | 'bytes25' | 'bytes26' | 'bytes27' | 'bytes28' | 'bytes29' | 'bytes30' | 'bytes31' | 'bytes32' ; 254 | 255 | Fixed 256 | : 'fixed' | ( 'fixed' [0-9]+ 'x' [0-9]+ ) ; 257 | 258 | Ufixed 259 | : 'ufixed' | ( 'ufixed' [0-9]+ 'x' [0-9]+ ) ; 260 | 261 | expression 262 | : expression ('++' | '--') 263 | | 'new' typeName 264 | | expression '[' expression ']' 265 | | expression '[' expression? ':' expression? ']' 266 | | expression '.' identifier 267 | | expression '{' nameValueList '}' 268 | | expression '(' functionCallArguments ')' 269 | | '(' expression ')' 270 | | ('++' | '--') expression 271 | | ('+' | '-') expression 272 | | ('after' | 'delete') expression 273 | | '!' expression 274 | | '~' expression 275 | | expression '**' expression 276 | | expression ('*' | '/' | '%') expression 277 | | expression ('+' | '-') expression 278 | | expression ('<<' | '>>') expression 279 | | expression '&' expression 280 | | expression '^' expression 281 | | expression '|' expression 282 | | expression ('<' | '>' | '<=' | '>=') expression 283 | | expression ('==' | '!=') expression 284 | | expression '&&' expression 285 | | expression '||' expression 286 | | expression '?' expression ':' expression 287 | | expression ('=' | '|=' | '^=' | '&=' | '<<=' | '>>=' | '+=' | '-=' | '*=' | '/=' | '%=') expression 288 | | primaryExpression ; 289 | 290 | primaryExpression 291 | : BooleanLiteral 292 | | numberLiteral 293 | | hexLiteral 294 | | stringLiteral 295 | | identifier ('[' ']')? 296 | | TypeKeyword 297 | | PayableKeyword 298 | | tupleExpression 299 | | typeNameExpression ('[' ']')? ; 300 | 301 | expressionList 302 | : expression (',' expression)* ; 303 | 304 | nameValueList 305 | : nameValue (',' nameValue)* ','? ; 306 | 307 | nameValue 308 | : identifier ':' expression ; 309 | 310 | functionCallArguments 311 | : '{' nameValueList? '}' 312 | | expressionList? ; 313 | 314 | functionCall 315 | : expression '(' functionCallArguments ')' ; 316 | 317 | assemblyBlock 318 | : '{' assemblyItem* '}' ; 319 | 320 | assemblyItem 321 | : identifier 322 | | assemblyBlock 323 | | assemblyExpression 324 | | assemblyLocalDefinition 325 | | assemblyAssignment 326 | | assemblyStackAssignment 327 | | labelDefinition 328 | | assemblySwitch 329 | | assemblyFunctionDefinition 330 | | assemblyFor 331 | | assemblyIf 332 | | BreakKeyword 333 | | ContinueKeyword 334 | | LeaveKeyword 335 | | subAssembly 336 | | numberLiteral 337 | | stringLiteral 338 | | hexLiteral ; 339 | 340 | assemblyExpression 341 | : assemblyCall | assemblyLiteral | assemblyMember ; 342 | 343 | assemblyMember 344 | : identifier '.' identifier ; 345 | 346 | assemblyCall 347 | : ( 'return' | 'address' | 'byte' | identifier ) ( '(' assemblyExpression? ( ',' assemblyExpression )* ')' )? ; 348 | 349 | assemblyLocalDefinition 350 | : 'let' assemblyIdentifierOrList ( ':=' assemblyExpression )? ; 351 | 352 | assemblyAssignment 353 | : assemblyIdentifierOrList ':=' assemblyExpression ; 354 | 355 | assemblyIdentifierOrList 356 | : identifier | assemblyMember | '(' assemblyIdentifierList ')' ; 357 | 358 | assemblyIdentifierList 359 | : identifier ( ',' identifier )* ; 360 | 361 | assemblyStackAssignment 362 | : '=:' identifier ; 363 | 364 | labelDefinition 365 | : identifier ':' ; 366 | 367 | assemblySwitch 368 | : 'switch' assemblyExpression assemblyCase* ; 369 | 370 | assemblyCase 371 | : 'case' assemblyLiteral assemblyBlock 372 | | 'default' assemblyBlock ; 373 | 374 | assemblyFunctionDefinition 375 | : 'function' identifier '(' assemblyIdentifierList? ')' 376 | assemblyFunctionReturns? assemblyBlock ; 377 | 378 | assemblyFunctionReturns 379 | : ( '->' assemblyIdentifierList ) ; 380 | 381 | assemblyFor 382 | : 'for' ( assemblyBlock | assemblyExpression ) 383 | assemblyExpression ( assemblyBlock | assemblyExpression ) assemblyBlock ; 384 | 385 | assemblyIf 386 | : 'if' assemblyExpression assemblyBlock ; 387 | 388 | assemblyLiteral 389 | : stringLiteral | DecimalNumber | HexNumber | hexLiteral ; 390 | 391 | subAssembly 392 | : 'assembly' identifier assemblyBlock ; 393 | 394 | tupleExpression 395 | : '(' ( expression? ( ',' expression? )* ) ')' 396 | | '[' ( expression ( ',' expression )* )? ']' ; 397 | 398 | typeNameExpression 399 | : elementaryTypeName 400 | | userDefinedTypeName ; 401 | 402 | numberLiteral 403 | : (DecimalNumber | HexNumber) NumberUnit? ; 404 | 405 | // some keywords need to be added here to avoid ambiguities 406 | // for example, "revert" is a keyword but it can also be a function name 407 | identifier 408 | : ('from' | 'calldata' | 'receive' | 'callback' | 'revert' | 'error' | ConstructorKeyword | PayableKeyword | LeaveKeyword | Identifier) ; 409 | 410 | BooleanLiteral 411 | : 'true' | 'false' ; 412 | 413 | DecimalNumber 414 | : ( DecimalDigits | (DecimalDigits? '.' DecimalDigits) ) ( [eE] DecimalDigits )? ; 415 | 416 | fragment 417 | DecimalDigits 418 | : [0-9] ( '_'? [0-9] )* ; 419 | 420 | HexNumber 421 | : '0' [xX] HexDigits ; 422 | 423 | fragment 424 | HexDigits 425 | : HexCharacter ( '_'? HexCharacter )* ; 426 | 427 | NumberUnit 428 | : 'wei' | 'gwei' | 'szabo' | 'finney' | 'ether' 429 | | 'seconds' | 'minutes' | 'hours' | 'days' | 'weeks' | 'years' ; 430 | 431 | hexLiteral : HexLiteralFragment+ ; 432 | 433 | HexLiteralFragment : 'hex' ('"' HexDigits? '"' | '\'' HexDigits? '\'') ; 434 | 435 | fragment 436 | HexPair 437 | : HexCharacter HexCharacter ; 438 | 439 | fragment 440 | HexCharacter 441 | : [0-9A-Fa-f] ; 442 | 443 | ReservedKeyword 444 | : 'abstract' 445 | | 'after' 446 | | 'case' 447 | | 'catch' 448 | | 'default' 449 | | 'final' 450 | | 'in' 451 | | 'inline' 452 | | 'let' 453 | | 'match' 454 | | 'null' 455 | | 'of' 456 | | 'relocatable' 457 | | 'static' 458 | | 'switch' 459 | | 'try' 460 | | 'typeof' ; 461 | 462 | AnonymousKeyword : 'anonymous' ; 463 | BreakKeyword : 'break' ; 464 | ConstantKeyword : 'constant' ; 465 | ImmutableKeyword : 'immutable' ; 466 | ContinueKeyword : 'continue' ; 467 | LeaveKeyword : 'leave' ; 468 | ExternalKeyword : 'external' ; 469 | IndexedKeyword : 'indexed' ; 470 | InternalKeyword : 'internal' ; 471 | PayableKeyword : 'payable' ; 472 | PrivateKeyword : 'private' ; 473 | PublicKeyword : 'public' ; 474 | VirtualKeyword : 'virtual' ; 475 | PureKeyword : 'pure' ; 476 | TypeKeyword : 'type' ; 477 | ViewKeyword : 'view' ; 478 | 479 | ConstructorKeyword : 'constructor' ; 480 | FallbackKeyword : 'fallback' ; 481 | ReceiveKeyword : 'receive' ; 482 | 483 | overrideSpecifier : 'override' ( '(' userDefinedTypeName (',' userDefinedTypeName)* ')' )? ; 484 | 485 | Identifier 486 | : IdentifierStart IdentifierPart* ; 487 | 488 | fragment 489 | IdentifierStart 490 | : [a-zA-Z$_] ; 491 | 492 | fragment 493 | IdentifierPart 494 | : [a-zA-Z0-9$_] ; 495 | 496 | stringLiteral 497 | : StringLiteralFragment+ ; 498 | 499 | StringLiteralFragment 500 | : 'unicode'? '"' DoubleQuotedStringCharacter* '"' 501 | | 'unicode'? '\'' SingleQuotedStringCharacter* '\'' ; 502 | 503 | fragment 504 | DoubleQuotedStringCharacter 505 | : ~["\r\n\\] | ('\\' .) ; 506 | 507 | fragment 508 | SingleQuotedStringCharacter 509 | : ~['\r\n\\] | ('\\' .) ; 510 | 511 | VersionLiteral 512 | : [0-9]+ '.' [0-9]+ ('.' [0-9]+)? ; 513 | 514 | WS 515 | : [ \t\r\n\u000C]+ -> skip ; 516 | 517 | COMMENT 518 | : '/*' .*? '*/' -> channel(HIDDEN) ; 519 | 520 | LINE_COMMENT 521 | : '//' ~[\r\n]* -> channel(HIDDEN) ; -------------------------------------------------------------------------------- /parser/solidity_listener.go: -------------------------------------------------------------------------------- 1 | // Code generated from parser/Solidity.g4 by ANTLR 4.9.2. DO NOT EDIT. 2 | 3 | package parser // Solidity 4 | 5 | import "github.com/antlr/antlr4/runtime/Go/antlr" 6 | 7 | // SolidityListener is a complete listener for a parse tree produced by SolidityParser. 8 | type SolidityListener interface { 9 | antlr.ParseTreeListener 10 | 11 | // EnterSourceUnit is called when entering the sourceUnit production. 12 | EnterSourceUnit(c *SourceUnitContext) 13 | 14 | // EnterPragmaDirective is called when entering the pragmaDirective production. 15 | EnterPragmaDirective(c *PragmaDirectiveContext) 16 | 17 | // EnterPragmaName is called when entering the pragmaName production. 18 | EnterPragmaName(c *PragmaNameContext) 19 | 20 | // EnterPragmaValue is called when entering the pragmaValue production. 21 | EnterPragmaValue(c *PragmaValueContext) 22 | 23 | // EnterVersion is called when entering the version production. 24 | EnterVersion(c *VersionContext) 25 | 26 | // EnterVersionOperator is called when entering the versionOperator production. 27 | EnterVersionOperator(c *VersionOperatorContext) 28 | 29 | // EnterVersionConstraint is called when entering the versionConstraint production. 30 | EnterVersionConstraint(c *VersionConstraintContext) 31 | 32 | // EnterImportDeclaration is called when entering the importDeclaration production. 33 | EnterImportDeclaration(c *ImportDeclarationContext) 34 | 35 | // EnterImportDirective is called when entering the importDirective production. 36 | EnterImportDirective(c *ImportDirectiveContext) 37 | 38 | // EnterImportPath is called when entering the importPath production. 39 | EnterImportPath(c *ImportPathContext) 40 | 41 | // EnterContractDefinition is called when entering the contractDefinition production. 42 | EnterContractDefinition(c *ContractDefinitionContext) 43 | 44 | // EnterInheritanceSpecifier is called when entering the inheritanceSpecifier production. 45 | EnterInheritanceSpecifier(c *InheritanceSpecifierContext) 46 | 47 | // EnterContractPart is called when entering the contractPart production. 48 | EnterContractPart(c *ContractPartContext) 49 | 50 | // EnterStateVariableDeclaration is called when entering the stateVariableDeclaration production. 51 | EnterStateVariableDeclaration(c *StateVariableDeclarationContext) 52 | 53 | // EnterFileLevelConstant is called when entering the fileLevelConstant production. 54 | EnterFileLevelConstant(c *FileLevelConstantContext) 55 | 56 | // EnterCustomErrorDefinition is called when entering the customErrorDefinition production. 57 | EnterCustomErrorDefinition(c *CustomErrorDefinitionContext) 58 | 59 | // EnterUsingForDeclaration is called when entering the usingForDeclaration production. 60 | EnterUsingForDeclaration(c *UsingForDeclarationContext) 61 | 62 | // EnterStructDefinition is called when entering the structDefinition production. 63 | EnterStructDefinition(c *StructDefinitionContext) 64 | 65 | // EnterModifierDefinition is called when entering the modifierDefinition production. 66 | EnterModifierDefinition(c *ModifierDefinitionContext) 67 | 68 | // EnterModifierInvocation is called when entering the modifierInvocation production. 69 | EnterModifierInvocation(c *ModifierInvocationContext) 70 | 71 | // EnterFunctionDefinition is called when entering the functionDefinition production. 72 | EnterFunctionDefinition(c *FunctionDefinitionContext) 73 | 74 | // EnterFunctionDescriptor is called when entering the functionDescriptor production. 75 | EnterFunctionDescriptor(c *FunctionDescriptorContext) 76 | 77 | // EnterReturnParameters is called when entering the returnParameters production. 78 | EnterReturnParameters(c *ReturnParametersContext) 79 | 80 | // EnterModifierList is called when entering the modifierList production. 81 | EnterModifierList(c *ModifierListContext) 82 | 83 | // EnterEventDefinition is called when entering the eventDefinition production. 84 | EnterEventDefinition(c *EventDefinitionContext) 85 | 86 | // EnterEnumValue is called when entering the enumValue production. 87 | EnterEnumValue(c *EnumValueContext) 88 | 89 | // EnterEnumDefinition is called when entering the enumDefinition production. 90 | EnterEnumDefinition(c *EnumDefinitionContext) 91 | 92 | // EnterParameterList is called when entering the parameterList production. 93 | EnterParameterList(c *ParameterListContext) 94 | 95 | // EnterParameter is called when entering the parameter production. 96 | EnterParameter(c *ParameterContext) 97 | 98 | // EnterEventParameterList is called when entering the eventParameterList production. 99 | EnterEventParameterList(c *EventParameterListContext) 100 | 101 | // EnterEventParameter is called when entering the eventParameter production. 102 | EnterEventParameter(c *EventParameterContext) 103 | 104 | // EnterFunctionTypeParameterList is called when entering the functionTypeParameterList production. 105 | EnterFunctionTypeParameterList(c *FunctionTypeParameterListContext) 106 | 107 | // EnterFunctionTypeParameter is called when entering the functionTypeParameter production. 108 | EnterFunctionTypeParameter(c *FunctionTypeParameterContext) 109 | 110 | // EnterVariableDeclaration is called when entering the variableDeclaration production. 111 | EnterVariableDeclaration(c *VariableDeclarationContext) 112 | 113 | // EnterTypeName is called when entering the typeName production. 114 | EnterTypeName(c *TypeNameContext) 115 | 116 | // EnterUserDefinedTypeName is called when entering the userDefinedTypeName production. 117 | EnterUserDefinedTypeName(c *UserDefinedTypeNameContext) 118 | 119 | // EnterMappingKey is called when entering the mappingKey production. 120 | EnterMappingKey(c *MappingKeyContext) 121 | 122 | // EnterMapping is called when entering the mapping production. 123 | EnterMapping(c *MappingContext) 124 | 125 | // EnterFunctionTypeName is called when entering the functionTypeName production. 126 | EnterFunctionTypeName(c *FunctionTypeNameContext) 127 | 128 | // EnterStorageLocation is called when entering the storageLocation production. 129 | EnterStorageLocation(c *StorageLocationContext) 130 | 131 | // EnterStateMutability is called when entering the stateMutability production. 132 | EnterStateMutability(c *StateMutabilityContext) 133 | 134 | // EnterBlock is called when entering the block production. 135 | EnterBlock(c *BlockContext) 136 | 137 | // EnterStatement is called when entering the statement production. 138 | EnterStatement(c *StatementContext) 139 | 140 | // EnterExpressionStatement is called when entering the expressionStatement production. 141 | EnterExpressionStatement(c *ExpressionStatementContext) 142 | 143 | // EnterIfStatement is called when entering the ifStatement production. 144 | EnterIfStatement(c *IfStatementContext) 145 | 146 | // EnterTryStatement is called when entering the tryStatement production. 147 | EnterTryStatement(c *TryStatementContext) 148 | 149 | // EnterCatchClause is called when entering the catchClause production. 150 | EnterCatchClause(c *CatchClauseContext) 151 | 152 | // EnterWhileStatement is called when entering the whileStatement production. 153 | EnterWhileStatement(c *WhileStatementContext) 154 | 155 | // EnterSimpleStatement is called when entering the simpleStatement production. 156 | EnterSimpleStatement(c *SimpleStatementContext) 157 | 158 | // EnterUncheckedStatement is called when entering the uncheckedStatement production. 159 | EnterUncheckedStatement(c *UncheckedStatementContext) 160 | 161 | // EnterForStatement is called when entering the forStatement production. 162 | EnterForStatement(c *ForStatementContext) 163 | 164 | // EnterInlineAssemblyStatement is called when entering the inlineAssemblyStatement production. 165 | EnterInlineAssemblyStatement(c *InlineAssemblyStatementContext) 166 | 167 | // EnterDoWhileStatement is called when entering the doWhileStatement production. 168 | EnterDoWhileStatement(c *DoWhileStatementContext) 169 | 170 | // EnterContinueStatement is called when entering the continueStatement production. 171 | EnterContinueStatement(c *ContinueStatementContext) 172 | 173 | // EnterBreakStatement is called when entering the breakStatement production. 174 | EnterBreakStatement(c *BreakStatementContext) 175 | 176 | // EnterReturnStatement is called when entering the returnStatement production. 177 | EnterReturnStatement(c *ReturnStatementContext) 178 | 179 | // EnterThrowStatement is called when entering the throwStatement production. 180 | EnterThrowStatement(c *ThrowStatementContext) 181 | 182 | // EnterEmitStatement is called when entering the emitStatement production. 183 | EnterEmitStatement(c *EmitStatementContext) 184 | 185 | // EnterRevertStatement is called when entering the revertStatement production. 186 | EnterRevertStatement(c *RevertStatementContext) 187 | 188 | // EnterVariableDeclarationStatement is called when entering the variableDeclarationStatement production. 189 | EnterVariableDeclarationStatement(c *VariableDeclarationStatementContext) 190 | 191 | // EnterVariableDeclarationList is called when entering the variableDeclarationList production. 192 | EnterVariableDeclarationList(c *VariableDeclarationListContext) 193 | 194 | // EnterIdentifierList is called when entering the identifierList production. 195 | EnterIdentifierList(c *IdentifierListContext) 196 | 197 | // EnterElementaryTypeName is called when entering the elementaryTypeName production. 198 | EnterElementaryTypeName(c *ElementaryTypeNameContext) 199 | 200 | // EnterExpression is called when entering the expression production. 201 | EnterExpression(c *ExpressionContext) 202 | 203 | // EnterPrimaryExpression is called when entering the primaryExpression production. 204 | EnterPrimaryExpression(c *PrimaryExpressionContext) 205 | 206 | // EnterExpressionList is called when entering the expressionList production. 207 | EnterExpressionList(c *ExpressionListContext) 208 | 209 | // EnterNameValueList is called when entering the nameValueList production. 210 | EnterNameValueList(c *NameValueListContext) 211 | 212 | // EnterNameValue is called when entering the nameValue production. 213 | EnterNameValue(c *NameValueContext) 214 | 215 | // EnterFunctionCallArguments is called when entering the functionCallArguments production. 216 | EnterFunctionCallArguments(c *FunctionCallArgumentsContext) 217 | 218 | // EnterFunctionCall is called when entering the functionCall production. 219 | EnterFunctionCall(c *FunctionCallContext) 220 | 221 | // EnterAssemblyBlock is called when entering the assemblyBlock production. 222 | EnterAssemblyBlock(c *AssemblyBlockContext) 223 | 224 | // EnterAssemblyItem is called when entering the assemblyItem production. 225 | EnterAssemblyItem(c *AssemblyItemContext) 226 | 227 | // EnterAssemblyExpression is called when entering the assemblyExpression production. 228 | EnterAssemblyExpression(c *AssemblyExpressionContext) 229 | 230 | // EnterAssemblyMember is called when entering the assemblyMember production. 231 | EnterAssemblyMember(c *AssemblyMemberContext) 232 | 233 | // EnterAssemblyCall is called when entering the assemblyCall production. 234 | EnterAssemblyCall(c *AssemblyCallContext) 235 | 236 | // EnterAssemblyLocalDefinition is called when entering the assemblyLocalDefinition production. 237 | EnterAssemblyLocalDefinition(c *AssemblyLocalDefinitionContext) 238 | 239 | // EnterAssemblyAssignment is called when entering the assemblyAssignment production. 240 | EnterAssemblyAssignment(c *AssemblyAssignmentContext) 241 | 242 | // EnterAssemblyIdentifierOrList is called when entering the assemblyIdentifierOrList production. 243 | EnterAssemblyIdentifierOrList(c *AssemblyIdentifierOrListContext) 244 | 245 | // EnterAssemblyIdentifierList is called when entering the assemblyIdentifierList production. 246 | EnterAssemblyIdentifierList(c *AssemblyIdentifierListContext) 247 | 248 | // EnterAssemblyStackAssignment is called when entering the assemblyStackAssignment production. 249 | EnterAssemblyStackAssignment(c *AssemblyStackAssignmentContext) 250 | 251 | // EnterLabelDefinition is called when entering the labelDefinition production. 252 | EnterLabelDefinition(c *LabelDefinitionContext) 253 | 254 | // EnterAssemblySwitch is called when entering the assemblySwitch production. 255 | EnterAssemblySwitch(c *AssemblySwitchContext) 256 | 257 | // EnterAssemblyCase is called when entering the assemblyCase production. 258 | EnterAssemblyCase(c *AssemblyCaseContext) 259 | 260 | // EnterAssemblyFunctionDefinition is called when entering the assemblyFunctionDefinition production. 261 | EnterAssemblyFunctionDefinition(c *AssemblyFunctionDefinitionContext) 262 | 263 | // EnterAssemblyFunctionReturns is called when entering the assemblyFunctionReturns production. 264 | EnterAssemblyFunctionReturns(c *AssemblyFunctionReturnsContext) 265 | 266 | // EnterAssemblyFor is called when entering the assemblyFor production. 267 | EnterAssemblyFor(c *AssemblyForContext) 268 | 269 | // EnterAssemblyIf is called when entering the assemblyIf production. 270 | EnterAssemblyIf(c *AssemblyIfContext) 271 | 272 | // EnterAssemblyLiteral is called when entering the assemblyLiteral production. 273 | EnterAssemblyLiteral(c *AssemblyLiteralContext) 274 | 275 | // EnterSubAssembly is called when entering the subAssembly production. 276 | EnterSubAssembly(c *SubAssemblyContext) 277 | 278 | // EnterTupleExpression is called when entering the tupleExpression production. 279 | EnterTupleExpression(c *TupleExpressionContext) 280 | 281 | // EnterTypeNameExpression is called when entering the typeNameExpression production. 282 | EnterTypeNameExpression(c *TypeNameExpressionContext) 283 | 284 | // EnterNumberLiteral is called when entering the numberLiteral production. 285 | EnterNumberLiteral(c *NumberLiteralContext) 286 | 287 | // EnterIdentifier is called when entering the identifier production. 288 | EnterIdentifier(c *IdentifierContext) 289 | 290 | // EnterHexLiteral is called when entering the hexLiteral production. 291 | EnterHexLiteral(c *HexLiteralContext) 292 | 293 | // EnterOverrideSpecifier is called when entering the overrideSpecifier production. 294 | EnterOverrideSpecifier(c *OverrideSpecifierContext) 295 | 296 | // EnterStringLiteral is called when entering the stringLiteral production. 297 | EnterStringLiteral(c *StringLiteralContext) 298 | 299 | // ExitSourceUnit is called when exiting the sourceUnit production. 300 | ExitSourceUnit(c *SourceUnitContext) 301 | 302 | // ExitPragmaDirective is called when exiting the pragmaDirective production. 303 | ExitPragmaDirective(c *PragmaDirectiveContext) 304 | 305 | // ExitPragmaName is called when exiting the pragmaName production. 306 | ExitPragmaName(c *PragmaNameContext) 307 | 308 | // ExitPragmaValue is called when exiting the pragmaValue production. 309 | ExitPragmaValue(c *PragmaValueContext) 310 | 311 | // ExitVersion is called when exiting the version production. 312 | ExitVersion(c *VersionContext) 313 | 314 | // ExitVersionOperator is called when exiting the versionOperator production. 315 | ExitVersionOperator(c *VersionOperatorContext) 316 | 317 | // ExitVersionConstraint is called when exiting the versionConstraint production. 318 | ExitVersionConstraint(c *VersionConstraintContext) 319 | 320 | // ExitImportDeclaration is called when exiting the importDeclaration production. 321 | ExitImportDeclaration(c *ImportDeclarationContext) 322 | 323 | // ExitImportDirective is called when exiting the importDirective production. 324 | ExitImportDirective(c *ImportDirectiveContext) 325 | 326 | // ExitImportPath is called when exiting the importPath production. 327 | ExitImportPath(c *ImportPathContext) 328 | 329 | // ExitContractDefinition is called when exiting the contractDefinition production. 330 | ExitContractDefinition(c *ContractDefinitionContext) 331 | 332 | // ExitInheritanceSpecifier is called when exiting the inheritanceSpecifier production. 333 | ExitInheritanceSpecifier(c *InheritanceSpecifierContext) 334 | 335 | // ExitContractPart is called when exiting the contractPart production. 336 | ExitContractPart(c *ContractPartContext) 337 | 338 | // ExitStateVariableDeclaration is called when exiting the stateVariableDeclaration production. 339 | ExitStateVariableDeclaration(c *StateVariableDeclarationContext) 340 | 341 | // ExitFileLevelConstant is called when exiting the fileLevelConstant production. 342 | ExitFileLevelConstant(c *FileLevelConstantContext) 343 | 344 | // ExitCustomErrorDefinition is called when exiting the customErrorDefinition production. 345 | ExitCustomErrorDefinition(c *CustomErrorDefinitionContext) 346 | 347 | // ExitUsingForDeclaration is called when exiting the usingForDeclaration production. 348 | ExitUsingForDeclaration(c *UsingForDeclarationContext) 349 | 350 | // ExitStructDefinition is called when exiting the structDefinition production. 351 | ExitStructDefinition(c *StructDefinitionContext) 352 | 353 | // ExitModifierDefinition is called when exiting the modifierDefinition production. 354 | ExitModifierDefinition(c *ModifierDefinitionContext) 355 | 356 | // ExitModifierInvocation is called when exiting the modifierInvocation production. 357 | ExitModifierInvocation(c *ModifierInvocationContext) 358 | 359 | // ExitFunctionDefinition is called when exiting the functionDefinition production. 360 | ExitFunctionDefinition(c *FunctionDefinitionContext) 361 | 362 | // ExitFunctionDescriptor is called when exiting the functionDescriptor production. 363 | ExitFunctionDescriptor(c *FunctionDescriptorContext) 364 | 365 | // ExitReturnParameters is called when exiting the returnParameters production. 366 | ExitReturnParameters(c *ReturnParametersContext) 367 | 368 | // ExitModifierList is called when exiting the modifierList production. 369 | ExitModifierList(c *ModifierListContext) 370 | 371 | // ExitEventDefinition is called when exiting the eventDefinition production. 372 | ExitEventDefinition(c *EventDefinitionContext) 373 | 374 | // ExitEnumValue is called when exiting the enumValue production. 375 | ExitEnumValue(c *EnumValueContext) 376 | 377 | // ExitEnumDefinition is called when exiting the enumDefinition production. 378 | ExitEnumDefinition(c *EnumDefinitionContext) 379 | 380 | // ExitParameterList is called when exiting the parameterList production. 381 | ExitParameterList(c *ParameterListContext) 382 | 383 | // ExitParameter is called when exiting the parameter production. 384 | ExitParameter(c *ParameterContext) 385 | 386 | // ExitEventParameterList is called when exiting the eventParameterList production. 387 | ExitEventParameterList(c *EventParameterListContext) 388 | 389 | // ExitEventParameter is called when exiting the eventParameter production. 390 | ExitEventParameter(c *EventParameterContext) 391 | 392 | // ExitFunctionTypeParameterList is called when exiting the functionTypeParameterList production. 393 | ExitFunctionTypeParameterList(c *FunctionTypeParameterListContext) 394 | 395 | // ExitFunctionTypeParameter is called when exiting the functionTypeParameter production. 396 | ExitFunctionTypeParameter(c *FunctionTypeParameterContext) 397 | 398 | // ExitVariableDeclaration is called when exiting the variableDeclaration production. 399 | ExitVariableDeclaration(c *VariableDeclarationContext) 400 | 401 | // ExitTypeName is called when exiting the typeName production. 402 | ExitTypeName(c *TypeNameContext) 403 | 404 | // ExitUserDefinedTypeName is called when exiting the userDefinedTypeName production. 405 | ExitUserDefinedTypeName(c *UserDefinedTypeNameContext) 406 | 407 | // ExitMappingKey is called when exiting the mappingKey production. 408 | ExitMappingKey(c *MappingKeyContext) 409 | 410 | // ExitMapping is called when exiting the mapping production. 411 | ExitMapping(c *MappingContext) 412 | 413 | // ExitFunctionTypeName is called when exiting the functionTypeName production. 414 | ExitFunctionTypeName(c *FunctionTypeNameContext) 415 | 416 | // ExitStorageLocation is called when exiting the storageLocation production. 417 | ExitStorageLocation(c *StorageLocationContext) 418 | 419 | // ExitStateMutability is called when exiting the stateMutability production. 420 | ExitStateMutability(c *StateMutabilityContext) 421 | 422 | // ExitBlock is called when exiting the block production. 423 | ExitBlock(c *BlockContext) 424 | 425 | // ExitStatement is called when exiting the statement production. 426 | ExitStatement(c *StatementContext) 427 | 428 | // ExitExpressionStatement is called when exiting the expressionStatement production. 429 | ExitExpressionStatement(c *ExpressionStatementContext) 430 | 431 | // ExitIfStatement is called when exiting the ifStatement production. 432 | ExitIfStatement(c *IfStatementContext) 433 | 434 | // ExitTryStatement is called when exiting the tryStatement production. 435 | ExitTryStatement(c *TryStatementContext) 436 | 437 | // ExitCatchClause is called when exiting the catchClause production. 438 | ExitCatchClause(c *CatchClauseContext) 439 | 440 | // ExitWhileStatement is called when exiting the whileStatement production. 441 | ExitWhileStatement(c *WhileStatementContext) 442 | 443 | // ExitSimpleStatement is called when exiting the simpleStatement production. 444 | ExitSimpleStatement(c *SimpleStatementContext) 445 | 446 | // ExitUncheckedStatement is called when exiting the uncheckedStatement production. 447 | ExitUncheckedStatement(c *UncheckedStatementContext) 448 | 449 | // ExitForStatement is called when exiting the forStatement production. 450 | ExitForStatement(c *ForStatementContext) 451 | 452 | // ExitInlineAssemblyStatement is called when exiting the inlineAssemblyStatement production. 453 | ExitInlineAssemblyStatement(c *InlineAssemblyStatementContext) 454 | 455 | // ExitDoWhileStatement is called when exiting the doWhileStatement production. 456 | ExitDoWhileStatement(c *DoWhileStatementContext) 457 | 458 | // ExitContinueStatement is called when exiting the continueStatement production. 459 | ExitContinueStatement(c *ContinueStatementContext) 460 | 461 | // ExitBreakStatement is called when exiting the breakStatement production. 462 | ExitBreakStatement(c *BreakStatementContext) 463 | 464 | // ExitReturnStatement is called when exiting the returnStatement production. 465 | ExitReturnStatement(c *ReturnStatementContext) 466 | 467 | // ExitThrowStatement is called when exiting the throwStatement production. 468 | ExitThrowStatement(c *ThrowStatementContext) 469 | 470 | // ExitEmitStatement is called when exiting the emitStatement production. 471 | ExitEmitStatement(c *EmitStatementContext) 472 | 473 | // ExitRevertStatement is called when exiting the revertStatement production. 474 | ExitRevertStatement(c *RevertStatementContext) 475 | 476 | // ExitVariableDeclarationStatement is called when exiting the variableDeclarationStatement production. 477 | ExitVariableDeclarationStatement(c *VariableDeclarationStatementContext) 478 | 479 | // ExitVariableDeclarationList is called when exiting the variableDeclarationList production. 480 | ExitVariableDeclarationList(c *VariableDeclarationListContext) 481 | 482 | // ExitIdentifierList is called when exiting the identifierList production. 483 | ExitIdentifierList(c *IdentifierListContext) 484 | 485 | // ExitElementaryTypeName is called when exiting the elementaryTypeName production. 486 | ExitElementaryTypeName(c *ElementaryTypeNameContext) 487 | 488 | // ExitExpression is called when exiting the expression production. 489 | ExitExpression(c *ExpressionContext) 490 | 491 | // ExitPrimaryExpression is called when exiting the primaryExpression production. 492 | ExitPrimaryExpression(c *PrimaryExpressionContext) 493 | 494 | // ExitExpressionList is called when exiting the expressionList production. 495 | ExitExpressionList(c *ExpressionListContext) 496 | 497 | // ExitNameValueList is called when exiting the nameValueList production. 498 | ExitNameValueList(c *NameValueListContext) 499 | 500 | // ExitNameValue is called when exiting the nameValue production. 501 | ExitNameValue(c *NameValueContext) 502 | 503 | // ExitFunctionCallArguments is called when exiting the functionCallArguments production. 504 | ExitFunctionCallArguments(c *FunctionCallArgumentsContext) 505 | 506 | // ExitFunctionCall is called when exiting the functionCall production. 507 | ExitFunctionCall(c *FunctionCallContext) 508 | 509 | // ExitAssemblyBlock is called when exiting the assemblyBlock production. 510 | ExitAssemblyBlock(c *AssemblyBlockContext) 511 | 512 | // ExitAssemblyItem is called when exiting the assemblyItem production. 513 | ExitAssemblyItem(c *AssemblyItemContext) 514 | 515 | // ExitAssemblyExpression is called when exiting the assemblyExpression production. 516 | ExitAssemblyExpression(c *AssemblyExpressionContext) 517 | 518 | // ExitAssemblyMember is called when exiting the assemblyMember production. 519 | ExitAssemblyMember(c *AssemblyMemberContext) 520 | 521 | // ExitAssemblyCall is called when exiting the assemblyCall production. 522 | ExitAssemblyCall(c *AssemblyCallContext) 523 | 524 | // ExitAssemblyLocalDefinition is called when exiting the assemblyLocalDefinition production. 525 | ExitAssemblyLocalDefinition(c *AssemblyLocalDefinitionContext) 526 | 527 | // ExitAssemblyAssignment is called when exiting the assemblyAssignment production. 528 | ExitAssemblyAssignment(c *AssemblyAssignmentContext) 529 | 530 | // ExitAssemblyIdentifierOrList is called when exiting the assemblyIdentifierOrList production. 531 | ExitAssemblyIdentifierOrList(c *AssemblyIdentifierOrListContext) 532 | 533 | // ExitAssemblyIdentifierList is called when exiting the assemblyIdentifierList production. 534 | ExitAssemblyIdentifierList(c *AssemblyIdentifierListContext) 535 | 536 | // ExitAssemblyStackAssignment is called when exiting the assemblyStackAssignment production. 537 | ExitAssemblyStackAssignment(c *AssemblyStackAssignmentContext) 538 | 539 | // ExitLabelDefinition is called when exiting the labelDefinition production. 540 | ExitLabelDefinition(c *LabelDefinitionContext) 541 | 542 | // ExitAssemblySwitch is called when exiting the assemblySwitch production. 543 | ExitAssemblySwitch(c *AssemblySwitchContext) 544 | 545 | // ExitAssemblyCase is called when exiting the assemblyCase production. 546 | ExitAssemblyCase(c *AssemblyCaseContext) 547 | 548 | // ExitAssemblyFunctionDefinition is called when exiting the assemblyFunctionDefinition production. 549 | ExitAssemblyFunctionDefinition(c *AssemblyFunctionDefinitionContext) 550 | 551 | // ExitAssemblyFunctionReturns is called when exiting the assemblyFunctionReturns production. 552 | ExitAssemblyFunctionReturns(c *AssemblyFunctionReturnsContext) 553 | 554 | // ExitAssemblyFor is called when exiting the assemblyFor production. 555 | ExitAssemblyFor(c *AssemblyForContext) 556 | 557 | // ExitAssemblyIf is called when exiting the assemblyIf production. 558 | ExitAssemblyIf(c *AssemblyIfContext) 559 | 560 | // ExitAssemblyLiteral is called when exiting the assemblyLiteral production. 561 | ExitAssemblyLiteral(c *AssemblyLiteralContext) 562 | 563 | // ExitSubAssembly is called when exiting the subAssembly production. 564 | ExitSubAssembly(c *SubAssemblyContext) 565 | 566 | // ExitTupleExpression is called when exiting the tupleExpression production. 567 | ExitTupleExpression(c *TupleExpressionContext) 568 | 569 | // ExitTypeNameExpression is called when exiting the typeNameExpression production. 570 | ExitTypeNameExpression(c *TypeNameExpressionContext) 571 | 572 | // ExitNumberLiteral is called when exiting the numberLiteral production. 573 | ExitNumberLiteral(c *NumberLiteralContext) 574 | 575 | // ExitIdentifier is called when exiting the identifier production. 576 | ExitIdentifier(c *IdentifierContext) 577 | 578 | // ExitHexLiteral is called when exiting the hexLiteral production. 579 | ExitHexLiteral(c *HexLiteralContext) 580 | 581 | // ExitOverrideSpecifier is called when exiting the overrideSpecifier production. 582 | ExitOverrideSpecifier(c *OverrideSpecifierContext) 583 | 584 | // ExitStringLiteral is called when exiting the stringLiteral production. 585 | ExitStringLiteral(c *StringLiteralContext) 586 | } 587 | -------------------------------------------------------------------------------- /parser/solidity_base_listener.go: -------------------------------------------------------------------------------- 1 | // Code generated from parser/Solidity.g4 by ANTLR 4.9.2. DO NOT EDIT. 2 | 3 | package parser // Solidity 4 | 5 | import "github.com/antlr/antlr4/runtime/Go/antlr" 6 | 7 | // BaseSolidityListener is a complete listener for a parse tree produced by SolidityParser. 8 | type BaseSolidityListener struct{} 9 | 10 | var _ SolidityListener = &BaseSolidityListener{} 11 | 12 | // VisitTerminal is called when a terminal node is visited. 13 | func (s *BaseSolidityListener) VisitTerminal(node antlr.TerminalNode) {} 14 | 15 | // VisitErrorNode is called when an error node is visited. 16 | func (s *BaseSolidityListener) VisitErrorNode(node antlr.ErrorNode) {} 17 | 18 | // EnterEveryRule is called when any rule is entered. 19 | func (s *BaseSolidityListener) EnterEveryRule(ctx antlr.ParserRuleContext) {} 20 | 21 | // ExitEveryRule is called when any rule is exited. 22 | func (s *BaseSolidityListener) ExitEveryRule(ctx antlr.ParserRuleContext) {} 23 | 24 | // EnterSourceUnit is called when production sourceUnit is entered. 25 | func (s *BaseSolidityListener) EnterSourceUnit(ctx *SourceUnitContext) {} 26 | 27 | // ExitSourceUnit is called when production sourceUnit is exited. 28 | func (s *BaseSolidityListener) ExitSourceUnit(ctx *SourceUnitContext) {} 29 | 30 | // EnterPragmaDirective is called when production pragmaDirective is entered. 31 | func (s *BaseSolidityListener) EnterPragmaDirective(ctx *PragmaDirectiveContext) {} 32 | 33 | // ExitPragmaDirective is called when production pragmaDirective is exited. 34 | func (s *BaseSolidityListener) ExitPragmaDirective(ctx *PragmaDirectiveContext) {} 35 | 36 | // EnterPragmaName is called when production pragmaName is entered. 37 | func (s *BaseSolidityListener) EnterPragmaName(ctx *PragmaNameContext) {} 38 | 39 | // ExitPragmaName is called when production pragmaName is exited. 40 | func (s *BaseSolidityListener) ExitPragmaName(ctx *PragmaNameContext) {} 41 | 42 | // EnterPragmaValue is called when production pragmaValue is entered. 43 | func (s *BaseSolidityListener) EnterPragmaValue(ctx *PragmaValueContext) {} 44 | 45 | // ExitPragmaValue is called when production pragmaValue is exited. 46 | func (s *BaseSolidityListener) ExitPragmaValue(ctx *PragmaValueContext) {} 47 | 48 | // EnterVersion is called when production version is entered. 49 | func (s *BaseSolidityListener) EnterVersion(ctx *VersionContext) {} 50 | 51 | // ExitVersion is called when production version is exited. 52 | func (s *BaseSolidityListener) ExitVersion(ctx *VersionContext) {} 53 | 54 | // EnterVersionOperator is called when production versionOperator is entered. 55 | func (s *BaseSolidityListener) EnterVersionOperator(ctx *VersionOperatorContext) {} 56 | 57 | // ExitVersionOperator is called when production versionOperator is exited. 58 | func (s *BaseSolidityListener) ExitVersionOperator(ctx *VersionOperatorContext) {} 59 | 60 | // EnterVersionConstraint is called when production versionConstraint is entered. 61 | func (s *BaseSolidityListener) EnterVersionConstraint(ctx *VersionConstraintContext) {} 62 | 63 | // ExitVersionConstraint is called when production versionConstraint is exited. 64 | func (s *BaseSolidityListener) ExitVersionConstraint(ctx *VersionConstraintContext) {} 65 | 66 | // EnterImportDeclaration is called when production importDeclaration is entered. 67 | func (s *BaseSolidityListener) EnterImportDeclaration(ctx *ImportDeclarationContext) {} 68 | 69 | // ExitImportDeclaration is called when production importDeclaration is exited. 70 | func (s *BaseSolidityListener) ExitImportDeclaration(ctx *ImportDeclarationContext) {} 71 | 72 | // EnterImportDirective is called when production importDirective is entered. 73 | func (s *BaseSolidityListener) EnterImportDirective(ctx *ImportDirectiveContext) {} 74 | 75 | // ExitImportDirective is called when production importDirective is exited. 76 | func (s *BaseSolidityListener) ExitImportDirective(ctx *ImportDirectiveContext) {} 77 | 78 | // EnterImportPath is called when production importPath is entered. 79 | func (s *BaseSolidityListener) EnterImportPath(ctx *ImportPathContext) {} 80 | 81 | // ExitImportPath is called when production importPath is exited. 82 | func (s *BaseSolidityListener) ExitImportPath(ctx *ImportPathContext) {} 83 | 84 | // EnterContractDefinition is called when production contractDefinition is entered. 85 | func (s *BaseSolidityListener) EnterContractDefinition(ctx *ContractDefinitionContext) {} 86 | 87 | // ExitContractDefinition is called when production contractDefinition is exited. 88 | func (s *BaseSolidityListener) ExitContractDefinition(ctx *ContractDefinitionContext) {} 89 | 90 | // EnterInheritanceSpecifier is called when production inheritanceSpecifier is entered. 91 | func (s *BaseSolidityListener) EnterInheritanceSpecifier(ctx *InheritanceSpecifierContext) {} 92 | 93 | // ExitInheritanceSpecifier is called when production inheritanceSpecifier is exited. 94 | func (s *BaseSolidityListener) ExitInheritanceSpecifier(ctx *InheritanceSpecifierContext) {} 95 | 96 | // EnterContractPart is called when production contractPart is entered. 97 | func (s *BaseSolidityListener) EnterContractPart(ctx *ContractPartContext) {} 98 | 99 | // ExitContractPart is called when production contractPart is exited. 100 | func (s *BaseSolidityListener) ExitContractPart(ctx *ContractPartContext) {} 101 | 102 | // EnterStateVariableDeclaration is called when production stateVariableDeclaration is entered. 103 | func (s *BaseSolidityListener) EnterStateVariableDeclaration(ctx *StateVariableDeclarationContext) {} 104 | 105 | // ExitStateVariableDeclaration is called when production stateVariableDeclaration is exited. 106 | func (s *BaseSolidityListener) ExitStateVariableDeclaration(ctx *StateVariableDeclarationContext) {} 107 | 108 | // EnterFileLevelConstant is called when production fileLevelConstant is entered. 109 | func (s *BaseSolidityListener) EnterFileLevelConstant(ctx *FileLevelConstantContext) {} 110 | 111 | // ExitFileLevelConstant is called when production fileLevelConstant is exited. 112 | func (s *BaseSolidityListener) ExitFileLevelConstant(ctx *FileLevelConstantContext) {} 113 | 114 | // EnterCustomErrorDefinition is called when production customErrorDefinition is entered. 115 | func (s *BaseSolidityListener) EnterCustomErrorDefinition(ctx *CustomErrorDefinitionContext) {} 116 | 117 | // ExitCustomErrorDefinition is called when production customErrorDefinition is exited. 118 | func (s *BaseSolidityListener) ExitCustomErrorDefinition(ctx *CustomErrorDefinitionContext) {} 119 | 120 | // EnterUsingForDeclaration is called when production usingForDeclaration is entered. 121 | func (s *BaseSolidityListener) EnterUsingForDeclaration(ctx *UsingForDeclarationContext) {} 122 | 123 | // ExitUsingForDeclaration is called when production usingForDeclaration is exited. 124 | func (s *BaseSolidityListener) ExitUsingForDeclaration(ctx *UsingForDeclarationContext) {} 125 | 126 | // EnterStructDefinition is called when production structDefinition is entered. 127 | func (s *BaseSolidityListener) EnterStructDefinition(ctx *StructDefinitionContext) {} 128 | 129 | // ExitStructDefinition is called when production structDefinition is exited. 130 | func (s *BaseSolidityListener) ExitStructDefinition(ctx *StructDefinitionContext) {} 131 | 132 | // EnterModifierDefinition is called when production modifierDefinition is entered. 133 | func (s *BaseSolidityListener) EnterModifierDefinition(ctx *ModifierDefinitionContext) {} 134 | 135 | // ExitModifierDefinition is called when production modifierDefinition is exited. 136 | func (s *BaseSolidityListener) ExitModifierDefinition(ctx *ModifierDefinitionContext) {} 137 | 138 | // EnterModifierInvocation is called when production modifierInvocation is entered. 139 | func (s *BaseSolidityListener) EnterModifierInvocation(ctx *ModifierInvocationContext) {} 140 | 141 | // ExitModifierInvocation is called when production modifierInvocation is exited. 142 | func (s *BaseSolidityListener) ExitModifierInvocation(ctx *ModifierInvocationContext) {} 143 | 144 | // EnterFunctionDefinition is called when production functionDefinition is entered. 145 | func (s *BaseSolidityListener) EnterFunctionDefinition(ctx *FunctionDefinitionContext) {} 146 | 147 | // ExitFunctionDefinition is called when production functionDefinition is exited. 148 | func (s *BaseSolidityListener) ExitFunctionDefinition(ctx *FunctionDefinitionContext) {} 149 | 150 | // EnterFunctionDescriptor is called when production functionDescriptor is entered. 151 | func (s *BaseSolidityListener) EnterFunctionDescriptor(ctx *FunctionDescriptorContext) {} 152 | 153 | // ExitFunctionDescriptor is called when production functionDescriptor is exited. 154 | func (s *BaseSolidityListener) ExitFunctionDescriptor(ctx *FunctionDescriptorContext) {} 155 | 156 | // EnterReturnParameters is called when production returnParameters is entered. 157 | func (s *BaseSolidityListener) EnterReturnParameters(ctx *ReturnParametersContext) {} 158 | 159 | // ExitReturnParameters is called when production returnParameters is exited. 160 | func (s *BaseSolidityListener) ExitReturnParameters(ctx *ReturnParametersContext) {} 161 | 162 | // EnterModifierList is called when production modifierList is entered. 163 | func (s *BaseSolidityListener) EnterModifierList(ctx *ModifierListContext) {} 164 | 165 | // ExitModifierList is called when production modifierList is exited. 166 | func (s *BaseSolidityListener) ExitModifierList(ctx *ModifierListContext) {} 167 | 168 | // EnterEventDefinition is called when production eventDefinition is entered. 169 | func (s *BaseSolidityListener) EnterEventDefinition(ctx *EventDefinitionContext) {} 170 | 171 | // ExitEventDefinition is called when production eventDefinition is exited. 172 | func (s *BaseSolidityListener) ExitEventDefinition(ctx *EventDefinitionContext) {} 173 | 174 | // EnterEnumValue is called when production enumValue is entered. 175 | func (s *BaseSolidityListener) EnterEnumValue(ctx *EnumValueContext) {} 176 | 177 | // ExitEnumValue is called when production enumValue is exited. 178 | func (s *BaseSolidityListener) ExitEnumValue(ctx *EnumValueContext) {} 179 | 180 | // EnterEnumDefinition is called when production enumDefinition is entered. 181 | func (s *BaseSolidityListener) EnterEnumDefinition(ctx *EnumDefinitionContext) {} 182 | 183 | // ExitEnumDefinition is called when production enumDefinition is exited. 184 | func (s *BaseSolidityListener) ExitEnumDefinition(ctx *EnumDefinitionContext) {} 185 | 186 | // EnterParameterList is called when production parameterList is entered. 187 | func (s *BaseSolidityListener) EnterParameterList(ctx *ParameterListContext) {} 188 | 189 | // ExitParameterList is called when production parameterList is exited. 190 | func (s *BaseSolidityListener) ExitParameterList(ctx *ParameterListContext) {} 191 | 192 | // EnterParameter is called when production parameter is entered. 193 | func (s *BaseSolidityListener) EnterParameter(ctx *ParameterContext) {} 194 | 195 | // ExitParameter is called when production parameter is exited. 196 | func (s *BaseSolidityListener) ExitParameter(ctx *ParameterContext) {} 197 | 198 | // EnterEventParameterList is called when production eventParameterList is entered. 199 | func (s *BaseSolidityListener) EnterEventParameterList(ctx *EventParameterListContext) {} 200 | 201 | // ExitEventParameterList is called when production eventParameterList is exited. 202 | func (s *BaseSolidityListener) ExitEventParameterList(ctx *EventParameterListContext) {} 203 | 204 | // EnterEventParameter is called when production eventParameter is entered. 205 | func (s *BaseSolidityListener) EnterEventParameter(ctx *EventParameterContext) {} 206 | 207 | // ExitEventParameter is called when production eventParameter is exited. 208 | func (s *BaseSolidityListener) ExitEventParameter(ctx *EventParameterContext) {} 209 | 210 | // EnterFunctionTypeParameterList is called when production functionTypeParameterList is entered. 211 | func (s *BaseSolidityListener) EnterFunctionTypeParameterList(ctx *FunctionTypeParameterListContext) { 212 | } 213 | 214 | // ExitFunctionTypeParameterList is called when production functionTypeParameterList is exited. 215 | func (s *BaseSolidityListener) ExitFunctionTypeParameterList(ctx *FunctionTypeParameterListContext) {} 216 | 217 | // EnterFunctionTypeParameter is called when production functionTypeParameter is entered. 218 | func (s *BaseSolidityListener) EnterFunctionTypeParameter(ctx *FunctionTypeParameterContext) {} 219 | 220 | // ExitFunctionTypeParameter is called when production functionTypeParameter is exited. 221 | func (s *BaseSolidityListener) ExitFunctionTypeParameter(ctx *FunctionTypeParameterContext) {} 222 | 223 | // EnterVariableDeclaration is called when production variableDeclaration is entered. 224 | func (s *BaseSolidityListener) EnterVariableDeclaration(ctx *VariableDeclarationContext) {} 225 | 226 | // ExitVariableDeclaration is called when production variableDeclaration is exited. 227 | func (s *BaseSolidityListener) ExitVariableDeclaration(ctx *VariableDeclarationContext) {} 228 | 229 | // EnterTypeName is called when production typeName is entered. 230 | func (s *BaseSolidityListener) EnterTypeName(ctx *TypeNameContext) {} 231 | 232 | // ExitTypeName is called when production typeName is exited. 233 | func (s *BaseSolidityListener) ExitTypeName(ctx *TypeNameContext) {} 234 | 235 | // EnterUserDefinedTypeName is called when production userDefinedTypeName is entered. 236 | func (s *BaseSolidityListener) EnterUserDefinedTypeName(ctx *UserDefinedTypeNameContext) {} 237 | 238 | // ExitUserDefinedTypeName is called when production userDefinedTypeName is exited. 239 | func (s *BaseSolidityListener) ExitUserDefinedTypeName(ctx *UserDefinedTypeNameContext) {} 240 | 241 | // EnterMappingKey is called when production mappingKey is entered. 242 | func (s *BaseSolidityListener) EnterMappingKey(ctx *MappingKeyContext) {} 243 | 244 | // ExitMappingKey is called when production mappingKey is exited. 245 | func (s *BaseSolidityListener) ExitMappingKey(ctx *MappingKeyContext) {} 246 | 247 | // EnterMapping is called when production mapping is entered. 248 | func (s *BaseSolidityListener) EnterMapping(ctx *MappingContext) {} 249 | 250 | // ExitMapping is called when production mapping is exited. 251 | func (s *BaseSolidityListener) ExitMapping(ctx *MappingContext) {} 252 | 253 | // EnterFunctionTypeName is called when production functionTypeName is entered. 254 | func (s *BaseSolidityListener) EnterFunctionTypeName(ctx *FunctionTypeNameContext) {} 255 | 256 | // ExitFunctionTypeName is called when production functionTypeName is exited. 257 | func (s *BaseSolidityListener) ExitFunctionTypeName(ctx *FunctionTypeNameContext) {} 258 | 259 | // EnterStorageLocation is called when production storageLocation is entered. 260 | func (s *BaseSolidityListener) EnterStorageLocation(ctx *StorageLocationContext) {} 261 | 262 | // ExitStorageLocation is called when production storageLocation is exited. 263 | func (s *BaseSolidityListener) ExitStorageLocation(ctx *StorageLocationContext) {} 264 | 265 | // EnterStateMutability is called when production stateMutability is entered. 266 | func (s *BaseSolidityListener) EnterStateMutability(ctx *StateMutabilityContext) {} 267 | 268 | // ExitStateMutability is called when production stateMutability is exited. 269 | func (s *BaseSolidityListener) ExitStateMutability(ctx *StateMutabilityContext) {} 270 | 271 | // EnterBlock is called when production block is entered. 272 | func (s *BaseSolidityListener) EnterBlock(ctx *BlockContext) {} 273 | 274 | // ExitBlock is called when production block is exited. 275 | func (s *BaseSolidityListener) ExitBlock(ctx *BlockContext) {} 276 | 277 | // EnterStatement is called when production statement is entered. 278 | func (s *BaseSolidityListener) EnterStatement(ctx *StatementContext) {} 279 | 280 | // ExitStatement is called when production statement is exited. 281 | func (s *BaseSolidityListener) ExitStatement(ctx *StatementContext) {} 282 | 283 | // EnterExpressionStatement is called when production expressionStatement is entered. 284 | func (s *BaseSolidityListener) EnterExpressionStatement(ctx *ExpressionStatementContext) {} 285 | 286 | // ExitExpressionStatement is called when production expressionStatement is exited. 287 | func (s *BaseSolidityListener) ExitExpressionStatement(ctx *ExpressionStatementContext) {} 288 | 289 | // EnterIfStatement is called when production ifStatement is entered. 290 | func (s *BaseSolidityListener) EnterIfStatement(ctx *IfStatementContext) {} 291 | 292 | // ExitIfStatement is called when production ifStatement is exited. 293 | func (s *BaseSolidityListener) ExitIfStatement(ctx *IfStatementContext) {} 294 | 295 | // EnterTryStatement is called when production tryStatement is entered. 296 | func (s *BaseSolidityListener) EnterTryStatement(ctx *TryStatementContext) {} 297 | 298 | // ExitTryStatement is called when production tryStatement is exited. 299 | func (s *BaseSolidityListener) ExitTryStatement(ctx *TryStatementContext) {} 300 | 301 | // EnterCatchClause is called when production catchClause is entered. 302 | func (s *BaseSolidityListener) EnterCatchClause(ctx *CatchClauseContext) {} 303 | 304 | // ExitCatchClause is called when production catchClause is exited. 305 | func (s *BaseSolidityListener) ExitCatchClause(ctx *CatchClauseContext) {} 306 | 307 | // EnterWhileStatement is called when production whileStatement is entered. 308 | func (s *BaseSolidityListener) EnterWhileStatement(ctx *WhileStatementContext) {} 309 | 310 | // ExitWhileStatement is called when production whileStatement is exited. 311 | func (s *BaseSolidityListener) ExitWhileStatement(ctx *WhileStatementContext) {} 312 | 313 | // EnterSimpleStatement is called when production simpleStatement is entered. 314 | func (s *BaseSolidityListener) EnterSimpleStatement(ctx *SimpleStatementContext) {} 315 | 316 | // ExitSimpleStatement is called when production simpleStatement is exited. 317 | func (s *BaseSolidityListener) ExitSimpleStatement(ctx *SimpleStatementContext) {} 318 | 319 | // EnterUncheckedStatement is called when production uncheckedStatement is entered. 320 | func (s *BaseSolidityListener) EnterUncheckedStatement(ctx *UncheckedStatementContext) {} 321 | 322 | // ExitUncheckedStatement is called when production uncheckedStatement is exited. 323 | func (s *BaseSolidityListener) ExitUncheckedStatement(ctx *UncheckedStatementContext) {} 324 | 325 | // EnterForStatement is called when production forStatement is entered. 326 | func (s *BaseSolidityListener) EnterForStatement(ctx *ForStatementContext) {} 327 | 328 | // ExitForStatement is called when production forStatement is exited. 329 | func (s *BaseSolidityListener) ExitForStatement(ctx *ForStatementContext) {} 330 | 331 | // EnterInlineAssemblyStatement is called when production inlineAssemblyStatement is entered. 332 | func (s *BaseSolidityListener) EnterInlineAssemblyStatement(ctx *InlineAssemblyStatementContext) {} 333 | 334 | // ExitInlineAssemblyStatement is called when production inlineAssemblyStatement is exited. 335 | func (s *BaseSolidityListener) ExitInlineAssemblyStatement(ctx *InlineAssemblyStatementContext) {} 336 | 337 | // EnterDoWhileStatement is called when production doWhileStatement is entered. 338 | func (s *BaseSolidityListener) EnterDoWhileStatement(ctx *DoWhileStatementContext) {} 339 | 340 | // ExitDoWhileStatement is called when production doWhileStatement is exited. 341 | func (s *BaseSolidityListener) ExitDoWhileStatement(ctx *DoWhileStatementContext) {} 342 | 343 | // EnterContinueStatement is called when production continueStatement is entered. 344 | func (s *BaseSolidityListener) EnterContinueStatement(ctx *ContinueStatementContext) {} 345 | 346 | // ExitContinueStatement is called when production continueStatement is exited. 347 | func (s *BaseSolidityListener) ExitContinueStatement(ctx *ContinueStatementContext) {} 348 | 349 | // EnterBreakStatement is called when production breakStatement is entered. 350 | func (s *BaseSolidityListener) EnterBreakStatement(ctx *BreakStatementContext) {} 351 | 352 | // ExitBreakStatement is called when production breakStatement is exited. 353 | func (s *BaseSolidityListener) ExitBreakStatement(ctx *BreakStatementContext) {} 354 | 355 | // EnterReturnStatement is called when production returnStatement is entered. 356 | func (s *BaseSolidityListener) EnterReturnStatement(ctx *ReturnStatementContext) {} 357 | 358 | // ExitReturnStatement is called when production returnStatement is exited. 359 | func (s *BaseSolidityListener) ExitReturnStatement(ctx *ReturnStatementContext) {} 360 | 361 | // EnterThrowStatement is called when production throwStatement is entered. 362 | func (s *BaseSolidityListener) EnterThrowStatement(ctx *ThrowStatementContext) {} 363 | 364 | // ExitThrowStatement is called when production throwStatement is exited. 365 | func (s *BaseSolidityListener) ExitThrowStatement(ctx *ThrowStatementContext) {} 366 | 367 | // EnterEmitStatement is called when production emitStatement is entered. 368 | func (s *BaseSolidityListener) EnterEmitStatement(ctx *EmitStatementContext) {} 369 | 370 | // ExitEmitStatement is called when production emitStatement is exited. 371 | func (s *BaseSolidityListener) ExitEmitStatement(ctx *EmitStatementContext) {} 372 | 373 | // EnterRevertStatement is called when production revertStatement is entered. 374 | func (s *BaseSolidityListener) EnterRevertStatement(ctx *RevertStatementContext) {} 375 | 376 | // ExitRevertStatement is called when production revertStatement is exited. 377 | func (s *BaseSolidityListener) ExitRevertStatement(ctx *RevertStatementContext) {} 378 | 379 | // EnterVariableDeclarationStatement is called when production variableDeclarationStatement is entered. 380 | func (s *BaseSolidityListener) EnterVariableDeclarationStatement(ctx *VariableDeclarationStatementContext) { 381 | } 382 | 383 | // ExitVariableDeclarationStatement is called when production variableDeclarationStatement is exited. 384 | func (s *BaseSolidityListener) ExitVariableDeclarationStatement(ctx *VariableDeclarationStatementContext) { 385 | } 386 | 387 | // EnterVariableDeclarationList is called when production variableDeclarationList is entered. 388 | func (s *BaseSolidityListener) EnterVariableDeclarationList(ctx *VariableDeclarationListContext) {} 389 | 390 | // ExitVariableDeclarationList is called when production variableDeclarationList is exited. 391 | func (s *BaseSolidityListener) ExitVariableDeclarationList(ctx *VariableDeclarationListContext) {} 392 | 393 | // EnterIdentifierList is called when production identifierList is entered. 394 | func (s *BaseSolidityListener) EnterIdentifierList(ctx *IdentifierListContext) {} 395 | 396 | // ExitIdentifierList is called when production identifierList is exited. 397 | func (s *BaseSolidityListener) ExitIdentifierList(ctx *IdentifierListContext) {} 398 | 399 | // EnterElementaryTypeName is called when production elementaryTypeName is entered. 400 | func (s *BaseSolidityListener) EnterElementaryTypeName(ctx *ElementaryTypeNameContext) {} 401 | 402 | // ExitElementaryTypeName is called when production elementaryTypeName is exited. 403 | func (s *BaseSolidityListener) ExitElementaryTypeName(ctx *ElementaryTypeNameContext) {} 404 | 405 | // EnterExpression is called when production expression is entered. 406 | func (s *BaseSolidityListener) EnterExpression(ctx *ExpressionContext) {} 407 | 408 | // ExitExpression is called when production expression is exited. 409 | func (s *BaseSolidityListener) ExitExpression(ctx *ExpressionContext) {} 410 | 411 | // EnterPrimaryExpression is called when production primaryExpression is entered. 412 | func (s *BaseSolidityListener) EnterPrimaryExpression(ctx *PrimaryExpressionContext) {} 413 | 414 | // ExitPrimaryExpression is called when production primaryExpression is exited. 415 | func (s *BaseSolidityListener) ExitPrimaryExpression(ctx *PrimaryExpressionContext) {} 416 | 417 | // EnterExpressionList is called when production expressionList is entered. 418 | func (s *BaseSolidityListener) EnterExpressionList(ctx *ExpressionListContext) {} 419 | 420 | // ExitExpressionList is called when production expressionList is exited. 421 | func (s *BaseSolidityListener) ExitExpressionList(ctx *ExpressionListContext) {} 422 | 423 | // EnterNameValueList is called when production nameValueList is entered. 424 | func (s *BaseSolidityListener) EnterNameValueList(ctx *NameValueListContext) {} 425 | 426 | // ExitNameValueList is called when production nameValueList is exited. 427 | func (s *BaseSolidityListener) ExitNameValueList(ctx *NameValueListContext) {} 428 | 429 | // EnterNameValue is called when production nameValue is entered. 430 | func (s *BaseSolidityListener) EnterNameValue(ctx *NameValueContext) {} 431 | 432 | // ExitNameValue is called when production nameValue is exited. 433 | func (s *BaseSolidityListener) ExitNameValue(ctx *NameValueContext) {} 434 | 435 | // EnterFunctionCallArguments is called when production functionCallArguments is entered. 436 | func (s *BaseSolidityListener) EnterFunctionCallArguments(ctx *FunctionCallArgumentsContext) {} 437 | 438 | // ExitFunctionCallArguments is called when production functionCallArguments is exited. 439 | func (s *BaseSolidityListener) ExitFunctionCallArguments(ctx *FunctionCallArgumentsContext) {} 440 | 441 | // EnterFunctionCall is called when production functionCall is entered. 442 | func (s *BaseSolidityListener) EnterFunctionCall(ctx *FunctionCallContext) {} 443 | 444 | // ExitFunctionCall is called when production functionCall is exited. 445 | func (s *BaseSolidityListener) ExitFunctionCall(ctx *FunctionCallContext) {} 446 | 447 | // EnterAssemblyBlock is called when production assemblyBlock is entered. 448 | func (s *BaseSolidityListener) EnterAssemblyBlock(ctx *AssemblyBlockContext) {} 449 | 450 | // ExitAssemblyBlock is called when production assemblyBlock is exited. 451 | func (s *BaseSolidityListener) ExitAssemblyBlock(ctx *AssemblyBlockContext) {} 452 | 453 | // EnterAssemblyItem is called when production assemblyItem is entered. 454 | func (s *BaseSolidityListener) EnterAssemblyItem(ctx *AssemblyItemContext) {} 455 | 456 | // ExitAssemblyItem is called when production assemblyItem is exited. 457 | func (s *BaseSolidityListener) ExitAssemblyItem(ctx *AssemblyItemContext) {} 458 | 459 | // EnterAssemblyExpression is called when production assemblyExpression is entered. 460 | func (s *BaseSolidityListener) EnterAssemblyExpression(ctx *AssemblyExpressionContext) {} 461 | 462 | // ExitAssemblyExpression is called when production assemblyExpression is exited. 463 | func (s *BaseSolidityListener) ExitAssemblyExpression(ctx *AssemblyExpressionContext) {} 464 | 465 | // EnterAssemblyMember is called when production assemblyMember is entered. 466 | func (s *BaseSolidityListener) EnterAssemblyMember(ctx *AssemblyMemberContext) {} 467 | 468 | // ExitAssemblyMember is called when production assemblyMember is exited. 469 | func (s *BaseSolidityListener) ExitAssemblyMember(ctx *AssemblyMemberContext) {} 470 | 471 | // EnterAssemblyCall is called when production assemblyCall is entered. 472 | func (s *BaseSolidityListener) EnterAssemblyCall(ctx *AssemblyCallContext) {} 473 | 474 | // ExitAssemblyCall is called when production assemblyCall is exited. 475 | func (s *BaseSolidityListener) ExitAssemblyCall(ctx *AssemblyCallContext) {} 476 | 477 | // EnterAssemblyLocalDefinition is called when production assemblyLocalDefinition is entered. 478 | func (s *BaseSolidityListener) EnterAssemblyLocalDefinition(ctx *AssemblyLocalDefinitionContext) {} 479 | 480 | // ExitAssemblyLocalDefinition is called when production assemblyLocalDefinition is exited. 481 | func (s *BaseSolidityListener) ExitAssemblyLocalDefinition(ctx *AssemblyLocalDefinitionContext) {} 482 | 483 | // EnterAssemblyAssignment is called when production assemblyAssignment is entered. 484 | func (s *BaseSolidityListener) EnterAssemblyAssignment(ctx *AssemblyAssignmentContext) {} 485 | 486 | // ExitAssemblyAssignment is called when production assemblyAssignment is exited. 487 | func (s *BaseSolidityListener) ExitAssemblyAssignment(ctx *AssemblyAssignmentContext) {} 488 | 489 | // EnterAssemblyIdentifierOrList is called when production assemblyIdentifierOrList is entered. 490 | func (s *BaseSolidityListener) EnterAssemblyIdentifierOrList(ctx *AssemblyIdentifierOrListContext) {} 491 | 492 | // ExitAssemblyIdentifierOrList is called when production assemblyIdentifierOrList is exited. 493 | func (s *BaseSolidityListener) ExitAssemblyIdentifierOrList(ctx *AssemblyIdentifierOrListContext) {} 494 | 495 | // EnterAssemblyIdentifierList is called when production assemblyIdentifierList is entered. 496 | func (s *BaseSolidityListener) EnterAssemblyIdentifierList(ctx *AssemblyIdentifierListContext) {} 497 | 498 | // ExitAssemblyIdentifierList is called when production assemblyIdentifierList is exited. 499 | func (s *BaseSolidityListener) ExitAssemblyIdentifierList(ctx *AssemblyIdentifierListContext) {} 500 | 501 | // EnterAssemblyStackAssignment is called when production assemblyStackAssignment is entered. 502 | func (s *BaseSolidityListener) EnterAssemblyStackAssignment(ctx *AssemblyStackAssignmentContext) {} 503 | 504 | // ExitAssemblyStackAssignment is called when production assemblyStackAssignment is exited. 505 | func (s *BaseSolidityListener) ExitAssemblyStackAssignment(ctx *AssemblyStackAssignmentContext) {} 506 | 507 | // EnterLabelDefinition is called when production labelDefinition is entered. 508 | func (s *BaseSolidityListener) EnterLabelDefinition(ctx *LabelDefinitionContext) {} 509 | 510 | // ExitLabelDefinition is called when production labelDefinition is exited. 511 | func (s *BaseSolidityListener) ExitLabelDefinition(ctx *LabelDefinitionContext) {} 512 | 513 | // EnterAssemblySwitch is called when production assemblySwitch is entered. 514 | func (s *BaseSolidityListener) EnterAssemblySwitch(ctx *AssemblySwitchContext) {} 515 | 516 | // ExitAssemblySwitch is called when production assemblySwitch is exited. 517 | func (s *BaseSolidityListener) ExitAssemblySwitch(ctx *AssemblySwitchContext) {} 518 | 519 | // EnterAssemblyCase is called when production assemblyCase is entered. 520 | func (s *BaseSolidityListener) EnterAssemblyCase(ctx *AssemblyCaseContext) {} 521 | 522 | // ExitAssemblyCase is called when production assemblyCase is exited. 523 | func (s *BaseSolidityListener) ExitAssemblyCase(ctx *AssemblyCaseContext) {} 524 | 525 | // EnterAssemblyFunctionDefinition is called when production assemblyFunctionDefinition is entered. 526 | func (s *BaseSolidityListener) EnterAssemblyFunctionDefinition(ctx *AssemblyFunctionDefinitionContext) { 527 | } 528 | 529 | // ExitAssemblyFunctionDefinition is called when production assemblyFunctionDefinition is exited. 530 | func (s *BaseSolidityListener) ExitAssemblyFunctionDefinition(ctx *AssemblyFunctionDefinitionContext) { 531 | } 532 | 533 | // EnterAssemblyFunctionReturns is called when production assemblyFunctionReturns is entered. 534 | func (s *BaseSolidityListener) EnterAssemblyFunctionReturns(ctx *AssemblyFunctionReturnsContext) {} 535 | 536 | // ExitAssemblyFunctionReturns is called when production assemblyFunctionReturns is exited. 537 | func (s *BaseSolidityListener) ExitAssemblyFunctionReturns(ctx *AssemblyFunctionReturnsContext) {} 538 | 539 | // EnterAssemblyFor is called when production assemblyFor is entered. 540 | func (s *BaseSolidityListener) EnterAssemblyFor(ctx *AssemblyForContext) {} 541 | 542 | // ExitAssemblyFor is called when production assemblyFor is exited. 543 | func (s *BaseSolidityListener) ExitAssemblyFor(ctx *AssemblyForContext) {} 544 | 545 | // EnterAssemblyIf is called when production assemblyIf is entered. 546 | func (s *BaseSolidityListener) EnterAssemblyIf(ctx *AssemblyIfContext) {} 547 | 548 | // ExitAssemblyIf is called when production assemblyIf is exited. 549 | func (s *BaseSolidityListener) ExitAssemblyIf(ctx *AssemblyIfContext) {} 550 | 551 | // EnterAssemblyLiteral is called when production assemblyLiteral is entered. 552 | func (s *BaseSolidityListener) EnterAssemblyLiteral(ctx *AssemblyLiteralContext) {} 553 | 554 | // ExitAssemblyLiteral is called when production assemblyLiteral is exited. 555 | func (s *BaseSolidityListener) ExitAssemblyLiteral(ctx *AssemblyLiteralContext) {} 556 | 557 | // EnterSubAssembly is called when production subAssembly is entered. 558 | func (s *BaseSolidityListener) EnterSubAssembly(ctx *SubAssemblyContext) {} 559 | 560 | // ExitSubAssembly is called when production subAssembly is exited. 561 | func (s *BaseSolidityListener) ExitSubAssembly(ctx *SubAssemblyContext) {} 562 | 563 | // EnterTupleExpression is called when production tupleExpression is entered. 564 | func (s *BaseSolidityListener) EnterTupleExpression(ctx *TupleExpressionContext) {} 565 | 566 | // ExitTupleExpression is called when production tupleExpression is exited. 567 | func (s *BaseSolidityListener) ExitTupleExpression(ctx *TupleExpressionContext) {} 568 | 569 | // EnterTypeNameExpression is called when production typeNameExpression is entered. 570 | func (s *BaseSolidityListener) EnterTypeNameExpression(ctx *TypeNameExpressionContext) {} 571 | 572 | // ExitTypeNameExpression is called when production typeNameExpression is exited. 573 | func (s *BaseSolidityListener) ExitTypeNameExpression(ctx *TypeNameExpressionContext) {} 574 | 575 | // EnterNumberLiteral is called when production numberLiteral is entered. 576 | func (s *BaseSolidityListener) EnterNumberLiteral(ctx *NumberLiteralContext) {} 577 | 578 | // ExitNumberLiteral is called when production numberLiteral is exited. 579 | func (s *BaseSolidityListener) ExitNumberLiteral(ctx *NumberLiteralContext) {} 580 | 581 | // EnterIdentifier is called when production identifier is entered. 582 | func (s *BaseSolidityListener) EnterIdentifier(ctx *IdentifierContext) {} 583 | 584 | // ExitIdentifier is called when production identifier is exited. 585 | func (s *BaseSolidityListener) ExitIdentifier(ctx *IdentifierContext) {} 586 | 587 | // EnterHexLiteral is called when production hexLiteral is entered. 588 | func (s *BaseSolidityListener) EnterHexLiteral(ctx *HexLiteralContext) {} 589 | 590 | // ExitHexLiteral is called when production hexLiteral is exited. 591 | func (s *BaseSolidityListener) ExitHexLiteral(ctx *HexLiteralContext) {} 592 | 593 | // EnterOverrideSpecifier is called when production overrideSpecifier is entered. 594 | func (s *BaseSolidityListener) EnterOverrideSpecifier(ctx *OverrideSpecifierContext) {} 595 | 596 | // ExitOverrideSpecifier is called when production overrideSpecifier is exited. 597 | func (s *BaseSolidityListener) ExitOverrideSpecifier(ctx *OverrideSpecifierContext) {} 598 | 599 | // EnterStringLiteral is called when production stringLiteral is entered. 600 | func (s *BaseSolidityListener) EnterStringLiteral(ctx *StringLiteralContext) {} 601 | 602 | // ExitStringLiteral is called when production stringLiteral is exited. 603 | func (s *BaseSolidityListener) ExitStringLiteral(ctx *StringLiteralContext) {} 604 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | github.com/DataDog/zstd v1.5.2 h1:vUG4lAyuPCXO0TLbXvPv7EB7cNK1QV/luu55UHLrrn8= 2 | github.com/DataDog/zstd v1.5.2/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw= 3 | github.com/Masterminds/semver/v3 v3.1.1 h1:hLg3sBzpNErnxhQtUy/mmLR2I9foDujNK030IGemrRc= 4 | github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= 5 | github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= 6 | github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= 7 | github.com/StackExchange/wmi v1.2.1 h1:VIkavFPXSjcnS+O8yTq7NI32k0R5Aj+v39y29VYDOSA= 8 | github.com/StackExchange/wmi v1.2.1/go.mod h1:rcmrprowKIVzvc+NUiLncP2uuArMWLCbu9SBzvHz7e8= 9 | github.com/VictoriaMetrics/fastcache v1.12.2 h1:N0y9ASrJ0F6h0QaC3o6uJb3NIZ9VKLjCM7NQbSmF7WI= 10 | github.com/VictoriaMetrics/fastcache v1.12.2/go.mod h1:AmC+Nzz1+3G2eCPapF6UcsnkThDcMsQicp4xDukwJYI= 11 | github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156 h1:eMwmnE/GDgah4HI848JfFxHt+iPb26b4zyfspmqY0/8= 12 | github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= 13 | github.com/antlr/antlr4/runtime/Go/antlr v0.0.0-20210826220005-b48c857c3a0e h1:GCzyKMDDjSGnlpl3clrdAK7I1AaVoaiKDOYkUzChZzg= 14 | github.com/antlr/antlr4/runtime/Go/antlr v0.0.0-20210826220005-b48c857c3a0e/go.mod h1:F7bn7fEU90QkQ3tnmaTx3LTKLEDqnwWODIYppRQ5hnY= 15 | github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= 16 | github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= 17 | github.com/bits-and-blooms/bitset v1.20.0 h1:2F+rfL86jE2d/bmw7OhqUg2Sj/1rURkBn3MdfoPyRVU= 18 | github.com/bits-and-blooms/bitset v1.20.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= 19 | github.com/cespare/cp v0.1.0 h1:SE+dxFebS7Iik5LK0tsi1k9ZCxEaFX4AjQmoyA+1dJk= 20 | github.com/cespare/cp v0.1.0/go.mod h1:SOGHArjBr4JWaSDEVpWpo/hNg6RoKrls6Oh40hiwW+s= 21 | github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= 22 | github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= 23 | github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= 24 | github.com/cockroachdb/datadriven v1.0.3-0.20230413201302-be42291fc80f h1:otljaYPt5hWxV3MUfO5dFPFiOXg9CyG5/kCfayTqsJ4= 25 | github.com/cockroachdb/datadriven v1.0.3-0.20230413201302-be42291fc80f/go.mod h1:a9RdTaap04u637JoCzcUoIcDmvwSUtcUFtT/C3kJlTU= 26 | github.com/cockroachdb/errors v1.11.3 h1:5bA+k2Y6r+oz/6Z/RFlNeVCesGARKuC6YymtcDrbC/I= 27 | github.com/cockroachdb/errors v1.11.3/go.mod h1:m4UIW4CDjx+R5cybPsNrRbreomiFqt8o1h1wUVazSd8= 28 | github.com/cockroachdb/fifo v0.0.0-20240606204812-0bbfbd93a7ce h1:giXvy4KSc/6g/esnpM7Geqxka4WSqI1SZc7sMJFd3y4= 29 | github.com/cockroachdb/fifo v0.0.0-20240606204812-0bbfbd93a7ce/go.mod h1:9/y3cnZ5GKakj/H4y9r9GTjCvAFta7KLgSHPJJYc52M= 30 | github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b h1:r6VH0faHjZeQy818SGhaone5OnYfxFR/+AzdY3sf5aE= 31 | github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b/go.mod h1:Vz9DsVWQQhf3vs21MhPMZpMGSht7O/2vFW2xusFUVOs= 32 | github.com/cockroachdb/pebble v1.1.5 h1:5AAWCBWbat0uE0blr8qzufZP5tBjkRyy/jWe1QWLnvw= 33 | github.com/cockroachdb/pebble v1.1.5/go.mod h1:17wO9el1YEigxkP/YtV8NtCivQDgoCyBg5c4VR/eOWo= 34 | github.com/cockroachdb/redact v1.1.5 h1:u1PMllDkdFfPWaNGMyLD1+so+aq3uUItthCFqzwPJ30= 35 | github.com/cockroachdb/redact v1.1.5/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg= 36 | github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 h1:zuQyyAKVxetITBuuhv3BI9cMrmStnpT18zmgmTxunpo= 37 | github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06/go.mod h1:7nc4anLGjupUW/PeY5qiNYsdNXj7zopG+eqsS7To5IQ= 38 | github.com/consensys/gnark-crypto v0.18.0 h1:vIye/FqI50VeAr0B3dx+YjeIvmc3LWz4yEfbWBpTUf0= 39 | github.com/consensys/gnark-crypto v0.18.0/go.mod h1:L3mXGFTe1ZN+RSJ+CLjUt9x7PNdx8ubaYfDROyp2Z8c= 40 | github.com/cpuguy83/go-md2man/v2 v2.0.5 h1:ZtcqGrnekaHpVLArFSe4HK5DoKx1T0rq2DwVB0alcyc= 41 | github.com/cpuguy83/go-md2man/v2 v2.0.5/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= 42 | github.com/crate-crypto/go-eth-kzg v1.3.0 h1:05GrhASN9kDAidaFJOda6A4BEvgvuXbazXg/0E3OOdI= 43 | github.com/crate-crypto/go-eth-kzg v1.3.0/go.mod h1:J9/u5sWfznSObptgfa92Jq8rTswn6ahQWEuiLHOjCUI= 44 | github.com/crate-crypto/go-ipa v0.0.0-20240724233137-53bbb0ceb27a h1:W8mUrRp6NOVl3J+MYp5kPMoUZPp7aOYHtaua31lwRHg= 45 | github.com/crate-crypto/go-ipa v0.0.0-20240724233137-53bbb0ceb27a/go.mod h1:sTwzHBvIzm2RfVCGNEBZgRyjwK40bVoun3ZnGOCafNM= 46 | github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= 47 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 48 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 49 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 50 | github.com/deckarep/golang-set/v2 v2.6.0 h1:XfcQbWM1LlMB8BsJ8N9vW5ehnnPVIw0je80NsVHagjM= 51 | github.com/deckarep/golang-set/v2 v2.6.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4= 52 | github.com/decred/dcrd/crypto/blake256 v1.0.0 h1:/8DMNYp9SGi5f0w7uCm6d6M4OU2rGFK09Y2A4Xv7EE0= 53 | github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc= 54 | github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 h1:YLtO71vCjJRCBcrPMtQ9nqBsqpA1m5sE92cU+pd5Mcc= 55 | github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1/go.mod h1:hyedUtir6IdtD/7lIxGeCxkaw7y45JueMRL4DIyJDKs= 56 | github.com/deepmap/oapi-codegen v1.6.0 h1:w/d1ntwh91XI0b/8ja7+u5SvA4IFfM0UNNLmiDR1gg0= 57 | github.com/deepmap/oapi-codegen v1.6.0/go.mod h1:ryDa9AgbELGeB+YEXE1dR53yAjHwFvE9iAUlWl9Al3M= 58 | github.com/ethereum/c-kzg-4844/v2 v2.1.0 h1:gQropX9YFBhl3g4HYhwE70zq3IHFRgbbNPw0Shwzf5w= 59 | github.com/ethereum/c-kzg-4844/v2 v2.1.0/go.mod h1:TC48kOKjJKPbN7C++qIgt0TJzZ70QznYR7Ob+WXl57E= 60 | github.com/ethereum/go-ethereum v1.16.0 h1:Acf8FlRmcSWEJm3lGjlnKTdNgFvF9/l28oQ8Q6HDj1o= 61 | github.com/ethereum/go-ethereum v1.16.0/go.mod h1:ngYIvmMAYdo4sGW9cGzLvSsPGhDOOzL0jK5S5iXpj0g= 62 | github.com/ethereum/go-verkle v0.2.2 h1:I2W0WjnrFUIzzVPwm8ykY+7pL2d4VhlsePn4j7cnFk8= 63 | github.com/ethereum/go-verkle v0.2.2/go.mod h1:M3b90YRnzqKyyzBEWJGqj8Qff4IDeXnzFw0P9bFw3uk= 64 | github.com/ferranbt/fastssz v0.1.2 h1:Dky6dXlngF6Qjc+EfDipAkE83N5I5DE68bY6O0VLNPk= 65 | github.com/ferranbt/fastssz v0.1.2/go.mod h1:X5UPrE2u1UJjxHA8X54u04SBwdAQjG2sFtWs39YxyWs= 66 | github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= 67 | github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= 68 | github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= 69 | github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= 70 | github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff h1:tY80oXqGNY4FhTFhk+o9oFHGINQ/+vhlm8HFzi6znCI= 71 | github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff/go.mod h1:x7DCsMOv1taUwEWCzT4cmDeAkigA5/QCwUodaVOe8Ww= 72 | github.com/getsentry/sentry-go v0.27.0 h1:Pv98CIbtB3LkMWmXi4Joa5OOcwbmnX88sF5qbK3r3Ps= 73 | github.com/getsentry/sentry-go v0.27.0/go.mod h1:lc76E2QywIyW8WuBnwl8Lc4bkmQH4+w1gwTf25trprY= 74 | github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA= 75 | github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og= 76 | github.com/go-ole/go-ole v1.2.5/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= 77 | github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE= 78 | github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78= 79 | github.com/gofrs/flock v0.12.1 h1:MTLVXXHf8ekldpJk3AKicLij9MdwOWkZ+a/jHHZby9E= 80 | github.com/gofrs/flock v0.12.1/go.mod h1:9zxTsyu5xtJ9DK+1tFZyibEV7y3uwDxPPfbxeeHCoD0= 81 | github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= 82 | github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= 83 | github.com/golang-jwt/jwt/v4 v4.5.1 h1:JdqV9zKUdtaa9gdPlywC3aeoEsR681PlKC+4F5gQgeo= 84 | github.com/golang-jwt/jwt/v4 v4.5.1/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= 85 | github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= 86 | github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= 87 | github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= 88 | github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= 89 | github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= 90 | github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= 91 | github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= 92 | github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= 93 | github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= 94 | github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= 95 | github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= 96 | github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb h1:PBC98N2aIaM3XXiurYmW7fx4GZkL8feAMVq7nEjURHk= 97 | github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= 98 | github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= 99 | github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= 100 | github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 101 | github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= 102 | github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= 103 | github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= 104 | github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= 105 | github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= 106 | github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= 107 | github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc= 108 | github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= 109 | github.com/graph-gophers/graphql-go v1.3.0 h1:Eb9x/q6MFpCLz7jBCiP/WTxjSDrYLR1QY41SORZyNJ0= 110 | github.com/graph-gophers/graphql-go v1.3.0/go.mod h1:9CQHMSxwO4MprSdzoIEobiHpoLtHm77vfxsvsIN5Vuc= 111 | github.com/hashicorp/go-bexpr v0.1.10 h1:9kuI5PFotCboP3dkDYFr/wi0gg0QVbSNz5oFRpxn4uE= 112 | github.com/hashicorp/go-bexpr v0.1.10/go.mod h1:oxlubA2vC/gFVfX1A6JGp7ls7uCDlfJn732ehYYg+g0= 113 | github.com/holiman/billy v0.0.0-20240216141850-2abb0c79d3c4 h1:X4egAf/gcS1zATw6wn4Ej8vjuVGxeHdan+bRb2ebyv4= 114 | github.com/holiman/billy v0.0.0-20240216141850-2abb0c79d3c4/go.mod h1:5GuXa7vkL8u9FkFuWdVvfR5ix8hRB7DbOAaYULamFpc= 115 | github.com/holiman/bloomfilter/v2 v2.0.3 h1:73e0e/V0tCydx14a0SCYS/EWCxgwLZ18CZcZKVu0fao= 116 | github.com/holiman/bloomfilter/v2 v2.0.3/go.mod h1:zpoh+gs7qcpqrHr3dB55AMiJwo0iURXE7ZOP9L9hSkA= 117 | github.com/holiman/uint256 v1.3.2 h1:a9EgMPSC1AAaj1SZL5zIQD3WbwTuHrMGOerLjGmM/TA= 118 | github.com/holiman/uint256 v1.3.2/go.mod h1:EOMSn4q6Nyt9P6efbI3bueV4e1b3dGlUCXeiRV4ng7E= 119 | github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= 120 | github.com/huin/goupnp v1.3.0 h1:UvLUlWDNpoUdYzb2TCn+MuTWtcjXKSza2n6CBdQ0xXc= 121 | github.com/huin/goupnp v1.3.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8= 122 | github.com/influxdata/influxdb-client-go/v2 v2.4.0 h1:HGBfZYStlx3Kqvsv1h2pJixbCl/jhnFtxpKFAv9Tu5k= 123 | github.com/influxdata/influxdb-client-go/v2 v2.4.0/go.mod h1:vLNHdxTJkIf2mSLvGrpj8TCcISApPoXkaxP8g9uRlW8= 124 | github.com/influxdata/influxdb1-client v0.0.0-20220302092344-a9ab5670611c h1:qSHzRbhzK8RdXOsAdfDgO49TtqC1oZ+acxPrkfTxcCs= 125 | github.com/influxdata/influxdb1-client v0.0.0-20220302092344-a9ab5670611c/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= 126 | github.com/influxdata/line-protocol v0.0.0-20200327222509-2487e7298839 h1:W9WBk7wlPfJLvMCdtV4zPulc4uCPrlywQOmbFOhgQNU= 127 | github.com/influxdata/line-protocol v0.0.0-20200327222509-2487e7298839/go.mod h1:xaLFMmpvUxqXtVkUJfg9QmT88cDaCJ3ZKgdZ78oO8Qo= 128 | github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7BdWus= 129 | github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= 130 | github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= 131 | github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= 132 | github.com/klauspost/compress v1.16.0 h1:iULayQNOReoYUe+1qtKOqw9CwJv3aNQu8ivo7lw1HU4= 133 | github.com/klauspost/compress v1.16.0/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= 134 | github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= 135 | github.com/klauspost/cpuid/v2 v2.0.9 h1:lgaqFMSdTdQYdZ04uHyN2d/eKdOMyi2YLSvlQIBFYa4= 136 | github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= 137 | github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= 138 | github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= 139 | github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= 140 | github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= 141 | github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= 142 | github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= 143 | github.com/leanovate/gopter v0.2.11 h1:vRjThO1EKPb/1NsDXuDrzldR28RLkBflWYcU9CvzWu4= 144 | github.com/leanovate/gopter v0.2.11/go.mod h1:aK3tzZP/C+p1m3SPRE4SYZFGP7jjkuSI4f7Xvpt0S9c= 145 | github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= 146 | github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= 147 | github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= 148 | github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= 149 | github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= 150 | github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= 151 | github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU= 152 | github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= 153 | github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= 154 | github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= 155 | github.com/minio/sha256-simd v1.0.0 h1:v1ta+49hkWZyvaKwrQB8elexRqm6Y0aMLjCNsrYxo6g= 156 | github.com/minio/sha256-simd v1.0.0/go.mod h1:OuYzVNI5vcoYIAmbIvHPl3N3jUzVedXbKy5RFepssQM= 157 | github.com/mitchellh/mapstructure v1.4.1 h1:CpVNEelQCZBooIPDn+AR3NpivK/TIKU8bDxdASFVQag= 158 | github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= 159 | github.com/mitchellh/pointerstructure v1.2.0 h1:O+i9nHnXS3l/9Wu7r4NrEdwA2VFTicjUEN1uBnDo34A= 160 | github.com/mitchellh/pointerstructure v1.2.0/go.mod h1:BRAsLI5zgXmw97Lf6s25bs8ohIXc3tViBH44KcwB2g4= 161 | github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78= 162 | github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= 163 | github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= 164 | github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= 165 | github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= 166 | github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= 167 | github.com/onsi/ginkgo v1.14.0 h1:2mOpI4JVVPBN+WQRa0WKH2eXR+Ey+uK4n7Zj0aYpIQA= 168 | github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= 169 | github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= 170 | github.com/onsi/gomega v1.10.1 h1:o0+MgICZLuZ7xjH7Vx6zS/zcu93/BEp1VwkIW1mEXCE= 171 | github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= 172 | github.com/opentracing/opentracing-go v1.1.0 h1:pWlfV3Bxv7k65HYwkikxat0+s3pV4bsqf19k25Ur8rU= 173 | github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= 174 | github.com/peterh/liner v1.1.1-0.20190123174540-a2c9a5303de7 h1:oYW+YCJ1pachXTQmzR3rNLYGGz4g/UgFcjb28p/viDM= 175 | github.com/peterh/liner v1.1.1-0.20190123174540-a2c9a5303de7/go.mod h1:CRroGNssyjTd/qIG2FyxByd2S8JEAZXBl4qUrZf8GS0= 176 | github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4= 177 | github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8= 178 | github.com/pion/dtls/v2 v2.2.7 h1:cSUBsETxepsCSFSxC3mc/aDo14qQLMSL+O6IjG28yV8= 179 | github.com/pion/dtls/v2 v2.2.7/go.mod h1:8WiMkebSHFD0T+dIU+UeBaoV7kDhOW5oDCzZ7WZ/F9s= 180 | github.com/pion/logging v0.2.2 h1:M9+AIj/+pxNsDfAT64+MAVgJO0rsyLnoJKCqf//DoeY= 181 | github.com/pion/logging v0.2.2/go.mod h1:k0/tDVsRCX2Mb2ZEmTqNa7CWsQPc+YYCB7Q+5pahoms= 182 | github.com/pion/stun/v2 v2.0.0 h1:A5+wXKLAypxQri59+tmQKVs7+l6mMM+3d+eER9ifRU0= 183 | github.com/pion/stun/v2 v2.0.0/go.mod h1:22qRSh08fSEttYUmJZGlriq9+03jtVmXNODgLccj8GQ= 184 | github.com/pion/transport/v2 v2.2.1 h1:7qYnCBlpgSJNYMbLCKuSY9KbQdBFoETvPNETv0y4N7c= 185 | github.com/pion/transport/v2 v2.2.1/go.mod h1:cXXWavvCnFF6McHTft3DWS9iic2Mftcz1Aq29pGcU5g= 186 | github.com/pion/transport/v3 v3.0.1 h1:gDTlPJwROfSfz6QfSi0ZmeCSkFcnWWiiR9ES0ouANiM= 187 | github.com/pion/transport/v3 v3.0.1/go.mod h1:UY7kiITrlMv7/IKgd5eTUcaahZx5oUN3l9SzK5f5xE0= 188 | github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= 189 | github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= 190 | github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 191 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 192 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 193 | github.com/prometheus/client_golang v1.15.0 h1:5fCgGYogn0hFdhyhLbw7hEsWxufKtY9klyvdNfFlFhM= 194 | github.com/prometheus/client_golang v1.15.0/go.mod h1:e9yaBhRPU2pPNsZwE+JdQl0KEt1N9XgF6zxWmaC0xOk= 195 | github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4= 196 | github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w= 197 | github.com/prometheus/common v0.42.0 h1:EKsfXEYo4JpWMHH5cg+KOUWeuJSov1Id8zGR8eeI1YM= 198 | github.com/prometheus/common v0.42.0/go.mod h1:xBwqVerjNdUDjgODMpudtOMwlOwf2SaTr1yjz4b7Zbc= 199 | github.com/prometheus/procfs v0.9.0 h1:wzCHvIvM5SxWqYvwgVL7yJY8Lz3PKn49KQtpgMYJfhI= 200 | github.com/prometheus/procfs v0.9.0/go.mod h1:+pB4zwohETzFnmlpe6yd2lSc+0/46IYZRB/chUwxUZY= 201 | github.com/prysmaticlabs/gohashtree v0.0.1-alpha.0.20220714111606-acbb2962fb48 h1:cSo6/vk8YpvkLbk9v3FO97cakNmUoxwi2KMP8hd5WIw= 202 | github.com/prysmaticlabs/gohashtree v0.0.1-alpha.0.20220714111606-acbb2962fb48/go.mod h1:4pWaT30XoEx1j8KNJf3TV+E3mQkaufn7mf+jRNb/Fuk= 203 | github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= 204 | github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= 205 | github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= 206 | github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= 207 | github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= 208 | github.com/rs/cors v1.7.0 h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik= 209 | github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= 210 | github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= 211 | github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= 212 | github.com/shibukawa/configdir v0.0.0-20170330084843-e180dbdc8da0 h1:Xuk8ma/ibJ1fOy4Ee11vHhUFHQNpHhrBneOCNHVXS5w= 213 | github.com/shibukawa/configdir v0.0.0-20170330084843-e180dbdc8da0/go.mod h1:7AwjWCpdPhkSmNAgUv5C7EJ4AbmjEB3r047r3DXWu3Y= 214 | github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible h1:Bn1aCHHRnjv4Bl16T8rcaFjYSrGrIZvpiGO6P3Q4GpU= 215 | github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= 216 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 217 | github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= 218 | github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= 219 | github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= 220 | github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 221 | github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 222 | github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= 223 | github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= 224 | github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= 225 | github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= 226 | github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= 227 | github.com/supranational/blst v0.3.14 h1:xNMoHRJOTwMn63ip6qoWJ2Ymgvj7E2b9jY2FAwY+qRo= 228 | github.com/supranational/blst v0.3.14/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3/j+w+fVonLw= 229 | github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70Z7CTTCmYQn2CKbY8j86K7/FAIr141uY= 230 | github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc= 231 | github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU= 232 | github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI= 233 | github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk= 234 | github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY= 235 | github.com/urfave/cli/v2 v2.27.5 h1:WoHEJLdsXr6dDWoJgMq/CboDmyY/8HMMH1fTECbih+w= 236 | github.com/urfave/cli/v2 v2.27.5/go.mod h1:3Sevf16NykTbInEnD0yKkjDAeZDS0A6bzhBH5hrMvTQ= 237 | github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 h1:gEOO8jv9F4OT7lGCjxCBTO/36wtF6j2nSip77qHd4x4= 238 | github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1/go.mod h1:Ohn+xnUBiLI6FVj/9LpzZWtj1/D6lUovWYBkxHVV3aM= 239 | github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= 240 | github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= 241 | github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= 242 | go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= 243 | go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= 244 | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= 245 | golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= 246 | golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= 247 | golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= 248 | golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE= 249 | golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= 250 | golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34= 251 | golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc= 252 | golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa h1:FRnLl4eNAQl8hwxVVC17teOw8kdjVDVAiFMtgUdTSRQ= 253 | golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa/go.mod h1:zk2irFbV9DP96SEBUUAy67IdHUaZuSnrz1n472HUCLE= 254 | golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= 255 | golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= 256 | golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= 257 | golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= 258 | golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 259 | golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 260 | golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 261 | golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 262 | golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= 263 | golang.org/x/net v0.0.0-20200813134508-3edf25e44fcc/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= 264 | golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= 265 | golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= 266 | golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= 267 | golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= 268 | golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= 269 | golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= 270 | golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI= 271 | golang.org/x/net v0.38.0 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8= 272 | golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8= 273 | golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 274 | golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 275 | golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 276 | golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 277 | golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 278 | golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 279 | golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 280 | golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 281 | golang.org/x/sync v0.12.0 h1:MHc5BpPuC30uJk597Ri8TV3CNZcTLu6B6z4lJy+g6Jw= 282 | golang.org/x/sync v0.12.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= 283 | golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 284 | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 285 | golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 286 | golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 287 | golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 288 | golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 289 | golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 290 | golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 291 | golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 292 | golang.org/x/sys v0.0.0-20200814200057-3d37ad5750ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 293 | golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 294 | golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 295 | golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 296 | golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 297 | golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 298 | golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 299 | golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 300 | golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 301 | golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 302 | golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 303 | golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 304 | golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 305 | golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 306 | golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= 307 | golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik= 308 | golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= 309 | golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= 310 | golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= 311 | golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= 312 | golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY= 313 | golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= 314 | golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU= 315 | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 316 | golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= 317 | golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 318 | golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= 319 | golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= 320 | golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= 321 | golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= 322 | golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY= 323 | golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4= 324 | golang.org/x/time v0.9.0 h1:EsRrnYcQiGH+5FfbgvV4AP7qEZstoyrHB0DzarOQ4ZY= 325 | golang.org/x/time v0.9.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= 326 | golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 327 | golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 328 | golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= 329 | golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= 330 | golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= 331 | golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= 332 | golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 333 | golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 334 | golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 335 | golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= 336 | golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 337 | google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= 338 | google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= 339 | google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= 340 | google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= 341 | google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= 342 | google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= 343 | google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= 344 | google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= 345 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 346 | gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= 347 | gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= 348 | gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= 349 | gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc= 350 | gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc= 351 | gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= 352 | gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= 353 | gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 354 | gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 355 | gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= 356 | gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= 357 | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 358 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 359 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 360 | --------------------------------------------------------------------------------