From f153b836db609e5697eea6ec04aa707412d99cae Mon Sep 17 00:00:00 2001 From: mj Date: Mon, 13 Jan 2025 19:13:08 +0800 Subject: [PATCH] update with queries --- precompiles/confidentialtransfers/CT.sol | 2 + precompiles/confidentialtransfers/abi.json | 2 +- x/evm/client/cli/query.go | 205 ++++++++++++++++++++- 3 files changed, 206 insertions(+), 3 deletions(-) diff --git a/precompiles/confidentialtransfers/CT.sol b/precompiles/confidentialtransfers/CT.sol index b7c3c139d..c20265ba9 100644 --- a/precompiles/confidentialtransfers/CT.sol +++ b/precompiles/confidentialtransfers/CT.sol @@ -28,6 +28,7 @@ interface ICT { bytes toAmountLo, bytes toAmountHi, bytes remainingBalance, + string decryptableBalance, bytes proofs ) external returns (bool success); @@ -40,6 +41,7 @@ interface ICT { bytes toAmountLo, bytes toAmountHi, bytes remainingBalance, + string decryptableBalance, bytes proofs, Auditor[] auditors ) external returns (bool success); diff --git a/precompiles/confidentialtransfers/abi.json b/precompiles/confidentialtransfers/abi.json index 1bb0d9d0c..162b6c5cc 100644 --- a/precompiles/confidentialtransfers/abi.json +++ b/precompiles/confidentialtransfers/abi.json @@ -1 +1 @@ -[{"inputs":[{"internalType":"string","name":"fromAddress","type":"string"},{"internalType":"string","name":"denom","type":"string"},{"internalType":"bytes","name":"publicKey","type":"bytes"},{"internalType":"string","name":"decryptableBalance","type":"string"},{"internalType":"bytes","name":"pendingBalanceLo","type":"bytes"},{"internalType":"bytes","name":"pendingBalanceHi","type":"bytes"},{"internalType":"bytes","name":"availableBalance","type":"bytes"},{"internalType":"bytes","name":"proofs","type":"bytes"}],"name":"initializeAccount","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"fromAddress","type":"string"},{"internalType":"string","name":"toAddress","type":"string"},{"internalType":"string","name":"denom","type":"string"},{"internalType":"bytes","name":"fromAmountLo","type":"bytes"},{"internalType":"bytes","name":"fromAmountHi","type":"bytes"},{"internalType":"bytes","name":"toAmountLo","type":"bytes"},{"internalType":"bytes","name":"toAmountHi","type":"bytes"},{"internalType":"bytes","name":"remainingBalance","type":"bytes"},{"internalType":"bytes","name":"proofs","type":"bytes"}],"name":"transfer","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"fromAddress","type":"string"},{"internalType":"string","name":"toAddress","type":"string"},{"internalType":"string","name":"denom","type":"string"},{"internalType":"bytes","name":"fromAmountLo","type":"bytes"},{"internalType":"bytes","name":"fromAmountHi","type":"bytes"},{"internalType":"bytes","name":"toAmountLo","type":"bytes"},{"internalType":"bytes","name":"toAmountHi","type":"bytes"},{"internalType":"bytes","name":"remainingBalance","type":"bytes"},{"internalType":"bytes","name":"proofs","type":"bytes"},{"components":[{"internalType":"string","name":"auditorAddress","type":"string"},{"internalType":"bytes","name":"encryptedTransferAmountLo","type":"bytes"},{"internalType":"bytes","name":"encryptedTransferAmountHi","type":"bytes"},{"internalType":"bytes","name":"transferAmountLoValidityProof","type":"bytes"},{"internalType":"bytes","name":"transferAmountHiValidityProof","type":"bytes"},{"internalType":"bytes","name":"transferAmountLoEqualityProof","type":"bytes"},{"internalType":"bytes","name":"transferAmountHiEqualityProof","type":"bytes"}],"internalType":"struct ICT.Auditor[]","name":"auditors","type":"tuple[]"}],"name":"transferWithAuditors","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"fromAddress","type":"string"},{"internalType":"string","name":"denom","type":"string"},{"internalType":"uint64","name":"amount","type":"uint64"}],"name":"deposit","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"fromAddress","type":"string"},{"internalType":"string","name":"denom","type":"string"},{"internalType":"string","name":"decryptableBalance","type":"string"},{"internalType":"uint32","name":"pendingBalanceCreditCounter","type":"uint32"},{"internalType":"bytes","name":"availableBalance","type":"bytes"}],"name":"applyPendingBalance","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"fromAddress","type":"string"},{"internalType":"string","name":"denom","type":"string"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"string","name":"decryptableBalance","type":"string"},{"internalType":"bytes","name":"remainingBalanceCommitment","type":"bytes"},{"internalType":"bytes","name":"proofs","type":"bytes"}],"name":"withdraw","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"stateMutability":"nonpayable","type":"function"}] +[{"inputs":[{"internalType":"string","name":"fromAddress","type":"string"},{"internalType":"string","name":"denom","type":"string"},{"internalType":"bytes","name":"publicKey","type":"bytes"},{"internalType":"string","name":"decryptableBalance","type":"string"},{"internalType":"bytes","name":"pendingBalanceLo","type":"bytes"},{"internalType":"bytes","name":"pendingBalanceHi","type":"bytes"},{"internalType":"bytes","name":"availableBalance","type":"bytes"},{"internalType":"bytes","name":"proofs","type":"bytes"}],"name":"initializeAccount","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"fromAddress","type":"string"},{"internalType":"string","name":"toAddress","type":"string"},{"internalType":"string","name":"denom","type":"string"},{"internalType":"bytes","name":"fromAmountLo","type":"bytes"},{"internalType":"bytes","name":"fromAmountHi","type":"bytes"},{"internalType":"bytes","name":"toAmountLo","type":"bytes"},{"internalType":"bytes","name":"toAmountHi","type":"bytes"},{"internalType":"bytes","name":"remainingBalance","type":"bytes"},{"internalType":"string","name":"decryptableBalance","type":"string"},{"internalType":"bytes","name":"proofs","type":"bytes"}],"name":"transfer","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"fromAddress","type":"string"},{"internalType":"string","name":"toAddress","type":"string"},{"internalType":"string","name":"denom","type":"string"},{"internalType":"bytes","name":"fromAmountLo","type":"bytes"},{"internalType":"bytes","name":"fromAmountHi","type":"bytes"},{"internalType":"bytes","name":"toAmountLo","type":"bytes"},{"internalType":"bytes","name":"toAmountHi","type":"bytes"},{"internalType":"bytes","name":"remainingBalance","type":"bytes"},{"internalType":"string","name":"decryptableBalance","type":"string"},{"internalType":"bytes","name":"proofs","type":"bytes"},{"components":[{"internalType":"string","name":"auditorAddress","type":"string"},{"internalType":"bytes","name":"encryptedTransferAmountLo","type":"bytes"},{"internalType":"bytes","name":"encryptedTransferAmountHi","type":"bytes"},{"internalType":"bytes","name":"transferAmountLoValidityProof","type":"bytes"},{"internalType":"bytes","name":"transferAmountHiValidityProof","type":"bytes"},{"internalType":"bytes","name":"transferAmountLoEqualityProof","type":"bytes"},{"internalType":"bytes","name":"transferAmountHiEqualityProof","type":"bytes"}],"internalType":"struct ICT.Auditor[]","name":"auditors","type":"tuple[]"}],"name":"transferWithAuditors","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"fromAddress","type":"string"},{"internalType":"string","name":"denom","type":"string"},{"internalType":"uint64","name":"amount","type":"uint64"}],"name":"deposit","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"fromAddress","type":"string"},{"internalType":"string","name":"denom","type":"string"},{"internalType":"string","name":"decryptableBalance","type":"string"},{"internalType":"uint32","name":"pendingBalanceCreditCounter","type":"uint32"},{"internalType":"bytes","name":"availableBalance","type":"bytes"}],"name":"applyPendingBalance","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"fromAddress","type":"string"},{"internalType":"string","name":"denom","type":"string"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"string","name":"decryptableBalance","type":"string"},{"internalType":"bytes","name":"remainingBalanceCommitment","type":"bytes"},{"internalType":"bytes","name":"proofs","type":"bytes"}],"name":"withdraw","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"stateMutability":"nonpayable","type":"function"}] diff --git a/x/evm/client/cli/query.go b/x/evm/client/cli/query.go index 4c537834b..50d805f16 100644 --- a/x/evm/client/cli/query.go +++ b/x/evm/client/cli/query.go @@ -57,6 +57,8 @@ func GetQueryCmd(_ string) *cobra.Command { cmd.AddCommand(CmdQueryPointee()) cmd.AddCommand(GetCmdQueryCtTransferPayload()) cmd.AddCommand(GetCmdQueryCtInitAccountPayload()) + cmd.AddCommand(GetCmdQueryCtApplyPendingBalancePayload()) + cmd.AddCommand(GetCmdQueryCtWithdrawPayload()) return cmd } @@ -734,8 +736,8 @@ func queryCtInitAccountPayload(cmd *cobra.Command, args []string) error { bz, err := newAbi.Pack( confidentialtransfers.InitializeAccountMethod, - seiAddress, - denom, + initAccountProto.FromAddress, + initAccountProto.Denom, initAccountProto.PublicKey, initAccountProto.DecryptableBalance, pendingBalanceLo, @@ -749,6 +751,205 @@ func queryCtInitAccountPayload(cmd *cobra.Command, args []string) error { return queryClientCtx.PrintString(hex.EncodeToString(bz)) } +func GetCmdQueryCtApplyPendingBalancePayload() *cobra.Command { + cmd := &cobra.Command{ + Use: "ct-apply-pending-balance-payload [abi-filepath] [from_address] [denom]", + Short: "get hex payload for the confidential transfers apply pending balance method", + Args: cobra.ExactArgs(3), + RunE: queryCtApplyPendingBalancePayload, + } + + flags.AddQueryFlagsToCmd(cmd) + + return cmd +} + +func queryCtApplyPendingBalancePayload(cmd *cobra.Command, args []string) error { + queryClientCtx, err := client.GetClientQueryContext(cmd) + if err != nil { + return err + } + queryClient := types.NewQueryClient(queryClientCtx) + + dat, err := os.ReadFile(args[0]) + if err != nil { + return err + } + + newAbi, err := abi.JSON(bytes.NewReader(dat)) + if err != nil { + return err + } + + fromAddress := args[1] + if fromAddress == "" { + return errors.New("from address cannot be empty") + } + + seiAddress, err := getSeiAddress(queryClient, fromAddress) + if err != nil { + return err + } + + denom := args[2] + if denom == "" { + return errors.New("denom cannot be empty") + } + + _, name, _, err := client.GetFromFields(queryClientCtx, queryClientCtx.Keyring, seiAddress) + if err != nil { + return err + } + + privKey, err := getPrivateKeyForName(cmd, name) + if err != nil { + return err + } + + ctQueryClient := cttypes.NewQueryClient(queryClientCtx) + fromAccount, err := ctcliutils.GetAccount(ctQueryClient, seiAddress, denom) + if err != nil { + return err + } + + applyPendingBalance, err := cttypes.NewApplyPendingBalance( + *privKey, + seiAddress, + denom, + fromAccount.DecryptableAvailableBalance, + fromAccount.PendingBalanceCreditCounter, + fromAccount.AvailableBalance, + fromAccount.PendingBalanceLo, + fromAccount.PendingBalanceHi) + if err != nil { + return err + } + + applyPendingBalanceProto := cttypes.NewMsgApplyPendingBalanceProto(applyPendingBalance) + + if err = applyPendingBalanceProto.ValidateBasic(); err != nil { + return err + } + + availableBalance, err := applyPendingBalanceProto.CurrentAvailableBalance.Marshal() + if err != nil { + return err + } + + bz, err := newAbi.Pack( + confidentialtransfers.ApplyPendingBalanceMethod, + applyPendingBalanceProto.Address, + applyPendingBalanceProto.Denom, + applyPendingBalanceProto.NewDecryptableAvailableBalance, + applyPendingBalanceProto.CurrentPendingBalanceCounter, + availableBalance) + + if err != nil { + return err + } + return queryClientCtx.PrintString(hex.EncodeToString(bz)) +} + +func GetCmdQueryCtWithdrawPayload() *cobra.Command { + cmd := &cobra.Command{ + Use: "ct-withdraw-payload [abi-filepath] [from_address] [amount]", + Short: "get hex payload for the confidential transfers withdraw method", + Args: cobra.ExactArgs(3), + RunE: queryCtWithdrawPayload, + } + + flags.AddQueryFlagsToCmd(cmd) + + return cmd +} + +func queryCtWithdrawPayload(cmd *cobra.Command, args []string) error { + queryClientCtx, err := client.GetClientQueryContext(cmd) + if err != nil { + return err + } + queryClient := types.NewQueryClient(queryClientCtx) + + dat, err := os.ReadFile(args[0]) + if err != nil { + return err + } + + newAbi, err := abi.JSON(bytes.NewReader(dat)) + if err != nil { + return err + } + + fromAddress := args[1] + if fromAddress == "" { + return errors.New("from address cannot be empty") + } + + seiAddress, err := getSeiAddress(queryClient, fromAddress) + if err != nil { + return err + } + + coin, err := sdk.ParseCoinNormalized(args[2]) + if err != nil { + return err + } + + _, name, _, err := client.GetFromFields(queryClientCtx, queryClientCtx.Keyring, seiAddress) + if err != nil { + return err + } + + privKey, err := getPrivateKeyForName(cmd, name) + if err != nil { + return err + } + + ctQueryClient := cttypes.NewQueryClient(queryClientCtx) + fromAccount, err := ctcliutils.GetAccount(ctQueryClient, seiAddress, coin.Denom) + if err != nil { + return err + } + + withdraw, err := cttypes.NewWithdraw( + *privKey, + fromAccount.AvailableBalance, + coin.Denom, + seiAddress, + fromAccount.DecryptableAvailableBalance, + coin.Amount.BigInt()) + + if err != nil { + return err + } + + withdrawProto := cttypes.NewMsgWithdrawProto(withdraw) + + if err = withdrawProto.ValidateBasic(); err != nil { + return err + } + + remainingBalanceCommitment, err := withdrawProto.RemainingBalanceCommitment.Marshal() + proofs, err := withdrawProto.Proofs.Marshal() + if err != nil { + return err + } + + bz, err := newAbi.Pack( + confidentialtransfers.WithdrawMethod, + withdrawProto.FromAddress, + withdrawProto.Denom, + withdrawProto.Amount, + withdrawProto.DecryptableBalance, + remainingBalanceCommitment, + proofs) + + if err != nil { + return err + } + return queryClientCtx.PrintString(hex.EncodeToString(bz)) +} + func getSeiAddress(queryClient types.QueryClient, address string) (string, error) { if common.IsHexAddress(address) { evmAddr := common.HexToAddress(address)