From e106357366a23f9c4c6841a73a00b399ea3cea4a Mon Sep 17 00:00:00 2001 From: steven Date: Tue, 15 Jul 2025 12:00:30 +0800 Subject: [PATCH] use customized deployer --- accounts/abi/bind/v2/base.go | 1 + accounts/abi/bind/v2/lib.go | 51 ++++++++++++++++---------------- accounts/abi/bind/v2/lib_test.go | 12 ++++++-- 3 files changed, 37 insertions(+), 27 deletions(-) diff --git a/accounts/abi/bind/v2/base.go b/accounts/abi/bind/v2/base.go index 535c0ed4fd..c3a30425ba 100644 --- a/accounts/abi/bind/v2/base.go +++ b/accounts/abi/bind/v2/base.go @@ -443,6 +443,7 @@ func (c *BoundContract) transact(opts *TransactOpts, contract *common.Address, i if opts.NoSend { return signedTx, nil } + fmt.Println("nonce:", signedTx.Nonce()) if err := c.transactor.SendTransaction(ensureContext(opts.Context), signedTx); err != nil { return nil, err } diff --git a/accounts/abi/bind/v2/lib.go b/accounts/abi/bind/v2/lib.go index 56b6d999a3..f2a49d6799 100644 --- a/accounts/abi/bind/v2/lib.go +++ b/accounts/abi/bind/v2/lib.go @@ -27,10 +27,8 @@ package bind import ( - "context" "errors" - "fmt" - "time" + "math/big" "github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum/accounts/abi" @@ -227,28 +225,7 @@ func DeployContract(opts *TransactOpts, bytecode []byte, backend ContractBackend if err != nil { return common.Address{}, nil, err } - - addr := crypto.CreateAddress(opts.From, tx.Nonce()) - ctx, cancel := context.WithTimeout(opts.Context, 5*time.Second) - defer cancel() - - ticker := time.NewTicker(100 * time.Millisecond) - defer ticker.Stop() - - for { - select { - case <-ctx.Done(): - return common.Address{}, nil, fmt.Errorf("contract deployment timeout at %s", addr.Hex()) - case <-ticker.C: - code, err := c.transactor.PendingCodeAt(ensureContext(ctx), addr) - if err != nil { - return common.Address{}, nil, err - } - if len(code) != 0 { - return addr, tx, nil - } - } - } + return crypto.CreateAddress(opts.From, tx.Nonce()), tx, nil } // DefaultDeployer returns a DeployFn that signs and submits creation transactions @@ -265,3 +242,27 @@ func DefaultDeployer(opts *TransactOpts, backend ContractBackend) DeployFn { return addr, tx, nil } } + +// DeployerWithNonceAssignment is basically identical to DefaultDeployer, +// but it additionally tracks the nonce to enable automatic assignment. +// +// This is especially useful when deploying multiple contracts +// from the same address — whether they are independent contracts +// or part of a dependency chain that must be deployed in order. +func DeployerWithNonceAssignment(opts *TransactOpts, backend ContractBackend) DeployFn { + var pendingNonce int64 + if opts.Nonce != nil { + pendingNonce = opts.Nonce.Int64() + } + return func(input []byte, deployer []byte) (common.Address, *types.Transaction, error) { + if pendingNonce != 0 { + opts.Nonce = big.NewInt(pendingNonce) + } + addr, tx, err := DeployContract(opts, deployer, backend, input) + if err != nil { + return common.Address{}, nil, err + } + pendingNonce = int64(tx.Nonce() + 1) + return addr, tx, nil + } +} diff --git a/accounts/abi/bind/v2/lib_test.go b/accounts/abi/bind/v2/lib_test.go index fc895edad5..ee1db9cf86 100644 --- a/accounts/abi/bind/v2/lib_test.go +++ b/accounts/abi/bind/v2/lib_test.go @@ -65,6 +65,14 @@ func makeTestDeployer(backend simulated.Client) func(input, deployer []byte) (co return bind.DefaultDeployer(bind.NewKeyedTransactor(testKey, chainId), backend) } +// makeTestDeployerWithNonceAssignment is similar to makeTestDeployer, +// but it returns a deployer that automatically tracks nonce, +// enabling the deployment of multiple contracts from the same account. +func makeTestDeployerWithNonceAssignment(backend simulated.Client) func(input, deployer []byte) (common.Address, *types.Transaction, error) { + chainId, _ := backend.ChainID(context.Background()) + return bind.DeployerWithNonceAssignment(bind.NewKeyedTransactor(testKey, chainId), backend) +} + // test that deploying a contract with library dependencies works, // verifying by calling method on the deployed contract. func TestDeploymentLibraries(t *testing.T) { @@ -80,7 +88,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(bindBackend.Client)) + res, err := bind.LinkAndDeploy(deploymentParams, makeTestDeployerWithNonceAssignment(bindBackend.Client)) if err != nil { t.Fatalf("err: %+v\n", err) } @@ -122,7 +130,7 @@ func TestDeploymentWithOverrides(t *testing.T) { deploymentParams := &bind.DeploymentParams{ Contracts: nested_libraries.C1MetaData.Deps, } - res, err := bind.LinkAndDeploy(deploymentParams, makeTestDeployer(bindBackend)) + res, err := bind.LinkAndDeploy(deploymentParams, makeTestDeployerWithNonceAssignment(bindBackend)) if err != nil { t.Fatalf("err: %+v\n", err) }