Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add function that calculates ledger account from a principal #582

Merged
merged 15 commits into from
Sep 26, 2023

Conversation

kentosugama
Copy link
Contributor

@kentosugama kentosugama commented Aug 9, 2023

Feature requested by community: https://dx.internetcomputer.org/topic/180

Requires a SHA224 and CRC32 implementation. Implementation taken from Timo's implementation:
https://github.com/research-ag/sha2

@kentosugama kentosugama self-assigned this Aug 9, 2023
Copy link
Contributor

@chenyan-dfinity chenyan-dfinity left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this the ledger account? I think we don't want to append CRC32 at the end.

Also, not sure if this belongs to base. Timo's sha224 library is way better than what we include here. I happen to wrote a version based on his library: https://github.com/dfinity/canister-profiling/blob/main/crypto/motoko/src/sha.mo#L16

@kentosugama
Copy link
Contributor Author

I asked Timo if I could include his implementation here and he said yes.

It seems that converting Principal to Account is a basic enough function to have it in base. I hid the cryptographic functions as private functions though.

I will look into where the CRC32 is coming from.

@ZenVoich
Copy link
Contributor

ZenVoich commented Sep 5, 2023

Won't it be confused with ICRC1 account?

Personally, I’m used to the fact that ledger account is accountId

@kentosugama
Copy link
Contributor Author

It looks like the Ledger documentation specifies the prepending of the CRC32 hash

https://internetcomputer.org/docs/current/references/ledger#_accounts

@chenyan-dfinity
Copy link
Contributor

Interesting. Better to clarify with the ledger team, because their code doesn't have CRC32 either: https://github.com/dfinity/ic/blob/master/rs/rosetta-api/icp_ledger/src/account_identifier.rs#L58

@kentosugama
Copy link
Contributor Author

I just tried making a call to the Ledger Canister with and without the CRC checksum. The call without the checksum failed.
The code you linked to has logic for checking the checksum. I think internally, they strip off the CRC but the public interface requires it. (https://github.com/dfinity/ic/blob/a6d4159013996396c84ca33f54dd60f2c5e17ea0/rs/rosetta-api/icp_ledger/ledger.did#L13)

@kentosugama kentosugama marked this pull request as ready for review September 11, 2023 19:40
@kentosugama
Copy link
Contributor Author

kentosugama commented Sep 12, 2023

@ZenVoich that's a fair feedback and seems consistent with the documentation.

Maybe it should be called toAccountID(), toLedgerAccount(), or even toLedgerAccountId()

@kentosugama kentosugama changed the title Add function that calculates account from a principal Add function that calculates ledger account from a principal Sep 12, 2023
@kentosugama
Copy link
Contributor Author

https://m7sm4-2iaaa-aaaab-qabra-cai.ic0.app/?tag=1188592470

This example seems to clearly show you need the CRC32.

src/Principal.mo Outdated Show resolved Hide resolved
Copy link
Contributor

@crusso crusso left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me, though slightly overkill since principals are short.
However, since this a user request, let's get it in.

I guess another design would be to parameterize by the sha244 implementation, but perhaps that's too risky. Or add a separate Ledger library that contains this (and in future other Ledger related logic). I expect many programs will use Principal, but not need the Ledger functionality.

I'll let @chenyan-dfinity decide...

Copy link
Contributor

@chenyan-dfinity chenyan-dfinity left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All good. I just realized that in the Rust implementation, the to_vec() method actually prepend the CRC32, so we are all good!

src/Principal.mo Outdated Show resolved Hide resolved
@kentosugama kentosugama merged commit 475e617 into master Sep 26, 2023
5 checks passed
@kentosugama kentosugama deleted the principal-to-account branch September 26, 2023 19:06
Comment on lines +417 to +424
s0 := ivs[iv][0];
s1 := ivs[iv][1];
s2 := ivs[iv][2];
s3 := ivs[iv][3];
s4 := ivs[iv][4];
s5 := ivs[iv][5];
s6 := ivs[iv][6];
s7 := ivs[iv][7]
Copy link

@timohanke timohanke Oct 27, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just for completeness, commenting here on an already merged PR, and too minor to be worth opening this again. So just for the record.

Since we are only using Sha224 I would have hard-codes the values here and remove the ivs array entirely since it also includes IVs for Sha256 which is confusing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants