mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-28 07:36:44 +00:00
accounts/abi/bind/v2: modify v2 DeployContract to take packed input to be more in-line with the rest of the API. add a default DeployFn implementation for the deployer.
This commit is contained in:
parent
e8259bf98e
commit
6680b836f6
4 changed files with 79 additions and 55 deletions
|
|
@ -227,7 +227,16 @@ func NewBoundContract(address common.Address, abi abi.ABI, caller ContractCaller
|
|||
}
|
||||
|
||||
func DeployContract(opts *TransactOpts, abi abi.ABI, bytecode []byte, backend ContractBackend, params ...interface{}) (common.Address, *types.Transaction, *BoundContract, error) {
|
||||
return bind2.DeployContract(opts, abi, bytecode, backend, params...)
|
||||
packed, err := abi.Pack("", params...)
|
||||
if err != nil {
|
||||
return common.Address{}, nil, nil, err
|
||||
}
|
||||
addr, tx, err := bind2.DeployContract(opts, bytecode, backend, packed)
|
||||
if err != nil {
|
||||
return common.Address{}, nil, nil, err
|
||||
}
|
||||
boundContract := NewBoundContract(addr, abi, backend, backend, backend)
|
||||
return addr, tx, boundContract, nil
|
||||
}
|
||||
|
||||
// MetaData collects all metadata for a bound contract.
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@ import (
|
|||
"github.com/ethereum/go-ethereum/accounts/abi"
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
"github.com/ethereum/go-ethereum/event"
|
||||
)
|
||||
|
||||
|
|
@ -37,24 +36,6 @@ func NewBoundContractV1(address common.Address, abi abi.ABI, caller ContractCall
|
|||
}
|
||||
}
|
||||
|
||||
// DeployContract deploys a contract onto the Ethereum blockchain and binds the
|
||||
// deployment address with a Go wrapper.
|
||||
func DeployContract(opts *TransactOpts, abi abi.ABI, bytecode []byte, backend ContractBackend, params ...any) (common.Address, *types.Transaction, *BoundContractV1, error) {
|
||||
// Otherwise try to deploy the contract
|
||||
c := NewBoundContractV1(common.Address{}, abi, backend, backend, backend)
|
||||
|
||||
input, err := c.abi.Pack("", params...)
|
||||
if err != nil {
|
||||
return common.Address{}, nil, nil, err
|
||||
}
|
||||
tx, err := c.transact(opts, nil, append(bytecode, input...))
|
||||
if err != nil {
|
||||
return common.Address{}, nil, nil, err
|
||||
}
|
||||
c.address = crypto.CreateAddress(opts.From, tx.Nonce())
|
||||
return c.address, tx, c, nil
|
||||
}
|
||||
|
||||
// Call invokes the (constant) contract method with params as input values and
|
||||
// sets the output to result. The result type might be a single field for simple
|
||||
// returns, a slice of interfaces for anonymous returns and a struct for named
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
package bind
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
|
||||
"github.com/ethereum/go-ethereum"
|
||||
|
|
@ -180,10 +181,10 @@ func Transact(c BoundContract, opt *TransactOpts, packedInput []byte) (*types.Tr
|
|||
return c.transact(opt, &addr, packedInput)
|
||||
}
|
||||
|
||||
// DeployContractRaw deploys a contract onto the Ethereum blockchain and binds the
|
||||
// DeployContract deploys a contract onto the Ethereum blockchain and binds the
|
||||
// deployment address with a Go wrapper. It expects its parameters to be abi-encoded
|
||||
// bytes.
|
||||
func DeployContractRaw(opts *TransactOpts, bytecode []byte, backend ContractBackend, packedParams []byte) (common.Address, *types.Transaction, error) {
|
||||
func DeployContract(opts *TransactOpts, bytecode []byte, backend ContractBackend, packedParams []byte) (common.Address, *types.Transaction, error) {
|
||||
c := NewBoundContractV1(common.Address{}, abi.ABI{}, backend, backend, backend)
|
||||
tx, err := c.RawCreationTransact(opts, append(bytecode, packedParams...))
|
||||
if err != nil {
|
||||
|
|
@ -192,3 +193,20 @@ func DeployContractRaw(opts *TransactOpts, bytecode []byte, backend ContractBack
|
|||
address := crypto.CreateAddress(opts.From, tx.Nonce())
|
||||
return address, tx, nil
|
||||
}
|
||||
|
||||
// DefaultDeployer returns a DeployFn that signs and submits creation transactions using the given signer.
|
||||
func DefaultDeployer(ctx context.Context, from common.Address, backend ContractBackend, signer SignerFn) DeployFn {
|
||||
opts := &TransactOpts{
|
||||
From: from,
|
||||
Nonce: nil,
|
||||
Signer: signer,
|
||||
Context: ctx,
|
||||
}
|
||||
return func(input []byte, deployer []byte) (common.Address, *types.Transaction, error) {
|
||||
addr, tx, err := DeployContract(opts, deployer, backend, input)
|
||||
if err != nil {
|
||||
return common.Address{}, nil, err
|
||||
}
|
||||
return addr, tx, nil
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ import (
|
|||
)
|
||||
|
||||
var testKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
|
||||
var testAddr = crypto.PubkeyToAddress(testKey.PublicKey)
|
||||
|
||||
// JSON returns a parsed ABI interface and error if it failed.
|
||||
func JSON(reader io.Reader) (abi.ABI, error) {
|
||||
|
|
@ -53,8 +54,7 @@ func JSON(reader io.Reader) (abi.ABI, error) {
|
|||
return instance, nil
|
||||
}
|
||||
|
||||
func testSetup() (*bind.TransactOpts, *backends.SimulatedBackend, error) {
|
||||
testAddr := crypto.PubkeyToAddress(testKey.PublicKey)
|
||||
func testSetup() (*backends.SimulatedBackend, error) {
|
||||
backend := simulated.NewBackend(
|
||||
types.GenesisAlloc{
|
||||
testAddr: {Balance: big.NewInt(10000000000000000)},
|
||||
|
|
@ -64,23 +64,6 @@ func testSetup() (*bind.TransactOpts, *backends.SimulatedBackend, error) {
|
|||
},
|
||||
)
|
||||
|
||||
signer := types.LatestSigner(params.AllDevChainProtocolChanges)
|
||||
opts := &bind.TransactOpts{
|
||||
From: testAddr,
|
||||
Nonce: nil,
|
||||
Signer: func(address common.Address, tx *types.Transaction) (*types.Transaction, error) {
|
||||
signature, err := crypto.Sign(signer.Hash(tx).Bytes(), testKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
signedTx, err := tx.WithSignature(signer, signature)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return signedTx, nil
|
||||
},
|
||||
Context: context.Background(),
|
||||
}
|
||||
// we should just be able to use the backend directly, instead of using
|
||||
// this deprecated interface. However, the simulated backend no longer
|
||||
// implements backends.SimulatedBackend...
|
||||
|
|
@ -88,19 +71,30 @@ func testSetup() (*bind.TransactOpts, *backends.SimulatedBackend, error) {
|
|||
Backend: backend,
|
||||
Client: backend.Client(),
|
||||
}
|
||||
return opts, &bindBackend, nil
|
||||
return &bindBackend, nil
|
||||
}
|
||||
|
||||
func makeTestDeployer(auth *bind.TransactOpts, backend bind.ContractBackend) func(input, deployer []byte) (common.Address, *types.Transaction, error) {
|
||||
return func(input, deployer []byte) (common.Address, *types.Transaction, error) {
|
||||
return bind.DeployContractRaw(auth, deployer, backend, input)
|
||||
func makeTestDeployer(backend bind.ContractBackend) func(input, deployer []byte) (common.Address, *types.Transaction, error) {
|
||||
signer := types.LatestSigner(params.AllDevChainProtocolChanges)
|
||||
sign := func(sender common.Address, tx *types.Transaction) (*types.Transaction, error) {
|
||||
signature, err := crypto.Sign(signer.Hash(tx).Bytes(), testKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
signedTx, err := tx.WithSignature(signer, signature)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return signedTx, nil
|
||||
}
|
||||
|
||||
return bind.DefaultDeployer(context.Background(), testAddr, backend, sign)
|
||||
}
|
||||
|
||||
// test that deploying a contract with library dependencies works,
|
||||
// verifying by calling method on the deployed contract.
|
||||
func TestDeploymentLibraries(t *testing.T) {
|
||||
opts, bindBackend, err := testSetup()
|
||||
bindBackend, err := testSetup()
|
||||
if err != nil {
|
||||
t.Fatalf("err setting up test: %v", err)
|
||||
}
|
||||
|
|
@ -112,7 +106,7 @@ func TestDeploymentLibraries(t *testing.T) {
|
|||
Contracts: []*bind.MetaData{&nested_libraries.C1MetaData},
|
||||
Inputs: map[string][]byte{nested_libraries.C1MetaData.ID: constructorInput},
|
||||
}
|
||||
res, err := bind.LinkAndDeploy(deploymentParams, makeTestDeployer(opts, bindBackend))
|
||||
res, err := bind.LinkAndDeploy(deploymentParams, makeTestDeployer(bindBackend))
|
||||
if err != nil {
|
||||
t.Fatalf("err: %+v\n", err)
|
||||
}
|
||||
|
|
@ -144,7 +138,7 @@ func TestDeploymentLibraries(t *testing.T) {
|
|||
// Same as TestDeployment. However, stagger the deployments with overrides:
|
||||
// first deploy the library deps and then the contract.
|
||||
func TestDeploymentWithOverrides(t *testing.T) {
|
||||
opts, bindBackend, err := testSetup()
|
||||
bindBackend, err := testSetup()
|
||||
if err != nil {
|
||||
t.Fatalf("err setting up test: %v", err)
|
||||
}
|
||||
|
|
@ -154,7 +148,7 @@ func TestDeploymentWithOverrides(t *testing.T) {
|
|||
deploymentParams := &bind.DeploymentParams{
|
||||
Contracts: nested_libraries.C1MetaData.Deps,
|
||||
}
|
||||
res, err := bind.LinkAndDeploy(deploymentParams, makeTestDeployer(opts, bindBackend))
|
||||
res, err := bind.LinkAndDeploy(deploymentParams, makeTestDeployer(bindBackend))
|
||||
if err != nil {
|
||||
t.Fatalf("err: %+v\n", err)
|
||||
}
|
||||
|
|
@ -180,7 +174,7 @@ func TestDeploymentWithOverrides(t *testing.T) {
|
|||
Inputs: map[string][]byte{nested_libraries.C1MetaData.ID: constructorInput},
|
||||
Overrides: overrides,
|
||||
}
|
||||
res, err = bind.LinkAndDeploy(deploymentParams, makeTestDeployer(opts, bindBackend))
|
||||
res, err = bind.LinkAndDeploy(deploymentParams, makeTestDeployer(bindBackend))
|
||||
if err != nil {
|
||||
t.Fatalf("err: %+v\n", err)
|
||||
}
|
||||
|
|
@ -209,15 +203,37 @@ func TestDeploymentWithOverrides(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
// returns transaction auth to send a basic transaction from testAddr
|
||||
func defaultTxAuth() *bind.TransactOpts {
|
||||
signer := types.LatestSigner(params.AllDevChainProtocolChanges)
|
||||
opts := &bind.TransactOpts{
|
||||
From: testAddr,
|
||||
Nonce: nil,
|
||||
Signer: func(address common.Address, tx *types.Transaction) (*types.Transaction, error) {
|
||||
signature, err := crypto.Sign(signer.Hash(tx).Bytes(), testKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
signedTx, err := tx.WithSignature(signer, signature)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return signedTx, nil
|
||||
},
|
||||
Context: context.Background(),
|
||||
}
|
||||
return opts
|
||||
}
|
||||
|
||||
func TestEvents(t *testing.T) {
|
||||
// test watch/filter logs method on a contract that emits various kinds of events (struct-containing, etc.)
|
||||
txAuth, backend, err := testSetup()
|
||||
backend, err := testSetup()
|
||||
if err != nil {
|
||||
t.Fatalf("error setting up testing env: %v", err)
|
||||
}
|
||||
|
||||
deploymentParams := &bind.DeploymentParams{Contracts: []*bind.MetaData{&events.CMetaData}}
|
||||
res, err := bind.LinkAndDeploy(deploymentParams, makeTestDeployer(txAuth, backend))
|
||||
res, err := bind.LinkAndDeploy(deploymentParams, makeTestDeployer(backend))
|
||||
if err != nil {
|
||||
t.Fatalf("error deploying contract for testing: %v", err)
|
||||
}
|
||||
|
|
@ -245,7 +261,7 @@ func TestEvents(t *testing.T) {
|
|||
defer sub2.Unsubscribe()
|
||||
|
||||
packedInput := c.PackEmitMulti()
|
||||
tx, err := bind.Transact(instance, txAuth, packedInput)
|
||||
tx, err := bind.Transact(instance, defaultTxAuth(), packedInput)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to send transaction: %v", err)
|
||||
}
|
||||
|
|
@ -310,13 +326,13 @@ done:
|
|||
|
||||
func TestErrors(t *testing.T) {
|
||||
// test watch/filter logs method on a contract that emits various kinds of events (struct-containing, etc.)
|
||||
txAuth, backend, err := testSetup()
|
||||
backend, err := testSetup()
|
||||
if err != nil {
|
||||
t.Fatalf("error setting up testing env: %v", err)
|
||||
}
|
||||
|
||||
deploymentParams := &bind.DeploymentParams{Contracts: []*bind.MetaData{&solc_errors.CMetaData}}
|
||||
res, err := bind.LinkAndDeploy(deploymentParams, makeTestDeployer(txAuth, backend))
|
||||
res, err := bind.LinkAndDeploy(deploymentParams, makeTestDeployer(backend))
|
||||
if err != nil {
|
||||
t.Fatalf("error deploying contract for testing: %v", err)
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue