code.vegaprotocol.io/vega@v0.79.0/core/datasource/external/ethcall/ethcall_test.go (about)

     1  // Copyright (C) 2023 Gobalsky Labs Limited
     2  //
     3  // This program is free software: you can redistribute it and/or modify
     4  // it under the terms of the GNU Affero General Public License as
     5  // published by the Free Software Foundation, either version 3 of the
     6  // License, or (at your option) any later version.
     7  //
     8  // This program is distributed in the hope that it will be useful,
     9  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    10  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    11  // GNU Affero General Public License for more details.
    12  //
    13  // You should have received a copy of the GNU Affero General Public License
    14  // along with this program.  If not, see <http://www.gnu.org/licenses/>.
    15  
    16  package ethcall_test
    17  
    18  import (
    19  	"bytes"
    20  	"context"
    21  	"crypto/ecdsa"
    22  	"embed"
    23  	"fmt"
    24  	"log"
    25  	"math/big"
    26  
    27  	"github.com/ethereum/go-ethereum/accounts/abi"
    28  	"github.com/ethereum/go-ethereum/accounts/abi/bind"
    29  	"github.com/ethereum/go-ethereum/accounts/abi/bind/backends"
    30  	"github.com/ethereum/go-ethereum/common"
    31  	"github.com/ethereum/go-ethereum/core"
    32  	"github.com/ethereum/go-ethereum/crypto"
    33  	eth_log "github.com/ethereum/go-ethereum/log"
    34  )
    35  
    36  //go:embed testdata/*
    37  var testData embed.FS
    38  
    39  type ToyChain struct {
    40  	key          *ecdsa.PrivateKey
    41  	client       *Client
    42  	addr         common.Address
    43  	contractAddr common.Address
    44  	abiBytes     []byte
    45  }
    46  
    47  type Client struct {
    48  	*backends.SimulatedBackend
    49  }
    50  
    51  func (c *Client) ChainID(context.Context) (*big.Int, error) {
    52  	return big.NewInt(1337), nil
    53  }
    54  
    55  func NewToyChain() (*ToyChain, error) {
    56  	// Stop go-ethereum writing loads of uninteresting logs
    57  	eth_log.Root().SetHandler(eth_log.DiscardHandler())
    58  
    59  	// Setup keys
    60  	key, err := crypto.GenerateKey()
    61  	if err != nil {
    62  		return nil, fmt.Errorf("could not generate key: %w", err)
    63  	}
    64  	addr := crypto.PubkeyToAddress(key.PublicKey)
    65  	signer, err := bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337))
    66  	if err != nil {
    67  		return nil, fmt.Errorf("couldn't create signer: %w", err)
    68  	}
    69  
    70  	// Setup simulated backend (works a bit like ganache) with a balance so we can deploy contracts
    71  	client := backends.NewSimulatedBackend(
    72  		core.GenesisAlloc{
    73  			addr: {Balance: big.NewInt(10000000000000000)},
    74  		}, 10000000,
    75  	)
    76  
    77  	// Read in contract ABI
    78  	contractAbiBytes, err := testData.ReadFile("testdata/MyContract.abi")
    79  	if err != nil {
    80  		log.Fatal(err)
    81  	}
    82  
    83  	contractAbi, err := abi.JSON(bytes.NewReader(contractAbiBytes))
    84  	if err != nil {
    85  		return nil, fmt.Errorf("could not get code at test addr: %w", err)
    86  	}
    87  
    88  	// Read in contract bytecode
    89  	contractBytecodeBytes, err := testData.ReadFile("testdata/MyContract.bin")
    90  	if err != nil {
    91  		log.Fatal(err)
    92  	}
    93  
    94  	// Deploy contract
    95  	contractAddr, _, _, err := bind.DeployContract(signer, contractAbi, common.FromHex(string(contractBytecodeBytes)), client)
    96  	if err != nil {
    97  		return nil, fmt.Errorf("could not deploy contract")
    98  	}
    99  
   100  	client.Commit()
   101  
   102  	return &ToyChain{
   103  		key:          key,
   104  		client:       &Client{client},
   105  		addr:         addr,
   106  		contractAddr: contractAddr,
   107  		abiBytes:     contractAbiBytes,
   108  	}, nil
   109  }