Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How does Bihara display transaction information through list-transactions

2025-01-15 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Internet Technology >

Share

Shulou(Shulou.com)06/01 Report--

This article mainly explains "how to display transaction information through list-transactions". The explanation in the article is simple and clear, easy to learn and understand. Please follow the editor's train of thought to study and learn "how to display transaction information through list-transactions".

Question: after the submitted transaction is successfully completed, the front end will display the transaction information in the form of a list. How does it get the back-end data? That is, how the following figure is implemented:

Because it involves both the front end and the back end, we also divide it into two minor issues:

How does the front end get the transaction data and display it?

How does the back end find the transaction data?

Let's solve the problem in turn.

How does the front end get the transaction data and display it?

Let's first look in Bihara's front-end code base. Since this function is a "list paging" display, it reminds me that there is a similar function to display balances in paging, which uses the general components provided by src/features/shared/components/BaseList, so it should be the same here.

After checking, sure enough, we found the List.jsx file under src/features/transactions/components/, and the directory structure is very similar to src/features/balances/components/, and then take a glance at the code, you can be sure that the same method was used.

But if you think about it, the process still seems a little different. Where the balance is displayed, we manually click on the menu in the left column so that the front-end route goes to / balances, and then by

Src/features/shared/routes.js#L5-L44

Const makeRoutes = (store, type, List, New, Show, options = {}) = > {/ /. Return {path: options.path | | type + RoutingContainer, name: options.name | | humanize (type +'), name_zh: options.name_zh, indexRoute: {component: List, onEnter: (nextState, replace) = > {loadPage (nextState, replace)}, onChange: (_, nextState, replace) = > {loadPage (nextState, replace)}}, childRoutes: childRoutes}}

The onEnter or onChange in the triggers the loadPage and finally calls the background interface / list-balances step by step. This time, in the example of this article, it automatically goes to the "list showing transactions" page after submitting the "submit transaction" form successfully. will it also trigger onEnter or onChange?

The answer is yes, because in the previous article, when the submitForm is executed and the last request to the background / submit-transaction succeeds, the function dealSignSubmitResp is called, and it is defined as:

Src/features/transactions/actions.js#L120-L132

Const dealSignSubmitResp = resp = > {/ /. Dispatch (push ({pathname:'/ transactions', state: {preserveFlash: true}})}

As you can see, it will eventually switch the front-end route to / transactions, which is exactly the same route as the balance shown. So according to the experience there, you must visit the / list-transactions interface in the background at the end of the day.

The derivation in this process will no longer be discussed in detail. If necessary, you can see the previous article on "how to display the balance".

Finally, I got how the data returned by the background is displayed in tabular form, which was also mentioned in that article and skipped here.

How does the back end find the transaction data?

When we know that the front end will access the / list-transactions interface in the background, we can easily find the following code in the original main project repository:

Api/api.go#L164-L244

Func (a * API) buildHandler () {/ /... If a.wallet! = nil {/ /... M.Handle ("/ list-transactions", jsonHandler (a.listTransactions)) / /...}

As you can see, the handler corresponding to list-transactions is a.listTransactions:

Api/query.go#L83-L107

Func (a * API) listTransactions (ctx context.Context, filter struct {ID string `json: "id" `AccountID string `json: "account_id" `Detail bool `json: "detail" `}) Response {transactions: = [] * query.AnnotatedTx {} var err error / / 1. If filter.AccountID! = "{transactions, err = a.wallet.GetTransactionsByAccountID (filter.AccountID)} else {transactions Err = a.wallet.GetTransactionsByTxID (filter.ID)} / /... / / 2. If filter.Detail = = false {txSummary: = a.wallet.GetTransactionsSummary (transactions) return NewSuccessResponse (txSummary)} return NewSuccessResponse (transactions)}

As you can see from the parameters of this method, the front end can pass three parameters, id,account_id and detail. In the example in this article, because it is a route that jumps directly to / transactions, no parameters are passed.

I divided the code into two pieces, and some of the error handling parts were omitted. Explain in turn:

The first is that you want to get transactions based on the parameters. If the account_id has a value, fetch it, that is, the transaction owned by an account; otherwise, fetch it with id, which refers to the id of the transaction. If neither of them has a value, it should be handled in the second branch, that is, a.wallet.GetTransactionsByTxID should also be able to handle the case where the parameter is an empty string

In the second code, if detail is false (if there is no value passed at the front end, it should also be the default value false, then the previous transactions will be turned into a summary and only part of the information will be returned; otherwise, the complete information will be returned.

We advanced the a.wallet.GetTransactionsByAccountID in the first code:

Wallet/indexer.go#L505-L523

Func (w * Wallet) GetTransactionsByAccountID (accountID string) ([] * query.AnnotatedTx, error) {annotatedTxs: = [] * query.AnnotatedTx {} / / 1.txIter: = w.DB.IteratorPrefix ([] byte (TxPrefix)) defer txIter.Release () / / 2.for txIter.Next () {/ / 3. AnnotatedTx: = & query.AnnotatedTx {} if err: = json.Unmarshal (txIter.Value (), & annotatedTx) Err! = nil {return nil, err} / / 4. If findTransactionsByAccount (annotatedTx, accountID) {annotateTxsAsset (w, [] * query.AnnotatedTx {annotatedTx}) annotatedTxs = append (annotatedTxs, annotatedTx)}} return annotatedTxs, nil}

Here, the code is divided into four blocks:

The first code is to traverse the values in the database prefixed with TxPrefix, where TxPrefix is TXS:,. The DB here is undoubtedly the leveldb of wallet.

Start traversing at the second place

The third place is to take out the Value of each element, which is in JSON format, and convert it to an AnnotatedTx object. Each element of txIter is a key-pair, including Key () and Value (). Only Value () is used here.

The fourth is to look in the current annotatedTx object, which is what we need if the id of the account contained in its input or output is equal to accountId. Then use the annotateTxsAsset method to complete the asset-related properties (such as alias, etc.) in the annotatedTx object.

The definition of AnnotatedTx is worth looking at:

Blockchain/query/annotated.go#L12-L22

Type AnnotatedTx struct {ID bc.Hash `json: "tx_id" `Timestamp uint64 `json: "block_time" `BlockID bc.Hash `json: "block_hash" `BlockHeight uint64 `json: "block_height" `Position uint32 `json : "block_index" `BlockTransactionsCount uint32 `json: "block_transactions_count Omitempty "`Inputs [] * AnnotatedInput `json:" inputs "`Outputs [] * AnnotatedOutput `json:" outputs "`StatusFail bool `json:" status_fail "`}

In fact, it is to hold the data finally returned to the front end, by adding JSON-related annotation to each field to facilitate the conversion to JSON.

If the account_id parameter is not passed at the front end, it will enter another branch, corresponding to a.wallet.GetTransactionsByTxID (filter.ID):

Wallet/indexer.go#L426-L450

Func (w * Wallet) GetTransactionsByTxID (txID string) ([] * query.AnnotatedTx, error) {annotatedTxs: = [] * query.AnnotatedTx {} formatKey: = "" if txID! = "" {rawFormatKey: = w.DB.Get (calcTxIndexKey (txID)) if rawFormatKey = = nil {return nil, fmt.Errorf ("No transaction (txid=%s)" TxID)} formatKey = string (rawFormatKey)} txIter: = w.DB.IteratorPrefix (calcAnnotatedKey (formatKey)) defer txIter.Release () for txIter.Next () {annotatedTx: = & query.AnnotatedTx {} if err: = json.Unmarshal (txIter.Value (), annotatedTx) Err! = nil {return nil, err} annotateTxsAsset (w, [] * query.AnnotatedTx {annotatedTx}) annotatedTxs = append ([] * query.AnnotatedTx {annotatedTx}, annotatedTxs...)} return annotatedTxs, nil}

This method looks long, but in fact the logic is relatively simple. If the front end passes txID, it will look for the trading object of the specified id in the wallet; otherwise, take it all out (in the case of this article). Where calcTxIndexKey (txID) is defined as:

Wallet/indexer.go#L61-L63

Func calcTxIndexKey (txID string) [] byte {return [] byte (TxIndexPrefix + txID)}

Where TxIndexPrefix is TID:.

CalcAnnotatedKey (formatKey) is defined as:

Wallet/indexer.go#L53-L55

Func calcAnnotatedKey (formatKey string) [] byte {return [] byte (TxPrefix + formatKey)}

Where the value of TxPrefix is TXS:.

Let's go back to the second place in listTransactions, which is detail. If detail is false, only the summary is needed, so a.wallet.GetTransactionsSummary (transactions) is called:

Wallet/indexer.go#L453-L486

Func (w * Wallet) GetTransactionsSummary (transactions [] * query.AnnotatedTx) [] TxSummary {Txs: = [] TxSummary {} for _, annotatedTx: = range transactions {tmpTxSummary: = TxSummary {Inputs: make ([] Summary, len (annotatedTx.Inputs)), Outputs: make ([] Summary, len (annotatedTx.Outputs), ID: annotatedTx.ID, Timestamp: annotatedTx.Timestamp } for i Input: = range annotatedTx.Inputs {tmpTxSummary.Inputs.Type = input.Type tmpTxSummary.Inputs.AccountID = input.AccountID tmpTxSummary.Inputs.AccountAlias = input.AccountAlias tmpTxSummary.I nputs[ I] .AssetID = input.AssetID tmpTxSummary.Inputs.AssetAlias = input.AssetAlias tmpTxSummary.Inputs.AccountID = input.Amount tmpTxSummary.Inputs [I] .amount = Inputs.AccountAlias = tmpTxSummary.Inputs.AccountID = tmpTxSummary.Inputs.AccountAlias = input.AssetID tmpTxSummary.Inputs.AssetAlias = tmpTxSummary.Inputs.AccountID = tmpTxSummary.Inputs.AccountID = tmpTxSummary.Inputs.Accoun I] .Arbitrary = input.Arbitrary} for j Output: = range annotatedTx.Outputs {tmpTxSummary.Outputs.Type = output.Type tmpTxSummary.Outputs.AccountID = output.AccountID tmpTxSummary.Outputs.AccountAlias = output.AccountAlias tmpTxS ummary.Outputs.AssetID = output.AssetID tmpTxSummary.Outputs.AssetAlias = output.AssetAlias tmpTxSummary.Outputs[ j] .Amount = output.Amount} Txs = append TmpTxSummary)} return Txs}

The code in this section is quite straightforward, which is to take some of the important information from the elements of transactions, form a new TxSummary object, and return to the past. Finally, these objects are returned to the front end as JSON.

Well, even if today's small problem is solved, because there is previous experience can be used, so the feeling is relatively simple.

Thank you for your reading, the above is the content of "how to display transaction information through list-transactions". After the study of this article, I believe you have a deeper understanding of how to display transaction information through list-transactions, and the specific use needs to be verified in practice. Here is, the editor will push for you more related knowledge points of the article, welcome to follow!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Internet Technology

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report