rpc/api, xeth: added signTransaction method
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.
This commit is contained in:
parent
9422eec554
commit
6ea05f5a54
@ -26,6 +26,7 @@ import (
|
|||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/common/natspec"
|
"github.com/ethereum/go-ethereum/common/natspec"
|
||||||
"github.com/ethereum/go-ethereum/eth"
|
"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/codec"
|
||||||
"github.com/ethereum/go-ethereum/rpc/shared"
|
"github.com/ethereum/go-ethereum/rpc/shared"
|
||||||
"github.com/ethereum/go-ethereum/xeth"
|
"github.com/ethereum/go-ethereum/xeth"
|
||||||
@ -70,8 +71,10 @@ var (
|
|||||||
"eth_getCode": (*ethApi).GetData,
|
"eth_getCode": (*ethApi).GetData,
|
||||||
"eth_getNatSpec": (*ethApi).GetNatSpec,
|
"eth_getNatSpec": (*ethApi).GetNatSpec,
|
||||||
"eth_sign": (*ethApi).Sign,
|
"eth_sign": (*ethApi).Sign,
|
||||||
"eth_sendRawTransaction": (*ethApi).SendRawTransaction,
|
"eth_sendRawTransaction": (*ethApi).SubmitTransaction,
|
||||||
|
"eth_submitTransaction": (*ethApi).SubmitTransaction,
|
||||||
"eth_sendTransaction": (*ethApi).SendTransaction,
|
"eth_sendTransaction": (*ethApi).SendTransaction,
|
||||||
|
"eth_signTransaction": (*ethApi).SignTransaction,
|
||||||
"eth_transact": (*ethApi).SendTransaction,
|
"eth_transact": (*ethApi).SendTransaction,
|
||||||
"eth_estimateGas": (*ethApi).EstimateGas,
|
"eth_estimateGas": (*ethApi).EstimateGas,
|
||||||
"eth_call": (*ethApi).Call,
|
"eth_call": (*ethApi).Call,
|
||||||
@ -285,7 +288,7 @@ func (self *ethApi) Sign(req *shared.Request) (interface{}, error) {
|
|||||||
return v, nil
|
return v, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *ethApi) SendRawTransaction(req *shared.Request) (interface{}, error) {
|
func (self *ethApi) SubmitTransaction(req *shared.Request) (interface{}, error) {
|
||||||
args := new(NewDataArgs)
|
args := new(NewDataArgs)
|
||||||
if err := self.codec.Decode(req.Params, &args); err != nil {
|
if err := self.codec.Decode(req.Params, &args); err != nil {
|
||||||
return nil, shared.NewDecodeParamError(err.Error())
|
return nil, shared.NewDecodeParamError(err.Error())
|
||||||
@ -298,6 +301,45 @@ func (self *ethApi) SendRawTransaction(req *shared.Request) (interface{}, error)
|
|||||||
return v, nil
|
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) {
|
func (self *ethApi) SendTransaction(req *shared.Request) (interface{}, error) {
|
||||||
args := new(NewTxArgs)
|
args := new(NewTxArgs)
|
||||||
if err := self.codec.Decode(req.Params, &args); err != nil {
|
if err := self.codec.Decode(req.Params, &args); err != nil {
|
||||||
|
@ -36,11 +36,23 @@ web3._extend({
|
|||||||
params: 3,
|
params: 3,
|
||||||
inputFormatter: [web3._extend.formatters.inputTransactionFormatter, web3._extend.utils.fromDecimal, web3._extend.utils.fromDecimal]
|
inputFormatter: [web3._extend.formatters.inputTransactionFormatter, web3._extend.utils.fromDecimal, web3._extend.utils.fromDecimal]
|
||||||
}),
|
}),
|
||||||
new web3._extend.Method({
|
new web3._extend.Method({
|
||||||
name: 'getNatSpec',
|
name: 'getNatSpec',
|
||||||
call: 'eth_getNatSpec',
|
call: 'eth_getNatSpec',
|
||||||
params: 1,
|
params: 1,
|
||||||
inputFormatter: [web3._extend.formatters.inputTransactionFormatter]
|
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:
|
properties:
|
||||||
|
54
xeth/xeth.go
54
xeth/xeth.go
@ -912,6 +912,60 @@ func (self *XEth) Frontend() Frontend {
|
|||||||
return self.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) {
|
func (self *XEth) Transact(fromStr, toStr, nonceStr, valueStr, gasStr, gasPriceStr, codeStr string) (string, error) {
|
||||||
|
|
||||||
// this minimalistic recoding is enough (works for natspec.js)
|
// this minimalistic recoding is enough (works for natspec.js)
|
||||||
|
Loading…
Reference in New Issue
Block a user