Make gettransaction return a btcjson GetTransactionResult type

This commit is contained in:
David Hill 2014-04-11 14:10:27 -04:00
parent 677ec10ee7
commit 880c1cbaeb

View file

@ -953,7 +953,12 @@ func GetTransaction(icmd btcjson.Cmd) (interface{}, *btcjson.Error) {
var sr *tx.SignedTx var sr *tx.SignedTx
var srAccount string var srAccount string
var amountReceived int64 var amountReceived int64
var details []map[string]interface{}
ret := btcjson.GetTransactionResult{
Details: make([]btcjson.GetTransactionDetailsResult, 0),
WalletConflicts: make([]string, 0),
}
details := make([]btcjson.GetTransactionDetailsResult, 0)
for _, e := range accumulatedTxen { for _, e := range accumulatedTxen {
switch record := e.Tx.(type) { switch record := e.Tx.(type) {
case *tx.RecvTxOut: case *tx.RecvTxOut:
@ -963,18 +968,22 @@ func GetTransaction(icmd btcjson.Cmd) (interface{}, *btcjson.Error) {
amountReceived += record.Value() amountReceived += record.Value()
_, addrs, _, _ := record.Addresses(cfg.Net()) _, addrs, _, _ := record.Addresses(cfg.Net())
details = append(details, map[string]interface{}{
"account": e.Account, var addr string
if len(addrs) == 1 {
addr = addrs[0].EncodeAddress()
}
details = append(details, btcjson.GetTransactionDetailsResult{
Account: e.Account,
// TODO(oga) We don't mine for now so there // TODO(oga) We don't mine for now so there
// won't be any special coinbase types. If the // won't be any special coinbase types. If the
// tx is a coinbase then we should handle it // tx is a coinbase then we should handle it
// specially with the category depending on // specially with the category depending on
// whether it is an orphan or in the blockchain. // whether it is an orphan or in the blockchain.
"category": "receive", Category: "receive",
"amount": float64(record.Value()) / float64(btcutil.SatoshiPerBitcoin), Amount: float64(record.Value()) / float64(btcutil.SatoshiPerBitcoin),
"address": addrs[0].EncodeAddress(), Address: addr,
}) })
case *tx.SignedTx: case *tx.SignedTx:
// there should only be a single SignedTx record, if any. // there should only be a single SignedTx record, if any.
// If found, it will be added to the beginning. // If found, it will be added to the beginning.
@ -986,37 +995,49 @@ func GetTransaction(icmd btcjson.Cmd) (interface{}, *btcjson.Error) {
totalAmount := amountReceived totalAmount := amountReceived
if sr != nil { if sr != nil {
totalAmount -= sr.TotalSent() totalAmount -= sr.TotalSent()
info := map[string]interface{}{ info := btcjson.GetTransactionDetailsResult{
"account": srAccount, Account: srAccount,
"category": "send", Category: "send",
// negative since it is a send // negative since it is a send
"amount": -(sr.TotalSent() - amountReceived), Amount: float64(-(sr.TotalSent() - amountReceived)) / float64(btcutil.SatoshiPerBitcoin),
"fee": sr.Fee(), Fee: float64(sr.Fee()) / float64(btcutil.SatoshiPerBitcoin),
} }
_, addrs, _, _ := btcscript.ExtractPkScriptAddrs(sr.Tx().MsgTx().TxOut[0].PkScript, cfg.Net())
if len(addrs) == 1 {
info.Address = addrs[0].EncodeAddress()
}
ret.Fee += info.Fee
// Add sent information to front. // Add sent information to front.
details = append([]map[string]interface{}{info}, details...) ret.Details = append(ret.Details, info)
} }
ret.Details = append(ret.Details, details...)
// Generic information should be the same, so just use the first one. // Generic information should be the same, so just use the first one.
first := accumulatedTxen[0] first := accumulatedTxen[0]
ret := map[string]interface{}{ ret.Amount = float64(totalAmount) / float64(btcutil.SatoshiPerBitcoin)
// "amount" ret.TxID = first.Tx.TxSha().String()
// "confirmations
"amount": totalAmount, buf := bytes.NewBuffer(make([]byte, 0, first.Tx.Tx().MsgTx().SerializeSize()))
err = first.Tx.Tx().MsgTx().Serialize(buf)
if err != nil {
return nil, &btcjson.Error{
Code: btcjson.ErrWallet.Code,
Message: err.Error(),
}
}
ret.Hex = hex.EncodeToString(buf.Bytes())
"txid": first.Tx.TxSha().String(),
// TODO(oga) technically we have different time and // TODO(oga) technically we have different time and
// timereceived depending on if a transaction was send or // timereceived depending on if a transaction was send or
// receive. We ideally should provide the correct numbers for // receive. We ideally should provide the correct numbers for
// both. Right now they will always be the same // both. Right now they will always be the same
"time": first.Tx.Time().Unix(), ret.Time = first.Tx.Time().Unix()
"timereceived": first.Tx.Time().Unix(), ret.TimeReceived = first.Tx.Time().Unix()
"details": details,
}
if details := first.Tx.Block(); details != nil { if details := first.Tx.Block(); details != nil {
ret["blockindex"] = float64(details.Height) ret.BlockIndex = int64(details.Index)
ret["blockhash"] = details.Hash.String() ret.BlockHash = details.Hash.String()
ret["blocktime"] = details.Time.Unix() ret.BlockTime = details.Time.Unix()
bs, err := GetCurBlock() bs, err := GetCurBlock()
if err != nil { if err != nil {
return nil, &btcjson.Error{ return nil, &btcjson.Error{
@ -1024,7 +1045,7 @@ func GetTransaction(icmd btcjson.Cmd) (interface{}, *btcjson.Error) {
Message: err.Error(), Message: err.Error(),
} }
} }
ret["confirmations"] = bs.Height - details.Height + 1 ret.Confirmations = int64(bs.Height - details.Height + 1)
} }
// TODO(oga) if the tx is a coinbase we should set "generated" to true. // TODO(oga) if the tx is a coinbase we should set "generated" to true.
// Since we do not mine this currently is never the case. // Since we do not mine this currently is never the case.