xrpl-py
xrpl-py copied to clipboard
Easier way to get Check ID
After you submit a CheckCreate transaction, you need the ID of the resulting Check ledger object in order to cash or cancel it. However, getting a Check ID is currently kind of a pain.
There are two general approaches:
- After autofilling the transaction, calculate the ID using SHA-512Half of the relevant pieces.
- First, get the transaction's identifying hash, then look up the transaction's results with
tx
or something similar, then dig through the metadata to find theCreatedNode
of typeCheck
and pull its ID from theLedgerIndex
field there.
The first approach requires more calculations but less network calls, so I think it's the better one. A helper function could go a long way to making that easier.
Either some kind of "Get Check ID" method that takes a CheckCreate transaction as an argument, or even a special method on the CheckCreate transaction model class, could handle all the hard bits without making the user work through them. This method would:
- Use the given CheckCreate transaction's
TicketSequence
(if present) orSequence
(otherwise), and raise an error if the transaction doesn't have either. (If the user is relying on autofilling to provide the sequence number, they'd have to call this "Get Check ID" method after autofilling.) - Construct a binary buffer consisting of the relevant pieces in order (16-bit Check space key, 160-bit AccountID, 32-bit Sequence or TicketSequence)
- Calculate and return the SHA-512Half hash of the buffer, as a hexadecimal string.
Test Case
Take the following CheckCreate transaction:
{
"Account": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
"Destination": "ra5nK24KXen9AHvsdFTKHSANinZseWnPcX",
"DestinationTag": 13,
"Fee": "10",
"Flags": 2147483648,
"LastLedgerSequence": 61965654,
"SendMax": {
"currency": "USD",
"issuer": "ra5nK24KXen9AHvsdFTKHSANinZseWnPcX",
"value": "10"
},
"Sequence": 384,
"TransactionType": "CheckCreate"
}
The correct Check ID is C4A46CCD8F096E994C4B0DEAB6CE98E722FC17D7944C28B95127C2659C47CBEB
.
Related Work
https://github.com/XRPLF/xrpl.js/issues/876
Payment Channels have the same challenge, by the way. Might be good to kill two birds with one stone and do those the same way.
This is a problem that I encountered when working with Checks too.
One solution with your ideas from above would be:
Use a GetChannelID like the PaymentChannels channel_authorize methods
This way, use the Sequence of the Check and the Sender's Account as parameters and let the method return the CheckID.
Add an Owner field to the Checks like in Escrows.
Instead of adding the CheckId as a single field, you could add an Owner field to the CheckCash/Cancel methods + the Check Sequence and let the CheckCash/Cancel method calculate the ChannelId when creating the transaction. That would mean that the Account cashing/canceling a check would not go through the trouble of finding the ChannelID , but instead use the Owner and Sequence field to auto-create the ChannelID.
I'm not entirely convinced of my answer now, but I believe some improvements could be made using the ideas from above.
Hi,
Can we redesign the CheckCreate
transaction so that it returns the appropriate Check ID
in the rippled
codebase? This is an issue faced by all the client libraries. Repeated downstream implementations could be error-prone, hence a single source of truth in rippled would be helpful.
Assuming that a client is willing to wait for sufficient time, can we not return the CheckID
as a response in the CheckCreate
transaction ? (and similarly for the other ledger object types) ?