github.com/0xsequence/ethkit@v1.25.0/ethdeploy/ethdeploy.go (about) 1 package ethdeploy 2 3 import ( 4 "context" 5 "math/big" 6 "strings" 7 8 "github.com/0xsequence/ethkit/ethrpc" 9 "github.com/0xsequence/ethkit/ethwallet" 10 "github.com/0xsequence/ethkit/go-ethereum/accounts/abi" 11 "github.com/0xsequence/ethkit/go-ethereum/accounts/abi/bind" 12 "github.com/0xsequence/ethkit/go-ethereum/common" 13 "github.com/0xsequence/ethkit/go-ethereum/core/types" 14 ) 15 16 // Deploy any contract with just the abi and its bytecode 17 // 18 // Sample usage: 19 // 20 // auth, err := wallet.Transactor() 21 // assert.NoError(t, err) 22 // auth.Nonce = big.NewInt(int64(nonce)) // next nonce for the account 23 // auth.Value = big.NewInt(0) // in wei 24 // auth.GasLimit = uint64(5000000) // in units 25 // auth.GasPrice = gasPrice 26 // 27 // // deploy transaction 28 // contractAddress, tx, contract, err := ethdeploy.DeployContract(auth, service.ETHRPC, contractABIJSONString, contractBytecodeHex) 29 // 30 // // get another account from the list 31 // wallet2, _ := ethwallet.NewETHWallet(cfg.Wallet.PrivateKeyMnemonic) 32 // wallet2.SetAccountIndex(1) 33 // address2, _ := wallet2.Address() 34 // 35 // var out = new(*big.Int) 36 // err := contract.Call(&bind.CallOpts{Context: context.Background()}, out, "balanceOf", address2, big.NewInt(1)) 37 // assert.NoError(t, err) 38 // fmt.Println("=======>", *out) // <---<< returns `balanceOf(address2)` output from the chain 39 // 40 41 type Deployer struct { 42 Provider *ethrpc.Provider 43 } 44 45 func NewDeployer(provider *ethrpc.Provider) *Deployer { 46 return &Deployer{Provider: provider} 47 } 48 49 // TODO: accept optional *TransactOpts argument, can be nil and we'll populate ourselves 50 // or make our own structs like DeployOpts with nonce, gasPrice and gasLimit 51 func (d *Deployer) DeployContract(ctx context.Context, wallet *ethwallet.Wallet, contractABI, contractBytecodeHex string, contractConstructorArgs ...interface{}) (common.Address, *types.Transaction, *bind.BoundContract, error) { 52 address := wallet.Address() 53 54 nonce, err := d.Provider.PendingNonceAt(ctx, address) 55 if err != nil { 56 return common.Address{}, nil, nil, err 57 } 58 59 gasPrice, err := d.Provider.SuggestGasPrice(ctx) 60 if err != nil { 61 return common.Address{}, nil, nil, err 62 } 63 64 auth, err := wallet.Transactor(ctx) 65 if err != nil { 66 return common.Address{}, nil, nil, err 67 } 68 69 auth.Nonce = big.NewInt(int64(nonce)) 70 auth.Value = big.NewInt(0) 71 auth.GasLimit = uint64(5000000) 72 auth.GasPrice = gasPrice 73 74 return DeployContract(auth, d.Provider, contractABI, contractBytecodeHex) 75 } 76 77 func DeployContract(auth *bind.TransactOpts, backend bind.ContractBackend, contractABI, contractBytecodeHex string, contractConstructorArgs ...interface{}) (common.Address, *types.Transaction, *bind.BoundContract, error) { 78 parsed, err := abi.JSON(strings.NewReader(contractABI)) 79 if err != nil { 80 return common.Address{}, nil, nil, err 81 } 82 83 address, tx, contract, err := bind.DeployContract(auth, parsed, common.FromHex(contractBytecodeHex), backend, contractConstructorArgs...) 84 if err != nil { 85 return common.Address{}, nil, nil, err 86 } 87 88 return address, tx, contract, nil 89 }