Skip to content

Commit 6bb29ae

Browse files
committed
Merge pull request #1666 from obscuren/create-transaction
rpc/api, xeth: added signTransaction method
2 parents 314c031 + 6ea05f5 commit 6bb29ae

File tree

3 files changed

+115
-7
lines changed

3 files changed

+115
-7
lines changed

rpc/api/eth.go

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import (
2626
"github.com/ethereum/go-ethereum/common"
2727
"github.com/ethereum/go-ethereum/common/natspec"
2828
"github.com/ethereum/go-ethereum/eth"
29+
"github.com/ethereum/go-ethereum/rlp"
2930
"github.com/ethereum/go-ethereum/rpc/codec"
3031
"github.com/ethereum/go-ethereum/rpc/shared"
3132
"github.com/ethereum/go-ethereum/xeth"
@@ -70,8 +71,10 @@ var (
7071
"eth_getCode": (*ethApi).GetData,
7172
"eth_getNatSpec": (*ethApi).GetNatSpec,
7273
"eth_sign": (*ethApi).Sign,
73-
"eth_sendRawTransaction": (*ethApi).SendRawTransaction,
74+
"eth_sendRawTransaction": (*ethApi).SubmitTransaction,
75+
"eth_submitTransaction": (*ethApi).SubmitTransaction,
7476
"eth_sendTransaction": (*ethApi).SendTransaction,
77+
"eth_signTransaction": (*ethApi).SignTransaction,
7578
"eth_transact": (*ethApi).SendTransaction,
7679
"eth_estimateGas": (*ethApi).EstimateGas,
7780
"eth_call": (*ethApi).Call,
@@ -285,7 +288,7 @@ func (self *ethApi) Sign(req *shared.Request) (interface{}, error) {
285288
return v, nil
286289
}
287290

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

304+
// JsonTransaction is returned as response by the JSON RPC. It contains the
305+
// signed RLP encoded transaction as Raw and the signed transaction object as Tx.
306+
type JsonTransaction struct {
307+
Raw string `json:"raw"`
308+
Tx *tx `json:"tx"`
309+
}
310+
311+
func (self *ethApi) SignTransaction(req *shared.Request) (interface{}, error) {
312+
args := new(NewTxArgs)
313+
if err := self.codec.Decode(req.Params, &args); err != nil {
314+
return nil, shared.NewDecodeParamError(err.Error())
315+
}
316+
317+
// nonce may be nil ("guess" mode)
318+
var nonce string
319+
if args.Nonce != nil {
320+
nonce = args.Nonce.String()
321+
}
322+
323+
var gas, price string
324+
if args.Gas != nil {
325+
gas = args.Gas.String()
326+
}
327+
if args.GasPrice != nil {
328+
price = args.GasPrice.String()
329+
}
330+
tx, err := self.xeth.SignTransaction(args.From, args.To, nonce, args.Value.String(), gas, price, args.Data)
331+
if err != nil {
332+
return nil, err
333+
}
334+
335+
data, err := rlp.EncodeToBytes(tx)
336+
if err != nil {
337+
return nil, err
338+
}
339+
340+
return JsonTransaction{"0x" + common.Bytes2Hex(data), newTx(tx)}, nil
341+
}
342+
301343
func (self *ethApi) SendTransaction(req *shared.Request) (interface{}, error) {
302344
args := new(NewTxArgs)
303345
if err := self.codec.Decode(req.Params, &args); err != nil {

rpc/api/eth_js.go

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,23 @@ web3._extend({
3636
params: 3,
3737
inputFormatter: [web3._extend.formatters.inputTransactionFormatter, web3._extend.utils.fromDecimal, web3._extend.utils.fromDecimal]
3838
}),
39-
new web3._extend.Method({
40-
name: 'getNatSpec',
41-
call: 'eth_getNatSpec',
42-
params: 1,
43-
inputFormatter: [web3._extend.formatters.inputTransactionFormatter]
39+
new web3._extend.Method({
40+
name: 'getNatSpec',
41+
call: 'eth_getNatSpec',
42+
params: 1,
43+
inputFormatter: [web3._extend.formatters.inputTransactionFormatter]
44+
}),
45+
new web3._extend.Method({
46+
name: 'signTransaction',
47+
call: 'eth_signTransaction',
48+
params: 1,
49+
inputFormatter: [web3._extend.formatters.inputTransactionFormatter]
50+
}),
51+
new web3._extend.Method({
52+
name: 'submitTransaction',
53+
call: 'eth_submitTransaction',
54+
params: 1,
55+
inputFormatter: [web3._extend.formatters.inputTransactionFormatter]
4456
})
4557
],
4658
properties:

xeth/xeth.go

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -879,6 +879,60 @@ func (self *XEth) Frontend() Frontend {
879879
return self.frontend
880880
}
881881

882+
func (self *XEth) SignTransaction(fromStr, toStr, nonceStr, valueStr, gasStr, gasPriceStr, codeStr string) (*types.Transaction, error) {
883+
if len(toStr) > 0 && toStr != "0x" && !isAddress(toStr) {
884+
return nil, errors.New("Invalid address")
885+
}
886+
887+
var (
888+
from = common.HexToAddress(fromStr)
889+
to = common.HexToAddress(toStr)
890+
value = common.Big(valueStr)
891+
gas *big.Int
892+
price *big.Int
893+
data []byte
894+
contractCreation bool
895+
)
896+
897+
if len(gasStr) == 0 {
898+
gas = DefaultGas()
899+
} else {
900+
gas = common.Big(gasStr)
901+
}
902+
903+
if len(gasPriceStr) == 0 {
904+
price = self.DefaultGasPrice()
905+
} else {
906+
price = common.Big(gasPriceStr)
907+
}
908+
909+
data = common.FromHex(codeStr)
910+
if len(toStr) == 0 {
911+
contractCreation = true
912+
}
913+
914+
var nonce uint64
915+
if len(nonceStr) != 0 {
916+
nonce = common.Big(nonceStr).Uint64()
917+
} else {
918+
state := self.backend.TxPool().State()
919+
nonce = state.GetNonce(from)
920+
}
921+
var tx *types.Transaction
922+
if contractCreation {
923+
tx = types.NewContractCreation(nonce, value, gas, price, data)
924+
} else {
925+
tx = types.NewTransaction(nonce, to, value, gas, price, data)
926+
}
927+
928+
signed, err := self.sign(tx, from, false)
929+
if err != nil {
930+
return nil, err
931+
}
932+
933+
return signed, nil
934+
}
935+
882936
func (self *XEth) Transact(fromStr, toStr, nonceStr, valueStr, gasStr, gasPriceStr, codeStr string) (string, error) {
883937

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

0 commit comments

Comments
 (0)