accounts/abi/bind: allow specifying signer on transactOpts (#21356)

This commit enables users to specify which signer they want to use while creating their transactOpts.
Previously all contract interactions used the homestead signer. Now a user can specify whether they
want to sign with homestead or EIP155 and specify the chainID which adds another layer of security.

Closes #16484
This commit is contained in:
Marius van der Wijden 2020-12-08 14:44:56 +01:00 committed by GitHub
parent 6a4e730003
commit ed0670cb17
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 127 additions and 40 deletions

@ -21,6 +21,7 @@ import (
"errors" "errors"
"io" "io"
"io/ioutil" "io/ioutil"
"math/big"
"github.com/ethereum/go-ethereum/accounts" "github.com/ethereum/go-ethereum/accounts"
"github.com/ethereum/go-ethereum/accounts/external" "github.com/ethereum/go-ethereum/accounts/external"
@ -28,11 +29,21 @@ import (
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/log"
) )
// ErrNoChainID is returned whenever the user failed to specify a chain id.
var ErrNoChainID = errors.New("no chain id specified")
// ErrNotAuthorized is returned when an account is not properly unlocked.
var ErrNotAuthorized = errors.New("not authorized to sign this account")
// NewTransactor is a utility method to easily create a transaction signer from // NewTransactor is a utility method to easily create a transaction signer from
// an encrypted json key stream and the associated passphrase. // an encrypted json key stream and the associated passphrase.
//
// Deprecated: Use NewTransactorWithChainID instead.
func NewTransactor(keyin io.Reader, passphrase string) (*TransactOpts, error) { func NewTransactor(keyin io.Reader, passphrase string) (*TransactOpts, error) {
log.Warn("WARNING: NewTransactor has been deprecated in favour of NewTransactorWithChainID")
json, err := ioutil.ReadAll(keyin) json, err := ioutil.ReadAll(keyin)
if err != nil { if err != nil {
return nil, err return nil, err
@ -45,13 +56,17 @@ func NewTransactor(keyin io.Reader, passphrase string) (*TransactOpts, error) {
} }
// NewKeyStoreTransactor is a utility method to easily create a transaction signer from // NewKeyStoreTransactor is a utility method to easily create a transaction signer from
// a decrypted key from a keystore. // an decrypted key from a keystore.
//
// Deprecated: Use NewKeyStoreTransactorWithChainID instead.
func NewKeyStoreTransactor(keystore *keystore.KeyStore, account accounts.Account) (*TransactOpts, error) { func NewKeyStoreTransactor(keystore *keystore.KeyStore, account accounts.Account) (*TransactOpts, error) {
log.Warn("WARNING: NewKeyStoreTransactor has been deprecated in favour of NewTransactorWithChainID")
signer := types.HomesteadSigner{}
return &TransactOpts{ return &TransactOpts{
From: account.Address, From: account.Address,
Signer: func(signer types.Signer, address common.Address, tx *types.Transaction) (*types.Transaction, error) { Signer: func(address common.Address, tx *types.Transaction) (*types.Transaction, error) {
if address != account.Address { if address != account.Address {
return nil, errors.New("not authorized to sign this account") return nil, ErrNotAuthorized
} }
signature, err := keystore.SignHash(account, signer.Hash(tx).Bytes()) signature, err := keystore.SignHash(account, signer.Hash(tx).Bytes())
if err != nil { if err != nil {
@ -64,13 +79,17 @@ func NewKeyStoreTransactor(keystore *keystore.KeyStore, account accounts.Account
// NewKeyedTransactor is a utility method to easily create a transaction signer // NewKeyedTransactor is a utility method to easily create a transaction signer
// from a single private key. // from a single private key.
//
// Deprecated: Use NewKeyedTransactorWithChainID instead.
func NewKeyedTransactor(key *ecdsa.PrivateKey) *TransactOpts { func NewKeyedTransactor(key *ecdsa.PrivateKey) *TransactOpts {
log.Warn("WARNING: NewKeyedTransactor has been deprecated in favour of NewKeyedTransactorWithChainID")
keyAddr := crypto.PubkeyToAddress(key.PublicKey) keyAddr := crypto.PubkeyToAddress(key.PublicKey)
signer := types.HomesteadSigner{}
return &TransactOpts{ return &TransactOpts{
From: keyAddr, From: keyAddr,
Signer: func(signer types.Signer, address common.Address, tx *types.Transaction) (*types.Transaction, error) { Signer: func(address common.Address, tx *types.Transaction) (*types.Transaction, error) {
if address != keyAddr { if address != keyAddr {
return nil, errors.New("not authorized to sign this account") return nil, ErrNotAuthorized
} }
signature, err := crypto.Sign(signer.Hash(tx).Bytes(), key) signature, err := crypto.Sign(signer.Hash(tx).Bytes(), key)
if err != nil { if err != nil {
@ -81,14 +100,73 @@ func NewKeyedTransactor(key *ecdsa.PrivateKey) *TransactOpts {
} }
} }
// NewTransactorWithChainID is a utility method to easily create a transaction signer from
// an encrypted json key stream and the associated passphrase.
func NewTransactorWithChainID(keyin io.Reader, passphrase string, chainID *big.Int) (*TransactOpts, error) {
json, err := ioutil.ReadAll(keyin)
if err != nil {
return nil, err
}
key, err := keystore.DecryptKey(json, passphrase)
if err != nil {
return nil, err
}
return NewKeyedTransactorWithChainID(key.PrivateKey, chainID)
}
// NewKeyStoreTransactorWithChainID is a utility method to easily create a transaction signer from
// an decrypted key from a keystore.
func NewKeyStoreTransactorWithChainID(keystore *keystore.KeyStore, account accounts.Account, chainID *big.Int) (*TransactOpts, error) {
if chainID == nil {
return nil, ErrNoChainID
}
signer := types.NewEIP155Signer(chainID)
return &TransactOpts{
From: account.Address,
Signer: func(address common.Address, tx *types.Transaction) (*types.Transaction, error) {
if address != account.Address {
return nil, ErrNotAuthorized
}
signature, err := keystore.SignHash(account, signer.Hash(tx).Bytes())
if err != nil {
return nil, err
}
return tx.WithSignature(signer, signature)
},
}, nil
}
// NewKeyedTransactorWithChainID is a utility method to easily create a transaction signer
// from a single private key.
func NewKeyedTransactorWithChainID(key *ecdsa.PrivateKey, chainID *big.Int) (*TransactOpts, error) {
keyAddr := crypto.PubkeyToAddress(key.PublicKey)
if chainID == nil {
return nil, ErrNoChainID
}
signer := types.NewEIP155Signer(chainID)
return &TransactOpts{
From: keyAddr,
Signer: func(address common.Address, tx *types.Transaction) (*types.Transaction, error) {
if address != keyAddr {
return nil, ErrNotAuthorized
}
signature, err := crypto.Sign(signer.Hash(tx).Bytes(), key)
if err != nil {
return nil, err
}
return tx.WithSignature(signer, signature)
},
}, nil
}
// NewClefTransactor is a utility method to easily create a transaction signer // NewClefTransactor is a utility method to easily create a transaction signer
// with a clef backend. // with a clef backend.
func NewClefTransactor(clef *external.ExternalSigner, account accounts.Account) *TransactOpts { func NewClefTransactor(clef *external.ExternalSigner, account accounts.Account) *TransactOpts {
return &TransactOpts{ return &TransactOpts{
From: account.Address, From: account.Address,
Signer: func(signer types.Signer, address common.Address, transaction *types.Transaction) (*types.Transaction, error) { Signer: func(address common.Address, transaction *types.Transaction) (*types.Transaction, error) {
if address != account.Address { if address != account.Address {
return nil, errors.New("not authorized to sign this account") return nil, ErrNotAuthorized
} }
return clef.SignTx(account, transaction, nil) // Clef enforces its own chain id return clef.SignTx(account, transaction, nil) // Clef enforces its own chain id
}, },

@ -74,6 +74,7 @@ type SimulatedBackend struct {
// NewSimulatedBackendWithDatabase creates a new binding backend based on the given database // NewSimulatedBackendWithDatabase creates a new binding backend based on the given database
// and uses a simulated blockchain for testing purposes. // and uses a simulated blockchain for testing purposes.
// A simulated backend always uses chainID 1337.
func NewSimulatedBackendWithDatabase(database ethdb.Database, alloc core.GenesisAlloc, gasLimit uint64) *SimulatedBackend { func NewSimulatedBackendWithDatabase(database ethdb.Database, alloc core.GenesisAlloc, gasLimit uint64) *SimulatedBackend {
genesis := core.Genesis{Config: params.AllEthashProtocolChanges, GasLimit: gasLimit, Alloc: alloc} genesis := core.Genesis{Config: params.AllEthashProtocolChanges, GasLimit: gasLimit, Alloc: alloc}
genesis.MustCommit(database) genesis.MustCommit(database)
@ -91,6 +92,7 @@ func NewSimulatedBackendWithDatabase(database ethdb.Database, alloc core.Genesis
// NewSimulatedBackend creates a new binding backend using a simulated blockchain // NewSimulatedBackend creates a new binding backend using a simulated blockchain
// for testing purposes. // for testing purposes.
// A simulated backend always uses chainID 1337.
func NewSimulatedBackend(alloc core.GenesisAlloc, gasLimit uint64) *SimulatedBackend { func NewSimulatedBackend(alloc core.GenesisAlloc, gasLimit uint64) *SimulatedBackend {
return NewSimulatedBackendWithDatabase(rawdb.NewMemoryDatabase(), alloc, gasLimit) return NewSimulatedBackendWithDatabase(rawdb.NewMemoryDatabase(), alloc, gasLimit)
} }

@ -39,7 +39,7 @@ import (
func TestSimulatedBackend(t *testing.T) { func TestSimulatedBackend(t *testing.T) {
var gasLimit uint64 = 8000029 var gasLimit uint64 = 8000029
key, _ := crypto.GenerateKey() // nolint: gosec key, _ := crypto.GenerateKey() // nolint: gosec
auth := bind.NewKeyedTransactor(key) auth, _ := bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337))
genAlloc := make(core.GenesisAlloc) genAlloc := make(core.GenesisAlloc)
genAlloc[auth.From] = core.GenesisAccount{Balance: big.NewInt(9223372036854775807)} genAlloc[auth.From] = core.GenesisAccount{Balance: big.NewInt(9223372036854775807)}
@ -411,7 +411,7 @@ func TestSimulatedBackend_EstimateGas(t *testing.T) {
key, _ := crypto.GenerateKey() key, _ := crypto.GenerateKey()
addr := crypto.PubkeyToAddress(key.PublicKey) addr := crypto.PubkeyToAddress(key.PublicKey)
opts := bind.NewKeyedTransactor(key) opts, _ := bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337))
sim := NewSimulatedBackend(core.GenesisAlloc{addr: {Balance: big.NewInt(params.Ether)}}, 10000000) sim := NewSimulatedBackend(core.GenesisAlloc{addr: {Balance: big.NewInt(params.Ether)}}, 10000000)
defer sim.Close() defer sim.Close()
@ -888,7 +888,7 @@ func TestSimulatedBackend_PendingCodeAt(t *testing.T) {
if err != nil { if err != nil {
t.Errorf("could not get code at test addr: %v", err) t.Errorf("could not get code at test addr: %v", err)
} }
auth := bind.NewKeyedTransactor(testKey) auth, _ := bind.NewKeyedTransactorWithChainID(testKey, big.NewInt(1337))
contractAddr, tx, contract, err := bind.DeployContract(auth, parsed, common.FromHex(abiBin), sim) contractAddr, tx, contract, err := bind.DeployContract(auth, parsed, common.FromHex(abiBin), sim)
if err != nil { if err != nil {
t.Errorf("could not deploy contract: %v tx: %v contract: %v", err, tx, contract) t.Errorf("could not deploy contract: %v tx: %v contract: %v", err, tx, contract)
@ -924,7 +924,7 @@ func TestSimulatedBackend_CodeAt(t *testing.T) {
if err != nil { if err != nil {
t.Errorf("could not get code at test addr: %v", err) t.Errorf("could not get code at test addr: %v", err)
} }
auth := bind.NewKeyedTransactor(testKey) auth, _ := bind.NewKeyedTransactorWithChainID(testKey, big.NewInt(1337))
contractAddr, tx, contract, err := bind.DeployContract(auth, parsed, common.FromHex(abiBin), sim) contractAddr, tx, contract, err := bind.DeployContract(auth, parsed, common.FromHex(abiBin), sim)
if err != nil { if err != nil {
t.Errorf("could not deploy contract: %v tx: %v contract: %v", err, tx, contract) t.Errorf("could not deploy contract: %v tx: %v contract: %v", err, tx, contract)
@ -956,7 +956,7 @@ func TestSimulatedBackend_PendingAndCallContract(t *testing.T) {
if err != nil { if err != nil {
t.Errorf("could not get code at test addr: %v", err) t.Errorf("could not get code at test addr: %v", err)
} }
contractAuth := bind.NewKeyedTransactor(testKey) contractAuth, _ := bind.NewKeyedTransactorWithChainID(testKey, big.NewInt(1337))
addr, _, _, err := bind.DeployContract(contractAuth, parsed, common.FromHex(abiBin), sim) addr, _, _, err := bind.DeployContract(contractAuth, parsed, common.FromHex(abiBin), sim)
if err != nil { if err != nil {
t.Errorf("could not deploy contract: %v", err) t.Errorf("could not deploy contract: %v", err)
@ -1043,7 +1043,7 @@ func TestSimulatedBackend_CallContractRevert(t *testing.T) {
if err != nil { if err != nil {
t.Errorf("could not get code at test addr: %v", err) t.Errorf("could not get code at test addr: %v", err)
} }
contractAuth := bind.NewKeyedTransactor(testKey) contractAuth, _ := bind.NewKeyedTransactorWithChainID(testKey, big.NewInt(1337))
addr, _, _, err := bind.DeployContract(contractAuth, parsed, common.FromHex(reverterBin), sim) addr, _, _, err := bind.DeployContract(contractAuth, parsed, common.FromHex(reverterBin), sim)
if err != nil { if err != nil {
t.Errorf("could not deploy contract: %v", err) t.Errorf("could not deploy contract: %v", err)

@ -32,7 +32,7 @@ import (
// SignerFn is a signer function callback when a contract requires a method to // SignerFn is a signer function callback when a contract requires a method to
// sign the transaction before submission. // sign the transaction before submission.
type SignerFn func(types.Signer, common.Address, *types.Transaction) (*types.Transaction, error) type SignerFn func(common.Address, *types.Transaction) (*types.Transaction, error)
// CallOpts is the collection of options to fine tune a contract call request. // CallOpts is the collection of options to fine tune a contract call request.
type CallOpts struct { type CallOpts struct {
@ -256,7 +256,7 @@ func (c *BoundContract) transact(opts *TransactOpts, contract *common.Address, i
if opts.Signer == nil { if opts.Signer == nil {
return nil, errors.New("no signer to authorize the transaction with") return nil, errors.New("no signer to authorize the transaction with")
} }
signedTx, err := opts.Signer(types.HomesteadSigner{}, opts.From, rawTx) signedTx, err := opts.Signer(opts.From, rawTx)
if err != nil { if err != nil {
return nil, err return nil, err
} }

@ -296,7 +296,7 @@ var bindTests = []struct {
` `
// Generate a new random account and a funded simulator // Generate a new random account and a funded simulator
key, _ := crypto.GenerateKey() key, _ := crypto.GenerateKey()
auth := bind.NewKeyedTransactor(key) auth, _ := bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337))
sim := backends.NewSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000)}}, 10000000) sim := backends.NewSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000)}}, 10000000)
defer sim.Close() defer sim.Close()
@ -351,7 +351,7 @@ var bindTests = []struct {
` `
// Generate a new random account and a funded simulator // Generate a new random account and a funded simulator
key, _ := crypto.GenerateKey() key, _ := crypto.GenerateKey()
auth := bind.NewKeyedTransactor(key) auth, _ := bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337))
sim := backends.NewSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000)}}, 10000000) sim := backends.NewSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000)}}, 10000000)
defer sim.Close() defer sim.Close()
@ -397,7 +397,7 @@ var bindTests = []struct {
` `
// Generate a new random account and a funded simulator // Generate a new random account and a funded simulator
key, _ := crypto.GenerateKey() key, _ := crypto.GenerateKey()
auth := bind.NewKeyedTransactor(key) auth, _ := bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337))
sim := backends.NewSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000)}}, 10000000) sim := backends.NewSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000)}}, 10000000)
defer sim.Close() defer sim.Close()
@ -455,7 +455,7 @@ var bindTests = []struct {
` `
// Generate a new random account and a funded simulator // Generate a new random account and a funded simulator
key, _ := crypto.GenerateKey() key, _ := crypto.GenerateKey()
auth := bind.NewKeyedTransactor(key) auth, _ := bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337))
sim := backends.NewSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000)}}, 10000000) sim := backends.NewSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000)}}, 10000000)
defer sim.Close() defer sim.Close()
@ -503,7 +503,7 @@ var bindTests = []struct {
` `
// Generate a new random account and a funded simulator // Generate a new random account and a funded simulator
key, _ := crypto.GenerateKey() key, _ := crypto.GenerateKey()
auth := bind.NewKeyedTransactor(key) auth, _ := bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337))
sim := backends.NewSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000)}}, 10000000) sim := backends.NewSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000)}}, 10000000)
defer sim.Close() defer sim.Close()
@ -598,7 +598,7 @@ var bindTests = []struct {
` `
// Generate a new random account and a funded simulator // Generate a new random account and a funded simulator
key, _ := crypto.GenerateKey() key, _ := crypto.GenerateKey()
auth := bind.NewKeyedTransactor(key) auth, _ := bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337))
sim := backends.NewSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000)}}, 10000000) sim := backends.NewSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000)}}, 10000000)
defer sim.Close() defer sim.Close()
@ -648,7 +648,7 @@ var bindTests = []struct {
` `
// Generate a new random account and a funded simulator // Generate a new random account and a funded simulator
key, _ := crypto.GenerateKey() key, _ := crypto.GenerateKey()
auth := bind.NewKeyedTransactor(key) auth, _ := bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337))
sim := backends.NewSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000)}}, 10000000) sim := backends.NewSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000)}}, 10000000)
defer sim.Close() defer sim.Close()
@ -723,7 +723,7 @@ var bindTests = []struct {
` `
// Generate a new random account and a funded simulator // Generate a new random account and a funded simulator
key, _ := crypto.GenerateKey() key, _ := crypto.GenerateKey()
auth := bind.NewKeyedTransactor(key) auth, _ := bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337))
sim := backends.NewSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000)}}, 10000000) sim := backends.NewSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000)}}, 10000000)
defer sim.Close() defer sim.Close()
@ -817,7 +817,7 @@ var bindTests = []struct {
` `
// Generate a new random account and a funded simulator // Generate a new random account and a funded simulator
key, _ := crypto.GenerateKey() key, _ := crypto.GenerateKey()
auth := bind.NewKeyedTransactor(key) auth, _ := bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337))
sim := backends.NewSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000)}}, 10000000) sim := backends.NewSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000)}}, 10000000)
defer sim.Close() defer sim.Close()
@ -1007,7 +1007,7 @@ var bindTests = []struct {
` `
// Generate a new random account and a funded simulator // Generate a new random account and a funded simulator
key, _ := crypto.GenerateKey() key, _ := crypto.GenerateKey()
auth := bind.NewKeyedTransactor(key) auth, _ := bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337))
sim := backends.NewSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000)}}, 10000000) sim := backends.NewSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000)}}, 10000000)
defer sim.Close() defer sim.Close()
@ -1142,7 +1142,7 @@ var bindTests = []struct {
` `
key, _ := crypto.GenerateKey() key, _ := crypto.GenerateKey()
auth := bind.NewKeyedTransactor(key) auth, _ := bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337))
sim := backends.NewSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000)}}, 10000000) sim := backends.NewSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000)}}, 10000000)
defer sim.Close() defer sim.Close()
@ -1284,7 +1284,7 @@ var bindTests = []struct {
` `
// Generate a new random account and a funded simulator // Generate a new random account and a funded simulator
key, _ := crypto.GenerateKey() key, _ := crypto.GenerateKey()
auth := bind.NewKeyedTransactor(key) auth, _ := bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337))
sim := backends.NewSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000)}}, 10000000) sim := backends.NewSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000)}}, 10000000)
defer sim.Close() defer sim.Close()
@ -1350,7 +1350,7 @@ var bindTests = []struct {
` `
// Initialize test accounts // Initialize test accounts
key, _ := crypto.GenerateKey() key, _ := crypto.GenerateKey()
auth := bind.NewKeyedTransactor(key) auth, _ := bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337))
sim := backends.NewSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000)}}, 10000000) sim := backends.NewSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000)}}, 10000000)
defer sim.Close() defer sim.Close()
@ -1444,7 +1444,7 @@ var bindTests = []struct {
sim := backends.NewSimulatedBackend(core.GenesisAlloc{addr: {Balance: big.NewInt(1000000000)}}, 10000000) sim := backends.NewSimulatedBackend(core.GenesisAlloc{addr: {Balance: big.NewInt(1000000000)}}, 10000000)
defer sim.Close() defer sim.Close()
transactOpts := bind.NewKeyedTransactor(key) transactOpts, _ := bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337))
_, _, _, err := DeployIdentifierCollision(transactOpts, sim) _, _, _, err := DeployIdentifierCollision(transactOpts, sim)
if err != nil { if err != nil {
t.Fatalf("failed to deploy contract: %v", err) t.Fatalf("failed to deploy contract: %v", err)
@ -1506,7 +1506,7 @@ var bindTests = []struct {
sim := backends.NewSimulatedBackend(core.GenesisAlloc{addr: {Balance: big.NewInt(1000000000)}}, 10000000) sim := backends.NewSimulatedBackend(core.GenesisAlloc{addr: {Balance: big.NewInt(1000000000)}}, 10000000)
defer sim.Close() defer sim.Close()
transactOpts := bind.NewKeyedTransactor(key) transactOpts, _ := bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337))
_, _, c1, err := DeployContractOne(transactOpts, sim) _, _, c1, err := DeployContractOne(transactOpts, sim)
if err != nil { if err != nil {
t.Fatal("Failed to deploy contract") t.Fatal("Failed to deploy contract")
@ -1563,7 +1563,7 @@ var bindTests = []struct {
` `
// Generate a new random account and a funded simulator // Generate a new random account and a funded simulator
key, _ := crypto.GenerateKey() key, _ := crypto.GenerateKey()
auth := bind.NewKeyedTransactor(key) auth, _ := bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337))
sim := backends.NewSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000)}}, 10000000) sim := backends.NewSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000)}}, 10000000)
defer sim.Close() defer sim.Close()
@ -1632,7 +1632,7 @@ var bindTests = []struct {
sim := backends.NewSimulatedBackend(core.GenesisAlloc{addr: {Balance: big.NewInt(1000000000)}}, 1000000) sim := backends.NewSimulatedBackend(core.GenesisAlloc{addr: {Balance: big.NewInt(1000000000)}}, 1000000)
defer sim.Close() defer sim.Close()
opts := bind.NewKeyedTransactor(key) opts, _ := bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337))
_, _, c, err := DeployNewFallbacks(opts, sim) _, _, c, err := DeployNewFallbacks(opts, sim)
if err != nil { if err != nil {
t.Fatalf("Failed to deploy contract: %v", err) t.Fatalf("Failed to deploy contract: %v", err)

@ -178,7 +178,7 @@ func TestCheckpointRegister(t *testing.T) {
contractBackend := backends.NewSimulatedBackend(core.GenesisAlloc{accounts[0].addr: {Balance: big.NewInt(1000000000)}, accounts[1].addr: {Balance: big.NewInt(1000000000)}, accounts[2].addr: {Balance: big.NewInt(1000000000)}}, 10000000) contractBackend := backends.NewSimulatedBackend(core.GenesisAlloc{accounts[0].addr: {Balance: big.NewInt(1000000000)}, accounts[1].addr: {Balance: big.NewInt(1000000000)}, accounts[2].addr: {Balance: big.NewInt(1000000000)}}, 10000000)
defer contractBackend.Close() defer contractBackend.Close()
transactOpts := bind.NewKeyedTransactor(accounts[0].key) transactOpts, _ := bind.NewKeyedTransactorWithChainID(accounts[0].key, big.NewInt(1337))
// 3 trusted signers, threshold 2 // 3 trusted signers, threshold 2
contractAddr, _, c, err := contract.DeployCheckpointOracle(transactOpts, contractBackend, []common.Address{accounts[0].addr, accounts[1].addr, accounts[2].addr}, sectionSize, processConfirms, big.NewInt(2)) contractAddr, _, c, err := contract.DeployCheckpointOracle(transactOpts, contractBackend, []common.Address{accounts[0].addr, accounts[1].addr, accounts[2].addr}, sectionSize, processConfirms, big.NewInt(2))

@ -80,7 +80,8 @@ func testCheckpointSyncing(t *testing.T, protocol int, syncMode int) {
data := append([]byte{0x19, 0x00}, append(registrarAddr.Bytes(), append([]byte{0, 0, 0, 0, 0, 0, 0, 0}, cp.Hash().Bytes()...)...)...) data := append([]byte{0x19, 0x00}, append(registrarAddr.Bytes(), append([]byte{0, 0, 0, 0, 0, 0, 0, 0}, cp.Hash().Bytes()...)...)...)
sig, _ := crypto.Sign(crypto.Keccak256(data), signerKey) sig, _ := crypto.Sign(crypto.Keccak256(data), signerKey)
sig[64] += 27 // Transform V from 0/1 to 27/28 according to the yellow paper sig[64] += 27 // Transform V from 0/1 to 27/28 according to the yellow paper
if _, err := server.handler.server.oracle.Contract().RegisterCheckpoint(bind.NewKeyedTransactor(signerKey), cp.SectionIndex, cp.Hash().Bytes(), new(big.Int).Sub(header.Number, big.NewInt(1)), header.ParentHash, [][]byte{sig}); err != nil { auth, _ := bind.NewKeyedTransactorWithChainID(signerKey, big.NewInt(1337))
if _, err := server.handler.server.oracle.Contract().RegisterCheckpoint(auth, cp.SectionIndex, cp.Hash().Bytes(), new(big.Int).Sub(header.Number, big.NewInt(1)), header.ParentHash, [][]byte{sig}); err != nil {
t.Error("register checkpoint failed", err) t.Error("register checkpoint failed", err)
} }
server.backend.Commit() server.backend.Commit()
@ -162,7 +163,8 @@ func testMissOracleBackend(t *testing.T, hasCheckpoint bool) {
data := append([]byte{0x19, 0x00}, append(registrarAddr.Bytes(), append([]byte{0, 0, 0, 0, 0, 0, 0, 0}, cp.Hash().Bytes()...)...)...) data := append([]byte{0x19, 0x00}, append(registrarAddr.Bytes(), append([]byte{0, 0, 0, 0, 0, 0, 0, 0}, cp.Hash().Bytes()...)...)...)
sig, _ := crypto.Sign(crypto.Keccak256(data), signerKey) sig, _ := crypto.Sign(crypto.Keccak256(data), signerKey)
sig[64] += 27 // Transform V from 0/1 to 27/28 according to the yellow paper sig[64] += 27 // Transform V from 0/1 to 27/28 according to the yellow paper
if _, err := server.handler.server.oracle.Contract().RegisterCheckpoint(bind.NewKeyedTransactor(signerKey), cp.SectionIndex, cp.Hash().Bytes(), new(big.Int).Sub(header.Number, big.NewInt(1)), header.ParentHash, [][]byte{sig}); err != nil { auth, _ := bind.NewKeyedTransactorWithChainID(signerKey, big.NewInt(1337))
if _, err := server.handler.server.oracle.Contract().RegisterCheckpoint(auth, cp.SectionIndex, cp.Hash().Bytes(), new(big.Int).Sub(header.Number, big.NewInt(1)), header.ParentHash, [][]byte{sig}); err != nil {
t.Error("register checkpoint failed", err) t.Error("register checkpoint failed", err)
} }
server.backend.Commit() server.backend.Commit()

@ -112,7 +112,8 @@ func prepare(n int, backend *backends.SimulatedBackend) {
switch i { switch i {
case 0: case 0:
// deploy checkpoint contract // deploy checkpoint contract
registrarAddr, _, _, _ = contract.DeployCheckpointOracle(bind.NewKeyedTransactor(bankKey), backend, []common.Address{signerAddr}, sectionSize, processConfirms, big.NewInt(1)) auth, _ := bind.NewKeyedTransactorWithChainID(bankKey, big.NewInt(1337))
registrarAddr, _, _, _ = contract.DeployCheckpointOracle(auth, backend, []common.Address{signerAddr}, sectionSize, processConfirms, big.NewInt(1))
// bankUser transfers some ether to user1 // bankUser transfers some ether to user1
nonce, _ := backend.PendingNonceAt(ctx, bankAddr) nonce, _ := backend.PendingNonceAt(ctx, bankAddr)
tx, _ := types.SignTx(types.NewTransaction(nonce, userAddr1, big.NewInt(10000), params.TxGas, nil, nil), signer, bankKey) tx, _ := types.SignTx(types.NewTransaction(nonce, userAddr1, big.NewInt(10000), params.TxGas, nil, nil), signer, bankKey)

@ -40,7 +40,7 @@ type MobileSigner struct {
} }
func (s *MobileSigner) Sign(addr *Address, unsignedTx *Transaction) (signedTx *Transaction, _ error) { func (s *MobileSigner) Sign(addr *Address, unsignedTx *Transaction) (signedTx *Transaction, _ error) {
sig, err := s.sign(types.EIP155Signer{}, addr.address, unsignedTx.tx) sig, err := s.sign(addr.address, unsignedTx.tx)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -82,12 +82,16 @@ func NewTransactOpts() *TransactOpts {
// NewKeyedTransactOpts is a utility method to easily create a transaction signer // NewKeyedTransactOpts is a utility method to easily create a transaction signer
// from a single private key. // from a single private key.
func NewKeyedTransactOpts(keyJson []byte, passphrase string) (*TransactOpts, error) { func NewKeyedTransactOpts(keyJson []byte, passphrase string, chainID *big.Int) (*TransactOpts, error) {
key, err := keystore.DecryptKey(keyJson, passphrase) key, err := keystore.DecryptKey(keyJson, passphrase)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return &TransactOpts{*bind.NewKeyedTransactor(key.PrivateKey)}, nil auth, err := bind.NewKeyedTransactorWithChainID(key.PrivateKey, chainID)
if err != nil {
return nil, err
}
return &TransactOpts{*auth}, nil
} }
func (opts *TransactOpts) GetFrom() *Address { return &Address{opts.opts.From} } func (opts *TransactOpts) GetFrom() *Address { return &Address{opts.opts.From} }
@ -106,7 +110,7 @@ func (opts *TransactOpts) GetGasLimit() int64 { return int64(opts.opts.GasLimi
func (opts *TransactOpts) SetFrom(from *Address) { opts.opts.From = from.address } func (opts *TransactOpts) SetFrom(from *Address) { opts.opts.From = from.address }
func (opts *TransactOpts) SetNonce(nonce int64) { opts.opts.Nonce = big.NewInt(nonce) } func (opts *TransactOpts) SetNonce(nonce int64) { opts.opts.Nonce = big.NewInt(nonce) }
func (opts *TransactOpts) SetSigner(s Signer) { func (opts *TransactOpts) SetSigner(s Signer) {
opts.opts.Signer = func(signer types.Signer, addr common.Address, tx *types.Transaction) (*types.Transaction, error) { opts.opts.Signer = func(addr common.Address, tx *types.Transaction) (*types.Transaction, error) {
sig, err := s.Sign(&Address{addr}, &Transaction{tx}) sig, err := s.Sign(&Address{addr}, &Transaction{tx})
if err != nil { if err != nil {
return nil, err return nil, err