Skip to content

Commit 2b3a0c8

Browse files
committed
Create keyed transaction with chain ID in host chain utils package
Instead of just calling bind.NewKeyedTransactorWithChainID we need to have two different versions - one for Ethereum and one for Celo. Celo codebase does not have bind.NewKeyedTransactorWithChainID function yet so we need to create EIP155-compatible transactor manually while for go-ethereum we can just use bind.NewKeyedTransactorWithChainID. We can get rid of a host-chain-specific approach when celo-org/celo-blockchain merges in changes from upstream ethereum/go-ethereum beyond v1.9.25. Constructing the transactor manually in the contract template just like before is not an option because bind.SignerFn has a different signature for ethereum/go-ethereum and celo-org/celo-blockchain.
1 parent 2232c5b commit 2b3a0c8

4 files changed

Lines changed: 59 additions & 5 deletions

File tree

pkg/chain/celo/celoutil/celoutil.go

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,23 @@ package celoutil
22

33
import (
44
"context"
5+
"crypto/ecdsa"
56
"fmt"
7+
"io/ioutil"
8+
"math/big"
9+
"time"
10+
611
"github.com/celo-org/celo-blockchain"
712
"github.com/celo-org/celo-blockchain/accounts/abi"
813
"github.com/celo-org/celo-blockchain/accounts/abi/bind"
914
"github.com/celo-org/celo-blockchain/accounts/keystore"
1015
"github.com/celo-org/celo-blockchain/common"
16+
"github.com/celo-org/celo-blockchain/core/types"
17+
"github.com/celo-org/celo-blockchain/crypto"
1118
celoclient "github.com/celo-org/celo-blockchain/ethclient"
1219
"github.com/celo-org/celo-blockchain/rpc"
1320
"github.com/ipfs/go-log"
1421
"github.com/keep-network/keep-common/pkg/chain/ethlike"
15-
"io/ioutil"
16-
"math/big"
17-
"time"
1822
)
1923

2024
var logger = log.Logger("keep-celoutil")
@@ -227,3 +231,37 @@ func NewNonceManager(
227231
ethlike.Address(account),
228232
)
229233
}
234+
235+
// NewKeyedTransactorWithChainID is a utility method to easily create
236+
// a transaction signer from a single private key.
237+
// FIXME Remove this function and rely on bind.NewKeyedTransactorWithChainID
238+
// FIXME when celo-org/celo-blockchain merges in changes from upstream
239+
// FIXME ethereum/go-ethereum beyond v1.9.25.
240+
func NewKeyedTransactorWithChainID(
241+
key *ecdsa.PrivateKey,
242+
chainID *big.Int,
243+
) (*bind.TransactOpts, error) {
244+
keyAddress := crypto.PubkeyToAddress(key.PublicKey)
245+
if chainID == nil {
246+
return nil, fmt.Errorf("no chain id specified")
247+
}
248+
return &bind.TransactOpts{
249+
From: keyAddress,
250+
Signer: func(
251+
_ types.Signer,
252+
address common.Address,
253+
tx *types.Transaction,
254+
) (*types.Transaction, error) {
255+
signer := types.NewEIP155Signer(chainID)
256+
257+
if address != keyAddress {
258+
return nil, fmt.Errorf("not authorized to sign this account")
259+
}
260+
signature, err := crypto.Sign(signer.Hash(tx).Bytes(), key)
261+
if err != nil {
262+
return nil, err
263+
}
264+
return tx.WithSignature(signer, signature)
265+
},
266+
}, nil
267+
}

pkg/chain/ethereum/ethutil/ethutil.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ package ethutil
44

55
import (
66
"context"
7+
"crypto/ecdsa"
78
"fmt"
89
"io/ioutil"
910
"math/big"
@@ -218,3 +219,12 @@ func NewNonceManager(
218219
ethlike.Address(account),
219220
)
220221
}
222+
223+
// NewKeyedTransactorWithChainID is a utility method to easily create
224+
// a transaction signer from a single private key.
225+
func NewKeyedTransactorWithChainID(
226+
privateKey *ecdsa.PrivateKey,
227+
chainID *big.Int,
228+
) (*bind.TransactOpts, error) {
229+
return bind.NewKeyedTransactorWithChainID(privateKey, chainID)
230+
}

tools/generators/ethlike/contract.go.tmpl

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,10 @@ func New{{.Class}}(
5757
From: accountKey.Address,
5858
}
5959

60-
transactorOptions, err := bind.NewKeyedTransactorWithChainID(
60+
// FIXME Switch to bind.NewKeyedTransactorWithChainID when
61+
// FIXME celo-org/celo-blockchain merges in changes from upstream
62+
// FIXME ethereum/go-ethereum beyond v1.9.25.
63+
transactorOptions, err := chainutil.NewKeyedTransactorWithChainID(
6164
accountKey.PrivateKey,
6265
chainId,
6366
)

tools/generators/ethlike/contract_template_content.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,10 @@ func New{{.Class}}(
6060
From: accountKey.Address,
6161
}
6262
63-
transactorOptions, err := bind.NewKeyedTransactorWithChainID(
63+
// FIXME Switch to bind.NewKeyedTransactorWithChainID when
64+
// FIXME celo-org/celo-blockchain merges in changes from upstream
65+
// FIXME ethereum/go-ethereum beyond v1.9.25.
66+
transactorOptions, err := chainutil.NewKeyedTransactorWithChainID(
6467
accountKey.PrivateKey,
6568
chainId,
6669
)

0 commit comments

Comments
 (0)