Can the endpoints /block and /account/balance not be implemented?

Can this process not be implemented? After each transaction in a block is executed, we do not record account balance changes. By now there is no record of which account balances were changed by the smart contract.

upload://9FbKMkER1sOZzfNQQu8cw2gJpJI.png

What happened? when I upload a picture, it tips “Sorry, you can’t put images in a post”

                               X                                                  |
                               X  Get Block +----------------------------------------------> /block
                               X                                                  |             +
                    +---------+X                +-----------------------------------------------+
                    |          X                v                                 |

Ensure balance computed | X [Optional] Get Additional Block Transactions ±----------> /block/transaction
from block operations | X |
equals balance on node | |
| |
±----------> Get account balance for each ±--------------------------> /account/balance
account seen in a block |
|

Are there no ways to get the “traces” of transfers that happen inside of smart contracts? For example, this is Ethereum’s version of traces: https://github.com/ethereum/go-ethereum/wiki/Tracing:-Introduction

This is a hard requirement for us, because we need to be able to look at transactions and see the associated balance changes from that transaction, even if they happened within a smart contract.

tron also records all trace for each contract, just not the change in balance, which we need some very complex work to support.

By the way, how do I use this endpoints /construction to construct a smart contract, I see that this endpoints /construction are only concerned with account balance changes, using only this data it is not possible to construct a contract other than a transfer contract.

Unfortunately we require balance changes from contract traces. This is a hard requirement, since we need to be able to observe how every transaction changes balances, even to a contract.

:wave: @Matt.Yue…this is a moderation setting we’ve been advised to enable to prevent spam. Sorry for the inconvenience.

To reiterate @Matt.Yue

If it is not possible to determine which account balances change (and by how much) in a given transaction, it will not be possible to implement the Rosetta Data API. These balance changes must be populated in calls to /block (and /block/transaction if implemented).

It is very important to many integrators that they can extract all balance changes that occurred in a given block. Without the ability to do this, it is not possible to determine which accounts received deposits or which account balances may have changed unexpectedly (which causes accounting and auditing nightmares!).

Previous Quesiton

When responding to your earlier question, I assumed you were referring to being able to query the balance of an account at any height using the /account/balance endpoint. Sorry for any confusion that answer may have caused related to this point!

Would you mind posting this in a separate thread @Matt.Yue? I think this is a great question!

You must complete the /block and /account/balance endpoint to implement the Data API. I wrote a little about this on the website.

Hi, patrick. I want to support querying history account balance. But when I run check:data, I get this error. The account (TJg4jR7LkASMZW6iowyKZ6cruaTy5dsBYN) is created first on block height 26, so the address is not exists on block height 25. It be retried some times and throw the exception.

2020/08/06 23:09:12 account { "address": "TJg4jR7LkASMZW6iowyKZ6cruaTy5dsBYN"} fetch error: {Code:204 Message:this account is not exists. Retriable:false Details:map[hash:00000000000000193d73e2510423cdc4b8bbc310efeb0627b3e680bd9ae14490 index:25]}
Check failed: retries exhausted: unable to fetch account {
 "address": "TJg4jR7LkASMZW6iowyKZ6cruaTy5dsBYN"
}: unable to get currency balance in storage helper: unable to get previous account balance: unable to add block to storage 000000000000001a1c8a7e23a948d5a024cf92f3155a20012f863584343b224e:26: unable to sync to 33

block height 25

{
    "block": {
        "block_identifier": {
            "index": 25,
            "hash": "00000000000000193d73e2510423cdc4b8bbc310efeb0627b3e680bd9ae14490"
        },
        "parent_block_identifier": {
            "index": 24,
            "hash": "00000000000000181a8cf7c212f01b6ba8037c0cf4cb37884cc3d609aa3150b3"
        },
        "timestamp": 1596726474000,
        "transactions": []
    }
}

block height 26

{
"block": {
    "block_identifier": {
        "index": 26,
        "hash": "000000000000001a1c8a7e23a948d5a024cf92f3155a20012f863584343b224e"
    },
    "parent_block_identifier": {
        "index": 25,
        "hash": "00000000000000193d73e2510423cdc4b8bbc310efeb0627b3e680bd9ae14490"
    },
    "timestamp": 1596726477000,
    "transactions": [
        {
            "transaction_identifier": {
                "hash": "7cb7c1afe37e1af3b8513748bd285870d5a06cb8f1b1ee33eaf2484f528b14c0"
            },
            "operations": [
                {
                    "operation_identifier": {
                        "index": 0
                    },
                    "type": "TransferContract",
                    "status": "SUCCESS",
                    "account": {
                        "address": "TGehVcNhud84JDCGrNHKVz9jEAVKUpbuiv"
                    },
                    "amount": {
                        "value": "-100000",
                        "currency": {
                            "symbol": "TRX",
                            "decimals": 6
                        }
                    }
                },
                {
                    "operation_identifier": {
                        "index": 1
                    },
                    "type": "TransferContract",
                    "status": "SUCCESS",
                    "account": {
                        "address": "THKrowiEfCe8evdbaBzDDvQjM5DGeB3s3F"
                    },
                    "amount": {
                        "value": "100000",
                        "currency": {
                            "symbol": "TRX",
                            "decimals": 6
                        }
                    }
                },
                {
                    "operation_identifier": {
                        "index": 2
                    },
                    "type": "TransferContract",
                    "status": "SUCCESS",
                    "account": {
                        "address": "TGehVcNhud84JDCGrNHKVz9jEAVKUpbuiv"
                    },
                    "amount": {
                        "value": "-5000000000000",
                        "currency": {
                            "symbol": "TRX",
                            "decimals": 6
                        }
                    }
                },
                {
                    "operation_identifier": {
                        "index": 3
                    },
                    "type": "TransferContract",
                    "status": "SUCCESS",
                    "account": {
                        "address": "TJg4jR7LkASMZW6iowyKZ6cruaTy5dsBYN"
                    },
                    "amount": {
                        "value": "5000000000000",
                        "currency": {
                            "symbol": "TRX",
                            "decimals": 6
                        }
                    }
                }
            ]
        }
    ]
}
}

If an address does not exist at a certain block, Rosetta assumes /account/balance will return a balance of 0 instead of error-ing. If there is some reason you don’t think this is a good idea in your implementation, I’m happy to discuss in more detail.

The rosetta-cli performs this lookup (balance fetch at the block before the address is seen) because it does not know the balance of the address before the first block where it sees an address (which is needed to accurately compute a balance change). If this address had a genesis allocation, for example, this “block before balance lookup” would ensure we started computing the balance of this address from the correct starting amount (the genesis allocation instead of 0).