diff --git a/cmd/geth/main.go b/cmd/geth/main.go index 3428bb4cf..a05bb4db5 100644 --- a/cmd/geth/main.go +++ b/cmd/geth/main.go @@ -461,22 +461,7 @@ func execJSFiles(ctx *cli.Context) { func unlockAccount(ctx *cli.Context, am *accounts.Manager, addr string, i int) (addrHex, auth string) { var err error - // Load startup keys. XXX we are going to need a different format - - if !((len(addr) == 40) || (len(addr) == 42)) { // with or without 0x - var index int - index, err = strconv.Atoi(addr) - if err != nil { - utils.Fatalf("Invalid account address '%s'", addr) - } - - addrHex, err = am.AddressByIndex(index) - if err != nil { - utils.Fatalf("%v", err) - } - } else { - addrHex = addr - } + addrHex = utils.ParamToAddress(addr, am) // Attempt to unlock the account 3 times attempts := 3 for tries := 0; tries < attempts; tries++ { diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index 20d3543d6..aaf569271 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -9,6 +9,7 @@ import ( "os" "path/filepath" "runtime" + "strconv" "github.com/ethereum/go-ethereum/metrics" @@ -122,8 +123,8 @@ var ( } EtherbaseFlag = cli.StringFlag{ Name: "etherbase", - Usage: "Public address for block mining rewards. By default the address of your primary account is used", - Value: "primary", + Usage: "Public address for block mining rewards. By default the address first created is used", + Value: "0", } GasPriceFlag = cli.StringFlag{ Name: "gasprice", @@ -351,6 +352,8 @@ func MakeEthConfig(clientID, version string, ctx *cli.Context) *eth.Config { if len(customName) > 0 { clientID += "/" + customName } + am := MakeAccountManager(ctx) + return ð.Config{ Name: common.MakeName(clientID, version), DataDir: ctx.GlobalString(DataDirFlag.Name), @@ -361,9 +364,9 @@ func MakeEthConfig(clientID, version string, ctx *cli.Context) *eth.Config { LogFile: ctx.GlobalString(LogFileFlag.Name), Verbosity: ctx.GlobalInt(VerbosityFlag.Name), LogJSON: ctx.GlobalString(LogJSONFlag.Name), - Etherbase: ctx.GlobalString(EtherbaseFlag.Name), + Etherbase: common.HexToAddress(ParamToAddress(ctx.GlobalString(EtherbaseFlag.Name), am)), MinerThreads: ctx.GlobalInt(MinerThreadsFlag.Name), - AccountManager: MakeAccountManager(ctx), + AccountManager: am, VmDebug: ctx.GlobalBool(VMDebugFlag.Name), MaxPeers: ctx.GlobalInt(MaxPeersFlag.Name), MaxPendingPeers: ctx.GlobalInt(MaxPendingPeersFlag.Name), @@ -488,3 +491,20 @@ func StartPProf(ctx *cli.Context) { log.Println(http.ListenAndServe(address, nil)) }() } + +func ParamToAddress(addr string, am *accounts.Manager) (addrHex string) { + if !((len(addr) == 40) || (len(addr) == 42)) { // with or without 0x + index, err := strconv.Atoi(addr) + if err != nil { + Fatalf("Invalid account address '%s'", addr) + } + + addrHex, err = am.AddressByIndex(index) + if err != nil { + Fatalf("%v", err) + } + } else { + addrHex = addr + } + return +} diff --git a/eth/backend.go b/eth/backend.go index 38e06bcf8..9f7a297f1 100644 --- a/eth/backend.go +++ b/eth/backend.go @@ -88,7 +88,7 @@ type Config struct { Shh bool Dial bool - Etherbase string + Etherbase common.Address GasPrice *big.Int MinerThreads int AccountManager *accounts.Manager @@ -324,7 +324,7 @@ func New(config *Config) (*Ethereum, error) { eventMux: &event.TypeMux{}, accountManager: config.AccountManager, DataDir: config.DataDir, - etherbase: common.HexToAddress(config.Etherbase), + etherbase: config.Etherbase, clientVersion: config.Name, // TODO should separate from Name netVersionId: config.NetworkId, NatSpec: config.NatSpec, @@ -480,6 +480,12 @@ func (s *Ethereum) Etherbase() (eb common.Address, err error) { return } +// set in js console via admin interface or wrapper from cli flags +func (self *Ethereum) SetEtherbase(etherbase common.Address) { + self.etherbase = etherbase + self.miner.SetEtherbase(etherbase) +} + func (s *Ethereum) StopMining() { s.miner.Stop() } func (s *Ethereum) IsMining() bool { return s.miner.Mining() } func (s *Ethereum) Miner() *miner.Miner { return s.miner } diff --git a/miner/miner.go b/miner/miner.go index 7f73f3ee8..83f7c4503 100644 --- a/miner/miner.go +++ b/miner/miner.go @@ -137,3 +137,8 @@ func (self *Miner) PendingState() *state.StateDB { func (self *Miner) PendingBlock() *types.Block { return self.worker.pendingBlock() } + +func (self *Miner) SetEtherbase(addr common.Address) { + self.coinbase = addr + self.worker.setEtherbase(addr) +} diff --git a/miner/worker.go b/miner/worker.go index 840609721..7be41118c 100644 --- a/miner/worker.go +++ b/miner/worker.go @@ -124,6 +124,12 @@ func newWorker(coinbase common.Address, eth core.Backend) *worker { return worker } +func (self *worker) setEtherbase(addr common.Address) { + self.mu.Lock() + defer self.mu.Unlock() + self.coinbase = addr +} + func (self *worker) pendingState() *state.StateDB { self.currentMu.Lock() defer self.currentMu.Unlock() diff --git a/rpc/api/miner.go b/rpc/api/miner.go index 7a84cb9ae..8d4646a5c 100644 --- a/rpc/api/miner.go +++ b/rpc/api/miner.go @@ -19,6 +19,7 @@ var ( "miner_makeDAG": (*minerApi).MakeDAG, "miner_setExtra": (*minerApi).SetExtra, "miner_setGasPrice": (*minerApi).SetGasPrice, + "miner_setEtherbase": (*minerApi).SetEtherbase, "miner_startAutoDAG": (*minerApi).StartAutoDAG, "miner_start": (*minerApi).StartMiner, "miner_stopAutoDAG": (*minerApi).StopAutoDAG, @@ -119,6 +120,15 @@ func (self *minerApi) SetGasPrice(req *shared.Request) (interface{}, error) { return true, nil } +func (self *minerApi) SetEtherbase(req *shared.Request) (interface{}, error) { + args := new(SetEtherbaseArgs) + if err := self.codec.Decode(req.Params, &args); err != nil { + return false, err + } + self.ethereum.SetEtherbase(args.Etherbase) + return nil, nil +} + func (self *minerApi) StartAutoDAG(req *shared.Request) (interface{}, error) { self.ethereum.StartAutoDAG() return true, nil diff --git a/rpc/api/miner_args.go b/rpc/api/miner_args.go index 7b0560c16..9da3b95ad 100644 --- a/rpc/api/miner_args.go +++ b/rpc/api/miner_args.go @@ -5,6 +5,7 @@ import ( "math/big" + "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/rpc/shared" ) @@ -76,6 +77,31 @@ func (args *GasPriceArgs) UnmarshalJSON(b []byte) (err error) { return shared.NewInvalidTypeError("Price", "not a string") } +type SetEtherbaseArgs struct { + Etherbase common.Address +} + +func (args *SetEtherbaseArgs) UnmarshalJSON(b []byte) (err error) { + var obj []interface{} + if err := json.Unmarshal(b, &obj); err != nil { + return shared.NewDecodeParamError(err.Error()) + } + + if len(obj) < 1 { + return shared.NewInsufficientParamsError(len(obj), 1) + } + + if addr, ok := obj[0].(string); ok { + args.Etherbase = common.HexToAddress(addr) + if (args.Etherbase == common.Address{}) { + return shared.NewInvalidTypeError("Etherbase", "not a valid address") + } + return nil + } + + return shared.NewInvalidTypeError("Etherbase", "not a string") +} + type MakeDAGArgs struct { BlockNumber int64 } diff --git a/rpc/api/miner_js.go b/rpc/api/miner_js.go index 8861a177a..c205f6712 100644 --- a/rpc/api/miner_js.go +++ b/rpc/api/miner_js.go @@ -17,6 +17,13 @@ web3._extend({ params: 1, inputFormatter: [null] }), + new web3._extend.Method({ + name: 'setEtherbase', + call: 'miner_setEtherbase', + params: 1, + inputFormatter: [web3._extend.formatters.formatInputInt], + outputFormatter: web3._extend.formatters.formatOutputBool + }), new web3._extend.Method({ name: 'setExtra', call: 'miner_setExtra', diff --git a/tests/block_test_util.go b/tests/block_test_util.go index 3b20da492..459e2baee 100644 --- a/tests/block_test_util.go +++ b/tests/block_test_util.go @@ -180,7 +180,7 @@ func (test *BlockTest) makeEthConfig() *eth.Config { return ð.Config{ DataDir: common.DefaultDataDir(), Verbosity: 5, - Etherbase: "primary", + Etherbase: common.Address{}, AccountManager: accounts.NewManager(ks), NewDB: func(path string) (common.Database, error) { return ethdb.NewMemDatabase() }, } diff --git a/tests/state_test_util.go b/tests/state_test_util.go index 7f1a22ac0..dbbd08729 100644 --- a/tests/state_test_util.go +++ b/tests/state_test_util.go @@ -2,6 +2,7 @@ package tests import ( "bytes" + "encoding/hex" "fmt" "io" "math/big" @@ -147,13 +148,12 @@ func runStateTest(test VmTest) error { func RunState(statedb *state.StateDB, env, tx map[string]string) ([]byte, state.Logs, *big.Int, error) { var ( - keyPair, _ = crypto.NewKeyPairFromSec([]byte(common.Hex2Bytes(tx["secretKey"]))) - data = common.FromHex(tx["data"]) - gas = common.Big(tx["gasLimit"]) - price = common.Big(tx["gasPrice"]) - value = common.Big(tx["value"]) - nonce = common.Big(tx["nonce"]).Uint64() - caddr = common.HexToAddress(env["currentCoinbase"]) + data = common.FromHex(tx["data"]) + gas = common.Big(tx["gasLimit"]) + price = common.Big(tx["gasPrice"]) + value = common.Big(tx["value"]) + nonce = common.Big(tx["nonce"]).Uint64() + caddr = common.HexToAddress(env["currentCoinbase"]) ) var to *common.Address @@ -168,9 +168,11 @@ func RunState(statedb *state.StateDB, env, tx map[string]string) ([]byte, state. coinbase := statedb.GetOrNewStateObject(caddr) coinbase.SetGasLimit(common.Big(env["currentGasLimit"])) - message := NewMessage(common.BytesToAddress(keyPair.Address()), to, data, value, gas, price, nonce) + key, _ := hex.DecodeString(tx["secretKey"]) + addr := crypto.PubkeyToAddress(crypto.ToECDSA(key).PublicKey) + message := NewMessage(addr, to, data, value, gas, price, nonce) vmenv := NewEnvFromMap(statedb, env, tx) - vmenv.origin = common.BytesToAddress(keyPair.Address()) + vmenv.origin = addr ret, _, err := core.ApplyMessage(vmenv, message, coinbase) if core.IsNonceErr(err) || core.IsInvalidTxErr(err) || state.IsGasLimitErr(err) { statedb.Set(snapshot) diff --git a/xeth/types.go b/xeth/types.go index cc06a8dcd..35ed2d308 100644 --- a/xeth/types.go +++ b/xeth/types.go @@ -168,16 +168,6 @@ func (self *Transaction) ToString() string { return self.ref.String() } -type Key struct { - Address string `json:"address"` - PrivateKey string `json:"privateKey"` - PublicKey string `json:"publicKey"` -} - -func NewKey(key *crypto.KeyPair) *Key { - return &Key{common.ToHex(key.Address()), common.ToHex(key.PrivateKey), common.ToHex(key.PublicKey)} -} - type PReceipt struct { CreatedContract bool `json:"createdContract"` Address string `json:"address"` diff --git a/xeth/xeth.go b/xeth/xeth.go index a3923436a..8e3200ad5 100644 --- a/xeth/xeth.go +++ b/xeth/xeth.go @@ -476,15 +476,6 @@ func (self *XEth) IsContract(address string) bool { return len(self.State().SafeGet(address).Code()) > 0 } -func (self *XEth) SecretToAddress(key string) string { - pair, err := crypto.NewKeyPairFromSec(common.FromHex(key)) - if err != nil { - return "" - } - - return common.ToHex(pair.Address()) -} - func (self *XEth) UninstallFilter(id int) bool { defer self.filterManager.UninstallFilter(id)