mirror of
https://github.com/kaspanet/kaspad.git
synced 2025-06-07 06:36:46 +00:00
Add support for createrawtransaction RPC command.
This commit is contained in:
parent
405eca4a44
commit
b6b2fd15b3
118
rpcserver.go
118
rpcserver.go
@ -53,7 +53,7 @@ var rpcHandlers = map[string]commandHandler{
|
|||||||
"addnode": handleAddNode,
|
"addnode": handleAddNode,
|
||||||
"backupwallet": handleAskWallet,
|
"backupwallet": handleAskWallet,
|
||||||
"createmultisig": handleAskWallet,
|
"createmultisig": handleAskWallet,
|
||||||
"createrawtransaction": handleUnimplemented,
|
"createrawtransaction": handleCreateRawTransaction,
|
||||||
"debuglevel": handleDebugLevel,
|
"debuglevel": handleDebugLevel,
|
||||||
"decoderawtransaction": handleDecodeRawTransaction,
|
"decoderawtransaction": handleDecodeRawTransaction,
|
||||||
"decodescript": handleUnimplemented,
|
"decodescript": handleUnimplemented,
|
||||||
@ -460,6 +460,108 @@ func handleAddNode(s *rpcServer, cmd btcjson.Cmd) (interface{}, error) {
|
|||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// messageToHex serializes a message to the wire protocol encoding using the
|
||||||
|
// latest protocol version and returns a hex-encoded string of the result.
|
||||||
|
func messageToHex(msg btcwire.Message) (string, error) {
|
||||||
|
var buf bytes.Buffer
|
||||||
|
err := msg.BtcEncode(&buf, btcwire.ProtocolVersion)
|
||||||
|
if err != nil {
|
||||||
|
return "", btcjson.Error{
|
||||||
|
Code: btcjson.ErrInternal.Code,
|
||||||
|
Message: err.Error(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return hex.EncodeToString(buf.Bytes()), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// handleCreateRawTransaction handles createrawtransaction commands.
|
||||||
|
func handleCreateRawTransaction(s *rpcServer, cmd btcjson.Cmd) (interface{}, error) {
|
||||||
|
c := cmd.(*btcjson.CreateRawTransactionCmd)
|
||||||
|
|
||||||
|
// Add all transaction inputs to a new transaction after performing
|
||||||
|
// some validty checks.
|
||||||
|
mtx := btcwire.NewMsgTx()
|
||||||
|
for _, input := range c.Inputs {
|
||||||
|
txHash, err := btcwire.NewShaHashFromStr(input.Txid)
|
||||||
|
if err != nil {
|
||||||
|
return nil, btcjson.ErrDecodeHexString
|
||||||
|
}
|
||||||
|
|
||||||
|
if input.Vout < 0 {
|
||||||
|
return nil, btcjson.Error{
|
||||||
|
Code: btcjson.ErrInvalidParameter.Code,
|
||||||
|
Message: "Invalid parameter, vout must be positive",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
prevOut := btcwire.NewOutPoint(txHash, uint32(input.Vout))
|
||||||
|
txIn := btcwire.NewTxIn(prevOut, []byte{})
|
||||||
|
mtx.AddTxIn(txIn)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add all transaction outputs to the transaction after performing
|
||||||
|
// some validty checks.
|
||||||
|
for encodedAddr, amount := range c.Amounts {
|
||||||
|
// Ensure amount is in the valid range for monetary amounts.
|
||||||
|
if amount <= 0 || amount > btcutil.MaxSatoshi {
|
||||||
|
return nil, btcjson.Error{
|
||||||
|
Code: btcjson.ErrType.Code,
|
||||||
|
Message: "Invalid amount",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decode the provided address.
|
||||||
|
addr, err := btcutil.DecodeAddr(encodedAddr)
|
||||||
|
if err != nil {
|
||||||
|
return nil, btcjson.Error{
|
||||||
|
Code: btcjson.ErrInvalidAddressOrKey.Code,
|
||||||
|
Message: btcjson.ErrInvalidAddressOrKey.Message +
|
||||||
|
": " + err.Error(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure the address is one of the supported types and that
|
||||||
|
// the network encoded with the address matches the network the
|
||||||
|
// server is currently on.
|
||||||
|
net := s.server.btcnet
|
||||||
|
switch addr := addr.(type) {
|
||||||
|
case *btcutil.AddressPubKeyHash:
|
||||||
|
net = addr.Net()
|
||||||
|
case *btcutil.AddressScriptHash:
|
||||||
|
net = addr.Net()
|
||||||
|
default:
|
||||||
|
return nil, btcjson.ErrInvalidAddressOrKey
|
||||||
|
}
|
||||||
|
if net != s.server.btcnet {
|
||||||
|
return nil, btcjson.Error{
|
||||||
|
Code: btcjson.ErrInvalidAddressOrKey.Code,
|
||||||
|
Message: fmt.Sprintf("%s: %q",
|
||||||
|
btcjson.ErrInvalidAddressOrKey.Message,
|
||||||
|
encodedAddr),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a new script which pays to the provided address.
|
||||||
|
pkScript, err := btcscript.PayToAddrScript(addr)
|
||||||
|
if err != nil {
|
||||||
|
return nil, btcjson.Error{
|
||||||
|
Code: btcjson.ErrInternal.Code,
|
||||||
|
Message: err.Error(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
txOut := btcwire.NewTxOut(amount, pkScript)
|
||||||
|
mtx.AddTxOut(txOut)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return the serialized and hex-encoded transaction.
|
||||||
|
mtxHex, err := messageToHex(mtx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return mtxHex, nil
|
||||||
|
}
|
||||||
|
|
||||||
// handleDebugLevel handles debuglevel commands.
|
// handleDebugLevel handles debuglevel commands.
|
||||||
func handleDebugLevel(s *rpcServer, cmd btcjson.Cmd) (interface{}, error) {
|
func handleDebugLevel(s *rpcServer, cmd btcjson.Cmd) (interface{}, error) {
|
||||||
c := cmd.(*btcjson.DebugLevelCmd)
|
c := cmd.(*btcjson.DebugLevelCmd)
|
||||||
@ -614,20 +716,6 @@ func handleGetBestBlockHash(s *rpcServer, cmd btcjson.Cmd) (interface{}, error)
|
|||||||
return sha.String(), nil
|
return sha.String(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// messageToHex serializes a message to the wire protocol encoding using the
|
|
||||||
// latest protocol version and returns a hex-encoded string of the result.
|
|
||||||
func messageToHex(msg btcwire.Message) (string, error) {
|
|
||||||
var buf bytes.Buffer
|
|
||||||
err := msg.BtcEncode(&buf, btcwire.ProtocolVersion)
|
|
||||||
if err != nil {
|
|
||||||
return "", btcjson.Error{
|
|
||||||
Code: btcjson.ErrInternal.Code,
|
|
||||||
Message: err.Error(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return hex.EncodeToString(buf.Bytes()), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// handleGetBlock implements the getblock command.
|
// handleGetBlock implements the getblock command.
|
||||||
func handleGetBlock(s *rpcServer, cmd btcjson.Cmd) (interface{}, error) {
|
func handleGetBlock(s *rpcServer, cmd btcjson.Cmd) (interface{}, error) {
|
||||||
c := cmd.(*btcjson.GetBlockCmd)
|
c := cmd.(*btcjson.GetBlockCmd)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user