Add first take on new transact and wallet creation RPC calls

This commit is contained in:
Gustav Simonsson 2015-02-15 00:39:50 +01:00
parent 988a366a18
commit 4d1a9cb835
7 changed files with 129 additions and 3 deletions

View file

@ -129,6 +129,7 @@ func (tx *Transaction) sender() []byte {
return crypto.Sha3(pubkey[1:])[12:]
}
// TODO: deprecate after new accounts & key stores are integrated
func (tx *Transaction) Sign(privk []byte) error {
sig := tx.Signature(privk)
@ -140,6 +141,13 @@ func (tx *Transaction) Sign(privk []byte) error {
return nil
}
func (tx *Transaction) SetSignatureValues(sig []byte) error {
tx.R = sig[:32]
tx.S = sig[32:64]
tx.V = uint64(sig[64] + 27)
return nil
}
func (tx *Transaction) SignECDSA(key *ecdsa.PrivateKey) error {
return tx.Sign(crypto.FromECDSA(key))
}

View file

@ -5,6 +5,7 @@ import (
"net"
"sync"
"github.com/ethereum/go-ethereum/accounts"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethdb"
@ -54,6 +55,7 @@ type Ethereum struct {
blockProcessor *core.BlockProcessor
txPool *core.TxPool
chainManager *core.ChainManager
accountManager *accounts.AccountManager
blockPool *BlockPool
whisper *whisper.Whisper
@ -90,6 +92,7 @@ func New(config *Config) (*Ethereum, error) {
return nil, fmt.Errorf("Database version mismatch. Protocol(%d / %d). `rm -rf %s`", protov, ProtocolVersion, ethutil.Config.ExecPath+"/database")
}
// TODO: remove keymanager & keyring once accountManager is integrated
// Create new keymanager
var keyManager *crypto.KeyManager
switch config.KeyStore {
@ -121,6 +124,13 @@ func New(config *Config) (*Ethereum, error) {
}
eth.chainManager = core.NewChainManager(db, eth.EventMux())
// TODO: add config flag and case on plain/protected key store
ks := crypto.NewKeyStorePlain(crypto.DefaultDataDir())
am, err := accounts.NewAccountManager(ks)
if err != nil {
return nil, err
}
eth.accountManager = &am
eth.txPool = core.NewTxPool(eth.EventMux())
eth.blockProcessor = core.NewBlockProcessor(db, eth.txPool, eth.chainManager, eth.EventMux())
eth.chainManager.SetProcessor(eth.blockProcessor)
@ -170,6 +180,10 @@ func (s *Ethereum) ChainManager() *core.ChainManager {
return s.chainManager
}
func (s *Ethereum) AccountManager() *accounts.AccountManager {
return s.accountManager
}
func (s *Ethereum) BlockProcessor() *core.BlockProcessor {
return s.blockProcessor
}

View file

@ -37,6 +37,16 @@ type NewTxArgs struct {
Data string `json:"data"`
}
type NewTxArgs2 struct {
From string `json:"from"`
Pass string `json:"pass"`
To string `json:"to"`
Value string `json:"value"`
Gas string `json:"gas"`
GasPrice string `json:"gasPrice"`
Data string `json:"data"`
}
type PushTxArgs struct {
Tx string `json:"tx"`
}

View file

@ -9,7 +9,7 @@
go-ethereum is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.

View file

@ -9,7 +9,7 @@
go-ethereum is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
@ -154,6 +154,20 @@ func (p *EthereumApi) Transact(args *NewTxArgs, reply *interface{}) error {
return nil
}
func (p *EthereumApi) Transact2(args *NewTxArgs2, reply *interface{}) error {
if len(args.Gas) == 0 {
args.Gas = defaultGas
}
if len(args.GasPrice) == 0 {
args.GasPrice = defaultGasPrice
}
result, _ := p.xeth.Transact2(args.From, args.Pass, args.To, args.Value, args.Gas, args.GasPrice, args.Data)
*reply = result
return nil
}
func (p *EthereumApi) Call(args *NewTxArgs, reply *interface{}) error {
result, err := p.xeth.Call( /* TODO specify account */ args.To, args.Value, args.Gas, args.GasPrice, args.Data)
if err != nil {

View file

@ -9,7 +9,7 @@
go-ethereum is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.

View file

@ -8,6 +8,7 @@ import (
"bytes"
"encoding/json"
"github.com/ethereum/go-ethereum/accounts"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
@ -25,6 +26,7 @@ var pipelogger = logger.NewLogger("XETH")
type Backend interface {
BlockProcessor() *core.BlockProcessor
ChainManager() *core.ChainManager
AccountManager() *accounts.AccountManager
TxPool() *core.TxPool
PeerCount() int
IsMining() bool
@ -41,6 +43,7 @@ type XEth struct {
eth Backend
blockProcessor *core.BlockProcessor
chainManager *core.ChainManager
accountManager *accounts.AccountManager
state *State
whisper *Whisper
}
@ -50,6 +53,7 @@ func New(eth Backend) *XEth {
eth: eth,
blockProcessor: eth.BlockProcessor(),
chainManager: eth.ChainManager(),
accountManager: eth.AccountManager(),
whisper: NewWhisper(eth.Whisper()),
}
xeth.state = NewState(xeth)
@ -301,3 +305,79 @@ func (self *XEth) Transact(toStr, valueStr, gasStr, gasPriceStr, codeStr string)
return toHex(tx.Hash()), nil
}
func (self *XEth) Transact2(fromStr, fromPassStr, toStr, valueStr, gasStr, gasPriceStr, codeStr string) (string, error) {
var (
from []byte
to []byte
value = ethutil.NewValue(valueStr)
gas = ethutil.NewValue(gasStr)
price = ethutil.NewValue(gasPriceStr)
data []byte
contractCreation bool
)
from = fromHex(fromStr)
data = fromHex(codeStr)
to = fromHex(toStr)
if len(to) == 0 {
contractCreation = true
}
var tx *types.Transaction
if contractCreation {
tx = types.NewContractCreationTx(value.BigInt(), gas.BigInt(), price.BigInt(), data)
} else {
tx = types.NewTransactionMessage(to, value.BigInt(), gas.BigInt(), price.BigInt(), data)
}
state := self.chainManager.TransState()
nonce := state.GetNonce(from)
tx.SetNonce(nonce)
sig, err := self.accountManager.Sign(from, fromPassStr, tx.Hash())
if err != nil {
return "", err
}
tx.SetSignatureValues(sig)
// Do some pre processing for our "pre" events and hooks
block := self.chainManager.NewBlock(from)
coinbase := state.GetOrNewStateObject(from)
coinbase.SetGasPool(block.GasLimit())
self.blockProcessor.ApplyTransactions(coinbase, state, block, types.Transactions{tx}, true)
err = self.eth.TxPool().Add(tx)
if err != nil {
return "", err
}
state.SetNonce(from, nonce+1)
if contractCreation {
addr := core.AddressFromMessage(tx)
pipelogger.Infof("Contract addr %x\n", addr)
}
if types.IsContractAddr(to) {
return toHex(core.AddressFromMessage(tx)), nil
}
return toHex(tx.Hash()), nil
}
// TODO: clarify what is amount, gas and gas price when creating a new wallet contract?
func (self *XEth) NewWallet(fromStr, fromPassStr, valueStr, gasStr, gasPriceStr, walletContractDataStr string) (newAddrHex string, newWalletContractAddrHex string, err error) {
from := fromHex(fromStr)
newAddr, err := self.accountManager.NewAccount(fromPassStr)
if err != nil {
return "", "", err
}
err = self.accountManager.AssociateContract(from, newAddr)
if err != nil {
return "", "", err
}
// TODO: how to add newAddr as authorised signer to the wallet contract code?
newWalletContractAddrHex, err = self.Transact2(fromStr, fromPassStr, "", valueStr, gasStr, gasPriceStr, walletContractDataStr)
return toHex(newAddr), newWalletContractAddrHex, nil
}