Skip to content

Commit

Permalink
rpc/api, xeth: added signTransaction method
Browse files Browse the repository at this point in the history
SignTransaction creates a transaction but does submit it to the
network. SignTransaction returns a structure which includes the
transaction object details as well as the RLP encoded transaction that
could possibly be submitted by the SendRawTransaction method.
  • Loading branch information
obscuren committed Nov 17, 2015
1 parent 9422eec commit 6ea05f5
Show file tree
Hide file tree
Showing 3 changed files with 115 additions and 7 deletions.
46 changes: 44 additions & 2 deletions rpc/api/eth.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/natspec"
"github.com/ethereum/go-ethereum/eth"
"github.com/ethereum/go-ethereum/rlp"
"github.com/ethereum/go-ethereum/rpc/codec"
"github.com/ethereum/go-ethereum/rpc/shared"
"github.com/ethereum/go-ethereum/xeth"
Expand Down Expand Up @@ -70,8 +71,10 @@ var (
"eth_getCode": (*ethApi).GetData,
"eth_getNatSpec": (*ethApi).GetNatSpec,
"eth_sign": (*ethApi).Sign,
"eth_sendRawTransaction": (*ethApi).SendRawTransaction,
"eth_sendRawTransaction": (*ethApi).SubmitTransaction,
"eth_submitTransaction": (*ethApi).SubmitTransaction,
"eth_sendTransaction": (*ethApi).SendTransaction,
"eth_signTransaction": (*ethApi).SignTransaction,
"eth_transact": (*ethApi).SendTransaction,
"eth_estimateGas": (*ethApi).EstimateGas,
"eth_call": (*ethApi).Call,
Expand Down Expand Up @@ -285,7 +288,7 @@ func (self *ethApi) Sign(req *shared.Request) (interface{}, error) {
return v, nil
}

func (self *ethApi) SendRawTransaction(req *shared.Request) (interface{}, error) {
func (self *ethApi) SubmitTransaction(req *shared.Request) (interface{}, error) {
args := new(NewDataArgs)
if err := self.codec.Decode(req.Params, &args); err != nil {
return nil, shared.NewDecodeParamError(err.Error())
Expand All @@ -298,6 +301,45 @@ func (self *ethApi) SendRawTransaction(req *shared.Request) (interface{}, error)
return v, nil
}

// JsonTransaction is returned as response by the JSON RPC. It contains the
// signed RLP encoded transaction as Raw and the signed transaction object as Tx.
type JsonTransaction struct {
Raw string `json:"raw"`
Tx *tx `json:"tx"`
}

func (self *ethApi) SignTransaction(req *shared.Request) (interface{}, error) {
args := new(NewTxArgs)
if err := self.codec.Decode(req.Params, &args); err != nil {
return nil, shared.NewDecodeParamError(err.Error())
}

// nonce may be nil ("guess" mode)
var nonce string
if args.Nonce != nil {
nonce = args.Nonce.String()
}

var gas, price string
if args.Gas != nil {
gas = args.Gas.String()
}
if args.GasPrice != nil {
price = args.GasPrice.String()
}
tx, err := self.xeth.SignTransaction(args.From, args.To, nonce, args.Value.String(), gas, price, args.Data)
if err != nil {
return nil, err
}

data, err := rlp.EncodeToBytes(tx)
if err != nil {
return nil, err
}

return JsonTransaction{"0x" + common.Bytes2Hex(data), newTx(tx)}, nil
}

func (self *ethApi) SendTransaction(req *shared.Request) (interface{}, error) {
args := new(NewTxArgs)
if err := self.codec.Decode(req.Params, &args); err != nil {
Expand Down
22 changes: 17 additions & 5 deletions rpc/api/eth_js.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,23 @@ web3._extend({
params: 3,
inputFormatter: [web3._extend.formatters.inputTransactionFormatter, web3._extend.utils.fromDecimal, web3._extend.utils.fromDecimal]
}),
new web3._extend.Method({
name: 'getNatSpec',
call: 'eth_getNatSpec',
params: 1,
inputFormatter: [web3._extend.formatters.inputTransactionFormatter]
new web3._extend.Method({
name: 'getNatSpec',
call: 'eth_getNatSpec',
params: 1,
inputFormatter: [web3._extend.formatters.inputTransactionFormatter]
}),
new web3._extend.Method({
name: 'signTransaction',
call: 'eth_signTransaction',
params: 1,
inputFormatter: [web3._extend.formatters.inputTransactionFormatter]
}),
new web3._extend.Method({
name: 'submitTransaction',
call: 'eth_submitTransaction',
params: 1,
inputFormatter: [web3._extend.formatters.inputTransactionFormatter]
})
],
properties:
Expand Down
54 changes: 54 additions & 0 deletions xeth/xeth.go
Original file line number Diff line number Diff line change
Expand Up @@ -912,6 +912,60 @@ func (self *XEth) Frontend() Frontend {
return self.frontend
}

func (self *XEth) SignTransaction(fromStr, toStr, nonceStr, valueStr, gasStr, gasPriceStr, codeStr string) (*types.Transaction, error) {
if len(toStr) > 0 && toStr != "0x" && !isAddress(toStr) {
return nil, errors.New("Invalid address")
}

var (
from = common.HexToAddress(fromStr)
to = common.HexToAddress(toStr)
value = common.Big(valueStr)
gas *big.Int
price *big.Int
data []byte
contractCreation bool
)

if len(gasStr) == 0 {
gas = DefaultGas()
} else {
gas = common.Big(gasStr)
}

if len(gasPriceStr) == 0 {
price = self.DefaultGasPrice()
} else {
price = common.Big(gasPriceStr)
}

data = common.FromHex(codeStr)
if len(toStr) == 0 {
contractCreation = true
}

var nonce uint64
if len(nonceStr) != 0 {
nonce = common.Big(nonceStr).Uint64()
} else {
state := self.backend.TxPool().State()
nonce = state.GetNonce(from)
}
var tx *types.Transaction
if contractCreation {
tx = types.NewContractCreation(nonce, value, gas, price, data)
} else {
tx = types.NewTransaction(nonce, to, value, gas, price, data)
}

signed, err := self.sign(tx, from, false)
if err != nil {
return nil, err
}

return signed, nil
}

func (self *XEth) Transact(fromStr, toStr, nonceStr, valueStr, gasStr, gasPriceStr, codeStr string) (string, error) {

// this minimalistic recoding is enough (works for natspec.js)
Expand Down

0 comments on commit 6ea05f5

Please sign in to comment.