From cf18000ca34e60eebbe31576554d7d2b1e2f1f05 Mon Sep 17 00:00:00 2001 From: Doris Benda Date: Mon, 18 Mar 2024 11:21:42 +0200 Subject: [PATCH 01/10] Initial CIS5 standard --- source/CIS/cis-5.rst | 51 ++++++++++++++++++++++++++++++++++++++++++++ source/index.rst | 2 +- 2 files changed, 52 insertions(+), 1 deletion(-) create mode 100644 source/CIS/cis-5.rst diff --git a/source/CIS/cis-5.rst b/source/CIS/cis-5.rst new file mode 100644 index 0000000..2fe00eb --- /dev/null +++ b/source/CIS/cis-5.rst @@ -0,0 +1,51 @@ +.. _CIS-5: + +===================================== +CIS-5: Smart Contract Wallet Standard +===================================== + +.. list-table:: + :stub-columns: 1 + + * - Created + - Mar 17, 2024 + * - Final + - Mar 28, 2024 + * - Supported versions + - | Smart contract version 1 or newer + | (Protocol version 4 or newer) + * - Standard identifier + - ``CIS-5`` + +Abstract +======== + +A standard interface for defining a smart contract wallet that can hold and transfer native currency and cis2 tokens. +Native currency/Cis2 tokens can be deposited into the smart contract wallet by +specifying to which public key the deposit should be assigned. + +The holder of the corresponding private key is the only entity that can authorize +to transfer tokens/currency in a self-custodial manner +from the public key balance (assigned in the smart contract) to some new accounts/smart contracts/public keys. + +The holder of the corresponding private key does not have to submit transactions +on chain to transfer its native currency/cis2 token balance, +but instead, it can generate a valid signature, identify a willing third +party to submit its signature on-chain (a service fee can be added to financially incentivize a third party to do so). + +The three main actions in the smart contract that can be taken: + +- *deposit*: assigns the balance to a public key within the smart contract wallet. + +- *internal transfer*: assigns the balance to a new public key within the smart contract wallet. + +- *withdraw*: withdraws the balance out of the smart contract wallet to a native account or smart contract. + +The goal is to simplify the account creation onboarding flow on Concordium +allowing for CIS5 smart contract wallets to be supported as first-classs citizens on Concordium wallets and tooling. + +Specification +============= + +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in :rfc:`2119`. + diff --git a/source/index.rst b/source/index.rst index b8e290a..0c0b33a 100644 --- a/source/index.rst +++ b/source/index.rst @@ -21,5 +21,5 @@ Concordium Interoperability Specifications CIS/cis-2 CIS/cis-3 CIS/cis-4 + CIS/cis-5 CIS/cis-6 - ID/concordium-did.rst From 6917ada5bf83e8b80b1718807ab63d2f4b02d063 Mon Sep 17 00:00:00 2001 From: Doris Benda Date: Mon, 18 Mar 2024 13:13:16 +0200 Subject: [PATCH 02/10] Add type definitions --- source/CIS/cis-5.rst | 272 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 265 insertions(+), 7 deletions(-) diff --git a/source/CIS/cis-5.rst b/source/CIS/cis-5.rst index 2fe00eb..805c369 100644 --- a/source/CIS/cis-5.rst +++ b/source/CIS/cis-5.rst @@ -16,19 +16,21 @@ CIS-5: Smart Contract Wallet Standard | (Protocol version 4 or newer) * - Standard identifier - ``CIS-5`` + * - Requires + - :ref:`CIS-0` Abstract ======== -A standard interface for defining a smart contract wallet that can hold and transfer native currency and cis2 tokens. +A standard interface for defining a smart contract wallet that can hold and transfer native currency and cis2 tokens. Native currency/Cis2 tokens can be deposited into the smart contract wallet by -specifying to which public key the deposit should be assigned. +specifying to which public key the deposit should be assigned. -The holder of the corresponding private key is the only entity that can authorize -to transfer tokens/currency in a self-custodial manner +The holder of the corresponding private key is the only entity that can authorize +to transfer tokens/currency in a self-custodial manner from the public key balance (assigned in the smart contract) to some new accounts/smart contracts/public keys. -The holder of the corresponding private key does not have to submit transactions +The holder of the corresponding private key does not have to submit transactions on chain to transfer its native currency/cis2 token balance, but instead, it can generate a valid signature, identify a willing third party to submit its signature on-chain (a service fee can be added to financially incentivize a third party to do so). @@ -41,11 +43,267 @@ The three main actions in the smart contract that can be taken: - *withdraw*: withdraws the balance out of the smart contract wallet to a native account or smart contract. -The goal is to simplify the account creation onboarding flow on Concordium -allowing for CIS5 smart contract wallets to be supported as first-classs citizens on Concordium wallets and tooling. +The goal of this standard is to simplify the account creation onboarding flow on Concordium +allowing for CIS5 smart contract wallets to be supported as first-class citizens on Concordium wallets and tooling. Specification ============= The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in :rfc:`2119`. +General types and serialization +------------------------------- + +.. note:: + + Integers are encoded in little-endian unless stated otherwise. + +.. _CIS-5-TokenID: + +``TokenID`` +^^^^^^^^^^^ + +- The token ID SHALL be able to encode all possible tokenIds from the :ref:`CIS-2-TokenID` (``tokenId``) + +A token ID is serialized as 1 byte for the size (``n``) of the identifier, followed by this number of bytes for the token id (``id``):: + + TokenID ::= (n: Byte) (id: Byteⁿ) + +.. note:: + + Token IDs can be as small as a single byte (by setting the first byte to the value 0) or as big as 256 bytes leaving more than 10^614 possible token IDs. + The token ID in the CIS5 standard needs to be able to encode up to 256 bytes long tokenIds. + +.. _CIS-5-TokenAmount: + +``TokenAmount`` +^^^^^^^^^^^^^^^ + +- The token amount SHALL be able to encode all possible tokenAmounts from the :ref:`CIS-2-TokenAmount` (``amount``). An amount of a token type is an unsigned integer up to 2^256 - 1. + +It is serialized using the LEB128_ variable-length unsigned integer encoding, with the additional constraint of the total number of bytes of the encoding MUST not exceed 37 bytes:: + + TokenAmount ::= (x: Byte) => x if x < 2^7 + | (x: Byte) (m: TokenAmount) => (x - 2^7) + 2^7 * m if x >= 2^7 + +.. _LEB128: https://en.wikipedia.org/wiki/LEB128 + + +.. _CIS-5-MetadataUrl: + +``MetadataUrl`` +^^^^^^^^^^^^^^^ + +A URL and optional checksum for metadata stored outside of this contract. + +It is serialized as: 2 bytes for the length (``n``) of the metadata URL in little-endian and then this many bytes for the URL to the metadata (``url``) followed by an optional checksum. +The checksum is serialized by 1 byte to indicate whether a hash of the metadata is included. +If its value is 0, then there is no hash; if the value is 1, then 32 bytes for a SHA256 hash (``hash``) follows:: + + MetadataChecksum ::= (0: Byte) + | (1: Byte) (hash: Byte³²) + + MetadataUrl ::= (n: Byte²) (url: Byteⁿ) (checksum: MetadataChecksum) + +.. _CIS-5-ContractAddress: + +``ContractAddress`` +^^^^^^^^^^^^^^^^^^^ + +An address of a contract instance. +It consists of an index and a subindex, both unsigned 64-bit integers. + +It is serialized as: First 8 bytes for the index (``index``) followed by 8 bytes for the subindex (``subindex``), both little-endian:: + + ContractAddress ::= (index: Byte⁸) (subindex: Byte⁸) + + +.. _CIS-5-AccountAddress: + +``AccountAddress`` +^^^^^^^^^^^^^^^^^^ + +An address of an account. + +It is serialized as 32 bytes:: + + AccountAddress ::= (address: Byte³²) + +.. _CIS-5-EntrypointName: + +``EntrypointName`` +^^^^^^^^^^^^^^^^^^ + +A name for a smart contract function entrypoint. + +It is serialized as: First 2 bytes encode the length (``n``) of the entrypoint name in little-endian, followed by this many bytes for the entrypoint name (``entrypoint``):: + + EntrypointName ::= (n: Byte²) (entrypoint: Byteⁿ) + +.. _CIS-5-Timestamp: + +``Timestamp`` +^^^^^^^^^^^^^ + +A timestamp given in milliseconds since Unix epoch. +It consists of an unsigned 64-bit integer. + +It is serialized as 8 bytes in little-endian:: + + Timestamp ::= (milliseconds: Byte⁸) + +.. _CIS-5-Nonce: + +``Nonce`` +^^^^^^^^^ + +An unsigned 64-bit integer number that increases sequentially to protect against replay attacks. + +It is serialized as 8 bytes in little-endian:: + + Nonce ::= (nonce: Byte⁸) + +.. _CIS-5-CCDAmount: + +``CCDAmount`` +^^^^^^^^^^^^^ + +An unsigned 64-bit integer number. + +It is serialized as 8 bytes in little-endian:: + + CCDAmount ::= (ccdAmount: Byte⁸) + +.. _CIS-5-PublicKeyEd25519: + +``PublicKeyEd25519`` +^^^^^^^^^^^^^^^^^^^^ + +A public key is represented as a 32-byte array. + +It is serialized as 32 bytes:: + + PublicKeyEd25519 ::= (key: Byte³²) + +.. _CIS-5-SignatureEd25519: + +``SignatureEd25519`` +^^^^^^^^^^^^^^^^^^^^ + +Signature for an Ed25519 message. + +It is serialized as 64 bytes:: + + SignatureEd25519 ::= (signature: Byte⁶⁴) + +.. _CIS-5-SigningData: + +``SigningData`` +^^^^^^^^^^^^^^^ + +Signing data contains metadata for the signature that is used to check whether the signed message is designated for the correct contract and entrypoint, and that it is not expired. + +It is serialized as :ref:`CIS-5-ContractAddress` (``contract_address``), :ref:`CIS-5-EntrypointName` (``entrypoint``), :ref:`CIS-5-Nonce` (``nonce``), and :ref:`CIS-5-Timestamp` (``timestamp``):: + + SigningData ::= (contract_address: ContractAddress) (entrypoint: EntrypointName) (nonce: Nonce) (timestamp: Timestamp) + +Logged events +------------- + +The event defined by this specification is serialized using one byte to discriminate it from other events logged by the smart contract. +Other events logged by the smart contract SHOULD NOT have a first byte colliding with the event defined by this specification. + +``NonceEvent`` +^^^^^^^^^^^^^^ + +A ``NonceEvent`` SHALL be logged for every signature checking function invoke. + +The ``NonceEvent`` is serialized as: First a byte with the value of 250, followed by the :ref:`CIS-5-Nonce` (``nonce``) that was used in the PermitMessage, and an :ref:`CIS-5-AccountAddress` (``sponsoree``):: + + NonceEvent ::= (250: Byte) (nonce: Nonce) (sponsoree: AccountAddress) + +``DepositNativeCurrencyEvent`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +A ``DepositNativeCurrencyEvent`` SHALL be logged for every `depositNativeCurrency` function invoke. + +The ``DepositNativeCurrencyEvent`` is serialized as: First a byte with the value of 249, followed by the :ref:`CIS-5-CCDAmount` (``amount``), and an :ref:`CIS-5-PublicKeyEd25519` (``beneficiary``):: + + DepositNativeCurrencyEvent ::= (249: Byte) (amount: CCDAmount) (beneficiary: PublicKeyEd25519) + +``DepositCis2TokensEvent`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +A ``DepositCis2TokensEvent`` SHALL be logged for every `depositCis2Tokens` function invoke. + +The ``DepositCis2TokensEvent`` is serialized as: First a byte with the value of 248, followed by the :ref:`CIS-5-CCDAmount` (``amount``), and an :ref:`CIS-5-PublicKeyEd25519` (``beneficiary``):: + + DepositCis2TokensEvent ::= (248: Byte) (amount: CCDAmount) (beneficiary: PublicKeyEd25519) + + + +.. _CIS-5-functions: + +Contract functions +------------------ + +A smart contract implementing this standard MUST export the following functions: + +- :ref:`CIS-5-functions-depositNativeCurrency` +- :ref:`CIS-5-functions-depositCis2Tokens` +- :ref:`CIS-5-functions-withdrawNativeCurrency` +- :ref:`CIS-5-functions-withdrawCis2Tokens` +- :ref:`CIS-5-functions-internalNativeCurrencyTransfer` +- :ref:`CIS-5-functions-internalCis2TokensTransfer` +- :ref:`CIS-5-functions-balanceOfNativeCurrency` +- :ref:`CIS-5-functions-balanceOfCis2Tokens` + + +.. _CIS-5-functions-depositNativeCurrency: + +``depositNativeCurrency`` +^^^^^^^^^^^^^^^^^^^^^^^^^ + +The function is payable and deposits/assigns the send CCDAmount (native currency) to a beneficiary (PublicKeyEd25519). + +Parameter +~~~~~~~~~ + +The parameter is a PublicKeyEd25519. + +See the serialization rules in :ref:`CIS-5-PublicKeyEd25519`. + +Requirements +~~~~~~~~~~~~ + +- The function MUST emit a `NonceEvent` and a `DepositEvent`. + +.. _CIS-5-functions-depositCis2Tokens: + +``depositCis2Tokens`` +^^^^^^^^^^^^^^^^^^^^^ +.. _CIS-5-functions-withdrawNativeCurrency: + +``withdrawNativeCurrency`` +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. _CIS-5-functions-withdrawCis2Tokens: + +``withdrawCis2Tokens`` +^^^^^^^^^^^^^^^^^^^^^^ +.. _CIS-5-functions-internalNativeCurrencyTransfer: + +``internalNativeCurrencyTransfer`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +.. _CIS-5-functions-internalCis2TokensTransfer: + +``internalCis2TokensTransfer`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +.. _CIS-5-functions-balanceOfNativeCurrency: + +``balanceOfNativeCurrency`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^ +.. _CIS-5-functions-balanceOfCis2Tokens: + +``balanceOfCis2Tokens`` +^^^^^^^^^^^^^^^^^^^^^^^^^ From cc99a755c43039bdff5dd10e94f855378f879234 Mon Sep 17 00:00:00 2001 From: Doris Benda Date: Mon, 18 Mar 2024 20:11:03 +0200 Subject: [PATCH 03/10] Add native currency withdraw function --- source/CIS/cis-2.rst | 2 + source/CIS/cis-5.rst | 247 ++++++++++++++++++++++++++++++++++++------- 2 files changed, 213 insertions(+), 36 deletions(-) diff --git a/source/CIS/cis-2.rst b/source/CIS/cis-2.rst index a6692c5..933b2d7 100644 --- a/source/CIS/cis-2.rst +++ b/source/CIS/cis-2.rst @@ -745,6 +745,8 @@ The main argument is simplicity and to save energy cost on common cases, but oth The specification does not prevent adding more fine-grained authorization, such as token-level operators. +.. _CIS-2-Receive-Hook-Function: + Receive hook function --------------------- diff --git a/source/CIS/cis-5.rst b/source/CIS/cis-5.rst index 805c369..68ec29a 100644 --- a/source/CIS/cis-5.rst +++ b/source/CIS/cis-5.rst @@ -1,8 +1,8 @@ .. _CIS-5: -===================================== -CIS-5: Smart Contract Wallet Standard -===================================== +========================================================= +CIS-5: Smart Contract Wallet Standard (Chaperone Account) +========================================================= .. list-table:: :stub-columns: 1 @@ -44,7 +44,7 @@ The three main actions in the smart contract that can be taken: - *withdraw*: withdraws the balance out of the smart contract wallet to a native account or smart contract. The goal of this standard is to simplify the account creation onboarding flow on Concordium -allowing for CIS5 smart contract wallets to be supported as first-class citizens on Concordium wallets and tooling. +allowing for CIS5 smart contract wallets to be supported as first-class citizens in Concordium wallets and tooling. Specification ============= @@ -63,7 +63,7 @@ General types and serialization ``TokenID`` ^^^^^^^^^^^ -- The token ID SHALL be able to encode all possible tokenIds from the :ref:`CIS-2-TokenID` (``tokenId``) +- The token ID SHALL be able to encode all possible Token IDs from the ``CIS-2 TokenID standard`` (:ref:`CIS-2-TokenID`) A token ID is serialized as 1 byte for the size (``n``) of the identifier, followed by this number of bytes for the token id (``id``):: @@ -71,15 +71,16 @@ A token ID is serialized as 1 byte for the size (``n``) of the identifier, follo .. note:: - Token IDs can be as small as a single byte (by setting the first byte to the value 0) or as big as 256 bytes leaving more than 10^614 possible token IDs. - The token ID in the CIS5 standard needs to be able to encode up to 256 bytes long tokenIds. + Token IDs (as defined in the CIS-2 standard) can be as small as a single byte (by setting the first byte to the value 0) + or as big as 256 bytes. + The token ID in the CIS5 standard needs to be able to encode up to 256 bytes long Token IDs as a result. .. _CIS-5-TokenAmount: ``TokenAmount`` ^^^^^^^^^^^^^^^ -- The token amount SHALL be able to encode all possible tokenAmounts from the :ref:`CIS-2-TokenAmount` (``amount``). An amount of a token type is an unsigned integer up to 2^256 - 1. +- The token amount SHALL be able to encode all possible tokenAmounts from the ``CIS-2 TokenAmount standard`` (:ref:`CIS-2-TokenAmount`). An amount of a token type is an unsigned integer up to 2^256 - 1. It is serialized using the LEB128_ variable-length unsigned integer encoding, with the additional constraint of the total number of bytes of the encoding MUST not exceed 37 bytes:: @@ -88,22 +89,16 @@ It is serialized using the LEB128_ variable-length unsigned integer encoding, wi .. _LEB128: https://en.wikipedia.org/wiki/LEB128 +.. _CIS-5-AccountAddress: -.. _CIS-5-MetadataUrl: - -``MetadataUrl`` -^^^^^^^^^^^^^^^ - -A URL and optional checksum for metadata stored outside of this contract. +``AccountAddress`` +^^^^^^^^^^^^^^^^^^ -It is serialized as: 2 bytes for the length (``n``) of the metadata URL in little-endian and then this many bytes for the URL to the metadata (``url``) followed by an optional checksum. -The checksum is serialized by 1 byte to indicate whether a hash of the metadata is included. -If its value is 0, then there is no hash; if the value is 1, then 32 bytes for a SHA256 hash (``hash``) follows:: +An address of an account. - MetadataChecksum ::= (0: Byte) - | (1: Byte) (hash: Byte³²) +It is serialized as 32 bytes:: - MetadataUrl ::= (n: Byte²) (url: Byteⁿ) (checksum: MetadataChecksum) + AccountAddress ::= (address: Byte³²) .. _CIS-5-ContractAddress: @@ -117,17 +112,20 @@ It is serialized as: First 8 bytes for the index (``index``) followed by 8 bytes ContractAddress ::= (index: Byte⁸) (subindex: Byte⁸) +.. _CIS-5-Address: -.. _CIS-5-AccountAddress: +``Address`` +^^^^^^^^^^^ -``AccountAddress`` -^^^^^^^^^^^^^^^^^^ +Is either an :ref:`CIS-5-AccountAddress` or a :ref:`CIS-5-ContractAddress`. -An address of an account. +It is serialized as: First byte indicates whether it is an account address or a contract address. +In case the first byte is 0 then an :ref:`CIS-5-AccountAddress` (``address``) follows. +In case the first byte is 1 then a :ref:`CIS-5-ContractAddress` (``address``) follows:: -It is serialized as 32 bytes:: + Address ::= (0: Byte) (address: AccountAddress) + | (1: Byte) (address: ContractAddress) - AccountAddress ::= (address: Byte³²) .. _CIS-5-EntrypointName: @@ -179,7 +177,7 @@ It is serialized as 8 bytes in little-endian:: ``PublicKeyEd25519`` ^^^^^^^^^^^^^^^^^^^^ -A public key is represented as a 32-byte array. +An Ed25519 public key is represented as a 32-byte array. It is serialized as 32 bytes:: @@ -227,18 +225,60 @@ The ``NonceEvent`` is serialized as: First a byte with the value of 250, followe A ``DepositNativeCurrencyEvent`` SHALL be logged for every `depositNativeCurrency` function invoke. -The ``DepositNativeCurrencyEvent`` is serialized as: First a byte with the value of 249, followed by the :ref:`CIS-5-CCDAmount` (``amount``), and an :ref:`CIS-5-PublicKeyEd25519` (``beneficiary``):: +The ``DepositNativeCurrencyEvent`` is serialized as: First a byte with the value of 249, followed by the :ref:`CIS-5-CCDAmount` (``ccdAmount``), the :ref:`CIS-5-Address` (``from``), and a :ref:`CIS-5-PublicKeyEd25519` (``to``):: - DepositNativeCurrencyEvent ::= (249: Byte) (amount: CCDAmount) (beneficiary: PublicKeyEd25519) + DepositNativeCurrencyEvent ::= (249: Byte) (ccdAmount: CCDAmount) (from: Address) (to: PublicKeyEd25519) ``DepositCis2TokensEvent`` -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +^^^^^^^^^^^^^^^^^^^^^^^^^^ A ``DepositCis2TokensEvent`` SHALL be logged for every `depositCis2Tokens` function invoke. -The ``DepositCis2TokensEvent`` is serialized as: First a byte with the value of 248, followed by the :ref:`CIS-5-CCDAmount` (``amount``), and an :ref:`CIS-5-PublicKeyEd25519` (``beneficiary``):: +The ``DepositCis2TokensEvent`` is serialized as: First a byte with the value of 248, followed by the +:ref:`CIS-5-TokenAmount` (``tokenAmount``), :ref:`CIS-5-TokenID` (``TokenID``), +:ref:`CIS-5-ContractAddress` (``contractAddress``), the :ref:`CIS-5-Address` (``from``), and a :ref:`CIS-5-PublicKeyEd25519` (``to``):: + + DepositCis2TokensEvent ::= (248: Byte) (tokenAmount: TokenAmount) (tokenId: TokenID) (contractAddress: ContractAddress) (from: Address) (to: PublicKeyEd25519) + +``WithdrawNativeCurrencyEvent`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +A ``WithdrawNativeCurrencyEvent`` SHALL be logged for every `withdrawNativeCurrency` function invoke. + +The ``WithdrawNativeCurrencyEvent`` is serialized as: First a byte with the value of 247, followed by the :ref:`CIS-5-CCDAmount` (``ccdAmount``), a :ref:`CIS-5-PublicKeyEd25519` (``from``), and the :ref:`CIS-5-Address` (``to``):: + + DepositNativeCurrencyEvent ::= (247: Byte) (ccdAmount: CCDAmount) (from: PublicKeyEd25519) (to: Address) + +``WithdrawCis2TokensEvent`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +A ``WithdrawCis2TokensEvent`` SHALL be logged for every `withdrawCis2Tokens` function invoke. + +The ``WithdrawCis2TokensEvent`` is serialized as: First a byte with the value of 246, followed by the +:ref:`CIS-5-TokenAmount` (``tokenAmount``), :ref:`CIS-5-TokenID` (``TokenID``), +:ref:`CIS-5-ContractAddress` (``contractAddress``), a :ref:`CIS-5-PublicKeyEd25519` (``from``), and the :ref:`CIS-5-Address` (``to``):: + + WithdrawCis2TokensEvent ::= (246: Byte) (tokenAmount: TokenAmount) (tokenId: TokenID) (contractAddress: ContractAddress) (from: PublicKeyEd25519) (to: Address) + +``InternalNativeCurrencyTransferEvent`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +A ``InternalNativeCurrencyTransferEvent`` SHALL be logged for every `internalNativeCurrencyTransfer` function invoke. + +The ``InternalNativeCurrencyTransferEvent`` is serialized as: First a byte with the value of 245, followed by the :ref:`CIS-5-CCDAmount` (``ccdAmount``), a :ref:`CIS-5-PublicKeyEd25519` (``from``), and the :ref:`CIS-5-PublicKeyEd25519` (``to``):: - DepositCis2TokensEvent ::= (248: Byte) (amount: CCDAmount) (beneficiary: PublicKeyEd25519) + InternalNativeCurrencyTransferEvent ::= (245: Byte) (ccdAmount: CCDAmount) (from: PublicKeyEd25519) (to: PublicKeyEd25519) + +``InternalCis2TokensTransferEvent`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +A ``InternalCis2TokensTransferEvent`` SHALL be logged for every `internalCis2TokensTransfer` function invoke. + +The ``InternalCis2TokensTransferEvent`` is serialized as: First a byte with the value of 244, followed by the +:ref:`CIS-5-TokenAmount` (``tokenAmount``), :ref:`CIS-5-TokenID` (``TokenID``), +:ref:`CIS-5-ContractAddress` (``contractAddress``), a :ref:`CIS-5-PublicKeyEd25519` (``from``), and the :ref:`CIS-5-PublicKeyEd25519` (``to``):: + + InternalCis2TokensTransferEvent ::= (244: Byte) (tokenAmount: TokenAmount) (tokenId: TokenID) (contractAddress: ContractAddress) (from: PublicKeyEd25519) (to: PublicKeyEd25519) @@ -264,46 +304,181 @@ A smart contract implementing this standard MUST export the following functions: ``depositNativeCurrency`` ^^^^^^^^^^^^^^^^^^^^^^^^^ -The function is payable and deposits/assigns the send CCDAmount (native currency) to a beneficiary (PublicKeyEd25519). +The function is payable and deposits/assigns the send CCDAmount (native currency) to a public key (``PublicKeyEd25519``). Parameter ~~~~~~~~~ -The parameter is a PublicKeyEd25519. +The parameter is a ``PublicKeyEd25519``. See the serialization rules in :ref:`CIS-5-PublicKeyEd25519`. Requirements ~~~~~~~~~~~~ -- The function MUST emit a `NonceEvent` and a `DepositEvent`. +- The function MUST emit a ``DepositNativeCurrencyEvent``. .. _CIS-5-functions-depositCis2Tokens: ``depositCis2Tokens`` ^^^^^^^^^^^^^^^^^^^^^ + +This function SHOULD be called through the receive hook mechanism (:ref:`CIS-2-Receive-Hook-Function`) +of a CIS-2 token contract. The function deposits/assigns the send CIS-2 token amount to a public key (``PublicKeyEd25519``). + +.. note:: + + If a use case wants to mint and deposit tokens to a public key in one transaction. + The CIS2 token has to have a mint function that calls this smart contract wallet ``depositCis2Tokens`` function via a hook mechanism. + +.. note:: + + The ``depositCis2Tokens`` function can be called by any smart contract. It is up to the exact implementation of the smart contract wallet whether it should trust the caller or not. + The smart contract wallet is not required to check if the invoking contract is a CIS-2 token contract or has some reasonable receive hook logic implemented. + If no additional authorization is added to this function, similar caution should be applied as if you would directly interact with any CIS-2 token contract. + Only interact with a CIS-2 token contract or value its recorded token balance if you checked its smart + contract logic or reasonable social reputation are given to the project/CIS-2 token contract. + +Parameter +~~~~~~~~~ + +The parameter is the :ref:`CIS-2-functions-transfer-receive-hook-parameter` (``OnReceivingCis2Params``) and the +``data`` field of the ``OnReceivingCis2Params`` SHALL encode a ``PublicKeyEd25519``. + +See the serialization rules in :ref:`CIS-2-functions-transfer-receive-hook-parameter` +and the serialization rules in :ref:`CIS-5-PublicKeyEd25519`. + +Requirements +~~~~~~~~~~~~ + +- The function MUST emit a ``DepositCis2TokensEvent``. +- The function SHOULD check that a contract is the caller since only a contract can implement a receive hook mechanism. + .. _CIS-5-functions-withdrawNativeCurrency: ``withdrawNativeCurrency`` ^^^^^^^^^^^^^^^^^^^^^^^^^^ +Executes a withdrawal of CCDs (native currency) to a native account or smart contract out of the smart contract wallet. +When transferring CCD to a contract address, a ccd receive hook function MUST be triggered. + + +Parameter +~~~~~~~~~ + +The parameter is the ``NativeCurrencyWithdrawParameter``. + +It is serialized as: a :ref:`CIS-5-PublicKeyEd25519` (``signer``), a :ref:`CIS-5-SignatureEd25519` (``signature``), +a :ref:`CIS-5-TimeStamp` (``expiryTime``), a :ref:`CIS-5-Nonce` (``nonce``), a :ref:`CIS-5-CCDAmount` (``serviceFee``), an :ref:`CIS-5-Address` (``serviceFeeRecipient``), +the receiving address :ref:`CIS-2-Receiver` (``to``), a :ref:`CIS-5-CCDAmount` (``ccdAmount``), and some additional data :ref:`CIS-2-AdditionalData` (``data``):: + + NativeCurrencyWithdrawParameter ::= (signer: PublicKeyEd25519) (signature: SignatureEd25519) (expiryTime: TimeStamp) (nonce: u64) (serviceFee: CCDAmount) (serviceFeeRecipient: Address) (to: Receiver) (ccdAmount: CCDAmount) (data: AdditionalData) + +.. _CIS-5-functions-transfer-ccd-receive-hook-parameter: + +CCD Receive hook parameter +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The parameter for the ccd receive hook function contains information about the transfer and some additional data bytes. + +It is serialized as: a :ref:`CIS-5-CCDAmount` (``ccdAmount``), a :ref:`CIS-5-PublicKeyEd25519` (``from``), and some aditional data :ref:`CIS-2-AdditionalData` (``data``):: + + CCDReceiveHookParameter ::= (ccdAmount: CCDAmount) (from: PublicKeyEd25519) (data: AdditionalData) + + +Requirements +~~~~~~~~~~~~ + +- The function MUST emit a ``NonceEvent`` and a ``WithdrawNativeCurrencyEvent``. +- The function MUST reject if the signature verification fails. + +- The withdrawal MUST fail, if the CCD balance of the ``signer`` is insufficient to do the withdrawal. +- A withdrawal MUST non-strictly decrease the CCD balance of the ``signer`` public key and non-strictly increase the balance of the ``to`` address or fail. +- A withdrawal back to this contract into the ``depositNativeCurrency`` entrypoint MUST be executed as a normal withdrawal. +- A withdrawal of a CCD amount of zero MUST be executed as a normal withdrawal. +- A withdrawal of any amount of CCD to a contract address MUST call a ccd receive hook function on the receiving smart contract with a :ref:`ccd receive hook parameter`. +- The contract function MUST reject if the ccd receive hook function called on the contract receiving CCDs rejects. +- The balance of a public key not owning any CCD amount SHOULD be treated as having a balance of zero. + +.. warning:: + + Be aware of transferring CCDs to a non-existing account address or contract address. + This specification by itself does not include a standard that has to be followed. + Checking the existence of an account address/ contract address would ideally be done off-chain before the message is even sent to the smart contract. + .. _CIS-5-functions-withdrawCis2Tokens: ``withdrawCis2Tokens`` ^^^^^^^^^^^^^^^^^^^^^^ + +Parameter +~~~~~~~~~ + + +Requirements +~~~~~~~~~~~~ + +- The function MUST emit a ``NonceEvent`` and a ``WithdrawCis2TokensEvent``. +- The function MUST reject if the signature verification fails. +- This function has to call a ``transfer`` function on the cis2 token contract. + + + .. _CIS-5-functions-internalNativeCurrencyTransfer: ``internalNativeCurrencyTransfer`` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Parameter +~~~~~~~~~ + + +Requirements +~~~~~~~~~~~~ + +- The function MUST emit a `NonceEvent` and a `InternalNativeCurrencyTransferEvent`. +- The function MUST reject if the signature verification fails. + + .. _CIS-5-functions-internalCis2TokensTransfer: ``internalCis2TokensTransfer`` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Parameter +~~~~~~~~~ + + +Requirements +~~~~~~~~~~~~ + +- The function MUST emit a ``NonceEvent`` and a ``InternalCis2TokensTransferEvent``. +- The function MUST reject if the signature verification fails. + .. _CIS-5-functions-balanceOfNativeCurrency: + ``balanceOfNativeCurrency`` ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Parameter +~~~~~~~~~ + + +Requirements +~~~~~~~~~~~~ + + .. _CIS-5-functions-balanceOfCis2Tokens: + ``balanceOfCis2Tokens`` -^^^^^^^^^^^^^^^^^^^^^^^^^ +^^^^^^^^^^^^^^^^^^^^^^^ + +Parameter +~~~~~~~~~ + + +Requirements +~~~~~~~~~~~~ + From 3453a7d82b16c0cf5e36a089ce6308adc209f750 Mon Sep 17 00:00:00 2001 From: Doris Benda Date: Mon, 18 Mar 2024 20:46:23 +0200 Subject: [PATCH 04/10] Add withdrawCis2Tokens function --- source/CIS/cis-5.rst | 55 +++++++++++++++++++++++++++++++------------- source/index.rst | 4 ++++ 2 files changed, 43 insertions(+), 16 deletions(-) diff --git a/source/CIS/cis-5.rst b/source/CIS/cis-5.rst index 68ec29a..ae518ca 100644 --- a/source/CIS/cis-5.rst +++ b/source/CIS/cis-5.rst @@ -359,20 +359,23 @@ Requirements ``withdrawNativeCurrency`` ^^^^^^^^^^^^^^^^^^^^^^^^^^ -Executes a withdrawal of CCDs (native currency) to a native account or smart contract out of the smart contract wallet. +Executes a list of token withdrawals of CCDs (native currency) to native accounts and/or smart contracts out of the smart contract wallet. When transferring CCD to a contract address, a ccd receive hook function MUST be triggered. - Parameter ~~~~~~~~~ -The parameter is the ``NativeCurrencyWithdrawParameter``. +The parameter is a list of withdrawals. + +It is serialized as: 2 bytes representing the number of withdrawals (``n``) followed by the bytes for this number of withdrawals. -It is serialized as: a :ref:`CIS-5-PublicKeyEd25519` (``signer``), a :ref:`CIS-5-SignatureEd25519` (``signature``), +Each withdrawal is serialized as: a :ref:`CIS-5-PublicKeyEd25519` (``signer``), a :ref:`CIS-5-SignatureEd25519` (``signature``), a :ref:`CIS-5-TimeStamp` (``expiryTime``), a :ref:`CIS-5-Nonce` (``nonce``), a :ref:`CIS-5-CCDAmount` (``serviceFee``), an :ref:`CIS-5-Address` (``serviceFeeRecipient``), the receiving address :ref:`CIS-2-Receiver` (``to``), a :ref:`CIS-5-CCDAmount` (``ccdAmount``), and some additional data :ref:`CIS-2-AdditionalData` (``data``):: - NativeCurrencyWithdrawParameter ::= (signer: PublicKeyEd25519) (signature: SignatureEd25519) (expiryTime: TimeStamp) (nonce: u64) (serviceFee: CCDAmount) (serviceFeeRecipient: Address) (to: Receiver) (ccdAmount: CCDAmount) (data: AdditionalData) + NativeCurrencyWithdrawal ::= (signer: PublicKeyEd25519) (signature: SignatureEd25519) (expiryTime: TimeStamp) (nonce: u64) (serviceFee: CCDAmount) (serviceFeeRecipient: Address) (to: Receiver) (ccdAmount: CCDAmount) (data: AdditionalData) + + NativeCurrencyWithdrawParameter ::= (n: Byte²) (withdrawal: NativeCurrencyWithdrawalⁿ) .. _CIS-5-functions-transfer-ccd-receive-hook-parameter: @@ -389,15 +392,16 @@ It is serialized as: a :ref:`CIS-5-CCDAmount` (``ccdAmount``), a :ref:`CIS-5-Pub Requirements ~~~~~~~~~~~~ -- The function MUST emit a ``NonceEvent`` and a ``WithdrawNativeCurrencyEvent``. -- The function MUST reject if the signature verification fails. - -- The withdrawal MUST fail, if the CCD balance of the ``signer`` is insufficient to do the withdrawal. -- A withdrawal MUST non-strictly decrease the CCD balance of the ``signer`` public key and non-strictly increase the balance of the ``to`` address or fail. +- The list of withdrawals MUST be executed in order. +- The contract function MUST reject if any of the withdrawals fail to be executed. +- The function MUST emit a ``NonceEvent`` and a ``WithdrawNativeCurrencyEvent`` for every withdrawal. +- The function MUST reject if the signature verification fails for any withdrawal. +- The function MUST fail, if the CCD balance of the ``signer`` is insufficient to do the withdrawal for any withdrawal. +- A function MUST non-strictly decrease the CCD balance of the ``signer`` public key and non-strictly increase the balance of the ``to`` address or fail for any withdrawal. - A withdrawal back to this contract into the ``depositNativeCurrency`` entrypoint MUST be executed as a normal withdrawal. - A withdrawal of a CCD amount of zero MUST be executed as a normal withdrawal. - A withdrawal of any amount of CCD to a contract address MUST call a ccd receive hook function on the receiving smart contract with a :ref:`ccd receive hook parameter`. -- The contract function MUST reject if the ccd receive hook function called on the contract receiving CCDs rejects. +- The contract function MUST reject if the ccd receive hook function called on the contract receiving CCDs rejects for any withdrawal. - The balance of a public key not owning any CCD amount SHOULD be treated as having a balance of zero. .. warning:: @@ -411,18 +415,37 @@ Requirements ``withdrawCis2Tokens`` ^^^^^^^^^^^^^^^^^^^^^^ +Executes a list of token withdrawals to native accounts and/or smart contracts out of the smart contract wallet. +This function MUST call the ``transfer`` function on the CIS-2 token contract for every withdrawal. + Parameter ~~~~~~~~~ +The parameter is a list of withdrawals. -Requirements -~~~~~~~~~~~~ +It is serialized as: 2 bytes representing the number of withdrawals (``n``) followed by the bytes for this number of withdrawals. -- The function MUST emit a ``NonceEvent`` and a ``WithdrawCis2TokensEvent``. -- The function MUST reject if the signature verification fails. -- This function has to call a ``transfer`` function on the cis2 token contract. +Each withdrawal is serialized as: a :ref:`CIS-5-PublicKeyEd25519` (``signer``), a :ref:`CIS-5-SignatureEd25519` (``signature``), +a :ref:`CIS-5-TimeStamp` (``expiryTime``), a :ref:`CIS-5-Nonce` (``nonce``), a :ref:`CIS-5-CCDAmount` (``serviceFee``), an :ref:`CIS-5-Address` (``serviceFeeRecipient``), +the receiving address :ref:`CIS-2-Receiver` (``to``), a :ref:`CIS-5-TokenAmount` (``tokenAmount``), a :ref:`CIS-5-TokenID` (``tokenID``), a :ref:`CIS-5-ContractAddress` (``cis2TokenContractAddress``), and some additional data :ref:`CIS-2-AdditionalData` (``data``):: + + Cis2TokensWithdrawal ::= (signer: PublicKeyEd25519) (signature: SignatureEd25519) (expiryTime: TimeStamp) (nonce: u64) (serviceFee: CCDAmount) (serviceFeeRecipient: Address) (to: Receiver) (tokenAmount: tokenAmount) (tokenId: tokenID) (cis2TokenContractAddress: ContractAddress) (data: AdditionalData) + Cis2TokensWithdrawParameter ::= (n: Byte²) (withdrawal: Cis2TokensWithdrawalⁿ) + +Requirements +~~~~~~~~~~~~ +- The list of withdrawals MUST be executed in order. +- The contract function MUST reject if any of the withdrawals fail to be executed. +- The function MUST emit a ``NonceEvent`` and a ``WithdrawCis2TokensEvent`` for every withdrawal. +- The function MUST reject if the signature verification fails for any withdrawal. +- This function MUST call the ``transfer`` function on the CIS-2 token contract for every withdrawal. +- The function MUST fail, if the token balance of the ``signer`` is insufficient to do the withdrawal for any withdrawal. +- A function MUST non-strictly decrease the token balance of the ``signer`` public key and non-strictly increase the balance of the ``to`` address or fail for any withdrawal. +- A withdrawal back to this contract into the ``depositCis2Tokens`` entrypoint MUST be executed as a normal withdrawal. +- A withdrawal of a token amount of zero MUST be executed as a normal withdrawal. +- The balance of a public key not owning any tokens SHOULD be treated as having a balance of zero. .. _CIS-5-functions-internalNativeCurrencyTransfer: diff --git a/source/index.rst b/source/index.rst index 0c0b33a..e11ace6 100644 --- a/source/index.rst +++ b/source/index.rst @@ -22,4 +22,8 @@ Concordium Interoperability Specifications CIS/cis-3 CIS/cis-4 CIS/cis-5 +<<<<<<< HEAD CIS/cis-6 +======= + ID/concordium-did.rst +>>>>>>> fb33efb (Add withdrawCis2Tokens function) From d7c329d34e897bfb5ff0710ab47f0c8442d169f6 Mon Sep 17 00:00:00 2001 From: Doris Benda Date: Tue, 19 Mar 2024 10:44:21 +0200 Subject: [PATCH 05/10] Add internal transfer functions and balance of functions --- source/CIS/cis-5.rst | 99 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 90 insertions(+), 9 deletions(-) diff --git a/source/CIS/cis-5.rst b/source/CIS/cis-5.rst index ae518ca..e819862 100644 --- a/source/CIS/cis-5.rst +++ b/source/CIS/cis-5.rst @@ -359,7 +359,7 @@ Requirements ``withdrawNativeCurrency`` ^^^^^^^^^^^^^^^^^^^^^^^^^^ -Executes a list of token withdrawals of CCDs (native currency) to native accounts and/or smart contracts out of the smart contract wallet. +The function executes a list of token withdrawals of CCDs (native currency) to native accounts and/or smart contracts out of the smart contract wallet. When transferring CCD to a contract address, a ccd receive hook function MUST be triggered. Parameter @@ -403,6 +403,7 @@ Requirements - A withdrawal of any amount of CCD to a contract address MUST call a ccd receive hook function on the receiving smart contract with a :ref:`ccd receive hook parameter`. - The contract function MUST reject if the ccd receive hook function called on the contract receiving CCDs rejects for any withdrawal. - The balance of a public key not owning any CCD amount SHOULD be treated as having a balance of zero. +- The function MUST transfer the ``serviceFee`` to the ``serviceFeeRecipient`` for every withdrawal. .. warning:: @@ -415,7 +416,7 @@ Requirements ``withdrawCis2Tokens`` ^^^^^^^^^^^^^^^^^^^^^^ -Executes a list of token withdrawals to native accounts and/or smart contracts out of the smart contract wallet. +The function executes a list of token withdrawals to native accounts and/or smart contracts out of the smart contract wallet. This function MUST call the ``transfer`` function on the CIS-2 token contract for every withdrawal. Parameter @@ -446,62 +447,142 @@ Requirements - A withdrawal back to this contract into the ``depositCis2Tokens`` entrypoint MUST be executed as a normal withdrawal. - A withdrawal of a token amount of zero MUST be executed as a normal withdrawal. - The balance of a public key not owning any tokens SHOULD be treated as having a balance of zero. +- The function MUST transfer the ``serviceFee`` to the ``serviceFeeRecipient`` for every withdrawal. .. _CIS-5-functions-internalNativeCurrencyTransfer: ``internalNativeCurrencyTransfer`` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +The function executes a list of CCD internal transfers to public keys within the smart contract wallet. Parameter ~~~~~~~~~ +The parameter is a list of internal transfers. + +It is serialized as: 2 bytes representing the number of transfers (``n``) followed by the bytes for this number of internal transfers. + +Each transfer is serialized as: a :ref:`CIS-5-PublicKeyEd25519` (``signer``), a :ref:`CIS-5-SignatureEd25519` (``signature``), +a :ref:`CIS-5-TimeStamp` (``expiryTime``), a :ref:`CIS-5-Nonce` (``nonce``), a :ref:`CIS-5-CCDAmount` (``serviceFee``), an :ref:`CIS-5-Address` (``serviceFeeRecipient``), +a :ref:`CIS-5-PublicKeyEd25519` (``from``), a :ref:`CIS-5-PublicKeyEd25519` (``to``), and a :ref:`CIS-5-CCDAmount` (``ccdAmount``):: + + NativeCurrencyInternalTransfer ::= (signer: PublicKeyEd25519) (signature: SignatureEd25519) (expiryTime: TimeStamp) (nonce: u64) (serviceFee: CCDAmount) (serviceFeeRecipient: Address) (from: PublicKeyEd25519) (to: PublicKeyEd25519) (ccdAmount: CCDAmount) + NativeCurrencyInternalTransferParameter ::= (n: Byte²) (transfer: NativeCurrencyInternalTransfer) + Requirements ~~~~~~~~~~~~ -- The function MUST emit a `NonceEvent` and a `InternalNativeCurrencyTransferEvent`. -- The function MUST reject if the signature verification fails. - +- The function MUST emit a ``NonceEvent`` and a ``InternalNativeCurrencyTransferEvent`` for every transfer. +- The function MUST reject if the signature verification fails for any transfer. +- The function MUST fail, if the CCD balance of the ``signer`` is insufficient to do the tranfser for any transfer. +- A function MUST non-strictly decrease the CCD balance of the ``signer`` public key and non-strictly increase the balance of the ``to`` address or fail for any transfer. +- A transfer of a CCD amount of zero MUST be executed as a normal transfer. +- The balance of a public key not owning any CCD amount SHOULD be treated as having a balance of zero. +- The function MUST transfer the ``serviceFee`` to the ``serviceFeeRecipient`` for every transfer. .. _CIS-5-functions-internalCis2TokensTransfer: ``internalCis2TokensTransfer`` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +The function executes a list of token internal transfers to public keys within the smart contract wallet. + Parameter ~~~~~~~~~ +The parameter is a list of internal transfers. + +It is serialized as: 2 bytes representing the number of transfers (``n``) followed by the bytes for this number of internal transfers. + +Each transfer is serialized as: a :ref:`CIS-5-PublicKeyEd25519` (``signer``), a :ref:`CIS-5-SignatureEd25519` (``signature``), +a :ref:`CIS-5-TimeStamp` (``expiryTime``), a :ref:`CIS-5-Nonce` (``nonce``), a :ref:`CIS-5-CCDAmount` (``serviceFee``), an :ref:`CIS-5-Address` (``serviceFeeRecipient``), +a :ref:`CIS-5-PublicKeyEd25519` (``from``), a :ref:`CIS-5-PublicKeyEd25519` (``to``), a :ref:`CIS-5-TokenAmount` (``tokenAmount``), a :ref:`CIS-5-TokenID` (``tokenID``), and a :ref:`CIS-5-ContractAddress` (``cis2TokenContractAddress``):: + + Cis2TokensInternalTransfer ::= (signer: PublicKeyEd25519) (signature: SignatureEd25519) (expiryTime: TimeStamp) (nonce: u64) (serviceFee: CCDAmount) (serviceFeeRecipient: Address) (from: PublicKeyEd25519) (to: PublicKeyEd25519) (tokenAmount: tokenAmount) (tokenID: TokenID) (cis2TokenContractAddress: ContractAddress) + Cis2TokensInternalTransferParameter ::= (n: Byte²) (transfer: Cis2TokensInternalTransfer) + Requirements ~~~~~~~~~~~~ -- The function MUST emit a ``NonceEvent`` and a ``InternalCis2TokensTransferEvent``. -- The function MUST reject if the signature verification fails. +- The function MUST emit a ``NonceEvent`` and a ``InternalCis2TokensTransferEvent`` for every transfer. +- The function MUST reject if the signature verification fails for any of the transfers. +- The function MUST fail, if the token balance of the ``signer`` is insufficient to do the transfer for any transfer. +- A function MUST non-strictly decrease the token balance of the ``signer`` public key and non-strictly increase the balance of the ``to`` address or fail for any transfer. +- A transfer of a token amount of zero MUST be executed as a normal transfer. +- The balance of a public key not owning any tokens SHOULD be treated as having a balance of zero. +- The function MUST transfer the ``serviceFee`` to the ``serviceFeeRecipient`` for every transfer. .. _CIS-5-functions-balanceOfNativeCurrency: - ``balanceOfNativeCurrency`` ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +The function queries the CCD balances of a list of public keys. + Parameter ~~~~~~~~~ +The parameter consists of a list public keys. + +It is serialized as: 2 bytes for the number of queries (``n``) and then this number of queries (``queries``). +A query is serialized as a :ref:`CIS-5-PublicKeyEd25519` (``publicKey``):: + + NativeCurrencyBalanceOfQuery ::= (publicKey: PublicKeyEd25519) + + NativeCurrencyBalanceOfParameter ::= (n: Byte²) (queries: NativeCurrencyBalanceOfQueryⁿ) + +Response +~~~~~~~~ + +The function output response is a list of CCD amounts. + +It is serialized as: 2 bytes for the number of CCD amounts (``n``) and then this number of :ref:`CIS-5-CCDAmount` (``results``):: + + NativeCurrencyBalanceOfResponse ::= (n: Byte²) (results: CCDAmountⁿ) + Requirements ~~~~~~~~~~~~ +- The balance of a public key not owning any CCD SHOULD be treated as having a balance of zero. +- The number of results in the response MUST correspond to the number of the queries in the parameter. +- The order of results in the response MUST correspond to the order of queries in the parameter. +- The contract function MUST NOT increase or decrease the CCD balance or token balance of any public key for any token type. .. _CIS-5-functions-balanceOfCis2Tokens: - ``balanceOfCis2Tokens`` ^^^^^^^^^^^^^^^^^^^^^^^ +The function queries the token balances of a list of public keys for given token IDs, and CIS-2 token contract addresses. + Parameter ~~~~~~~~~ +The parameter consists of a list of token ID, CIS-2 token contract address, and public key triplets. + +It is serialized as: 2 bytes for the number of queries (``n``) and then this number of queries (``queries``). +A query is serialized as a :ref:`CIS-5-TokenID` (``tokenID``), a :ref:`CIS-5-ContractAddress` (``cis2TokenContractAddress``), and a :ref:`CIS-5-PublicKeyEd25519` (``publicKey``):: + + Cis2TokensBalanceOfQuery ::= (tokenID: TokenID) (cis2TokenContractAddress: ContractAddress) (publicKey: PublicKeyEd25519) + + Cis2TokensBalanceOfParameter ::= (n: Byte²) (queries: Cis2TokensBalanceOfQueryⁿ) + +Response +~~~~~~~~ + +The function output response is a list of token amounts. + +It is serialized as: 2 bytes for the number of token amounts (``n``) and then this number of :ref:`CIS-5-TokenAmount` (``results``):: + + Cis2TokensBalanceOfResponse ::= (n: Byte²) (results: TokenAmountⁿ) Requirements ~~~~~~~~~~~~ +- The balance of an public key not owning any amount of a token type SHOULD be treated as having a balance of zero. +- The number of results in the response MUST correspond to the number of the queries in the parameter. +- The order of results in the response MUST correspond to the order of queries in the parameter. +- The contract function MUST NOT increase or decrease the CCD balance or token balance of any public key for any token type. From 6655ff2b024d56730da18a6975e711a28de633d4 Mon Sep 17 00:00:00 2001 From: Doris Benda Date: Tue, 19 Mar 2024 13:54:20 +0200 Subject: [PATCH 06/10] Fix small typos --- source/CIS/cis-5.rst | 83 +++++++++++++++++++++++++------------------- 1 file changed, 47 insertions(+), 36 deletions(-) diff --git a/source/CIS/cis-5.rst b/source/CIS/cis-5.rst index e819862..c84d7c0 100644 --- a/source/CIS/cis-5.rst +++ b/source/CIS/cis-5.rst @@ -22,8 +22,8 @@ CIS-5: Smart Contract Wallet Standard (Chaperone Account) Abstract ======== -A standard interface for defining a smart contract wallet that can hold and transfer native currency and cis2 tokens. -Native currency/Cis2 tokens can be deposited into the smart contract wallet by +A standard interface for defining a smart contract wallet that can hold and transfer native currency and CIS-2 tokens. +Native currency/CIS-2 tokens can be deposited into the smart contract wallet by specifying to which public key the deposit should be assigned. The holder of the corresponding private key is the only entity that can authorize @@ -31,7 +31,7 @@ to transfer tokens/currency in a self-custodial manner from the public key balance (assigned in the smart contract) to some new accounts/smart contracts/public keys. The holder of the corresponding private key does not have to submit transactions -on chain to transfer its native currency/cis2 token balance, +on chain to transfer its native currency/CIS-2 token balance, but instead, it can generate a valid signature, identify a willing third party to submit its signature on-chain (a service fee can be added to financially incentivize a third party to do so). @@ -44,7 +44,7 @@ The three main actions in the smart contract that can be taken: - *withdraw*: withdraws the balance out of the smart contract wallet to a native account or smart contract. The goal of this standard is to simplify the account creation onboarding flow on Concordium -allowing for CIS5 smart contract wallets to be supported as first-class citizens in Concordium wallets and tooling. +allowing for CIS-5 smart contract wallets to be supported as first-class citizens in Concordium wallets and tooling. Specification ============= @@ -73,7 +73,7 @@ A token ID is serialized as 1 byte for the size (``n``) of the identifier, follo Token IDs (as defined in the CIS-2 standard) can be as small as a single byte (by setting the first byte to the value 0) or as big as 256 bytes. - The token ID in the CIS5 standard needs to be able to encode up to 256 bytes long Token IDs as a result. + The token ID in the CIS-5 standard needs to be able to encode up to 256 bytes long Token IDs as a result. .. _CIS-5-TokenAmount: @@ -82,7 +82,7 @@ A token ID is serialized as 1 byte for the size (``n``) of the identifier, follo - The token amount SHALL be able to encode all possible tokenAmounts from the ``CIS-2 TokenAmount standard`` (:ref:`CIS-2-TokenAmount`). An amount of a token type is an unsigned integer up to 2^256 - 1. -It is serialized using the LEB128_ variable-length unsigned integer encoding, with the additional constraint of the total number of bytes of the encoding MUST not exceed 37 bytes:: +It is serialized using the LEB128_ variable-length unsigned integer encoding, with the additional constraint that the total number of bytes of the encoding MUST not exceed 37 bytes:: TokenAmount ::= (x: Byte) => x if x < 2^7 | (x: Byte) (m: TokenAmount) => (x - 2^7) + 2^7 * m if x >= 2^7 @@ -119,7 +119,7 @@ It is serialized as: First 8 bytes for the index (``index``) followed by 8 bytes Is either an :ref:`CIS-5-AccountAddress` or a :ref:`CIS-5-ContractAddress`. -It is serialized as: First byte indicates whether it is an account address or a contract address. +It is serialized as: The first byte indicates whether it is an account address or a contract address. In case the first byte is 0 then an :ref:`CIS-5-AccountAddress` (``address``) follows. In case the first byte is 1 then a :ref:`CIS-5-ContractAddress` (``address``) follows:: @@ -201,9 +201,20 @@ It is serialized as 64 bytes:: Signing data contains metadata for the signature that is used to check whether the signed message is designated for the correct contract and entrypoint, and that it is not expired. -It is serialized as :ref:`CIS-5-ContractAddress` (``contract_address``), :ref:`CIS-5-EntrypointName` (``entrypoint``), :ref:`CIS-5-Nonce` (``nonce``), and :ref:`CIS-5-Timestamp` (``timestamp``):: +It is serialized as :ref:`CIS-5-ContractAddress` (``contract_address``), :ref:`CIS-5-EntrypointName` (``entrypoint``), :ref:`CIS-5-Nonce` (``nonce``), :ref:`CIS-5-Timestamp` (``timestamp``), :ref:`CIS-5-CCDAmount`/:ref:`CIS-5-TokenAmount` (``serviceFee``), and :ref:`CIS-5-Address` (``serviceFeeRecipient``):: + + SigningData ::= (contract_address: ContractAddress) (entrypoint: EntrypointName) (nonce: Nonce) (timestamp: Timestamp) (serviceFee: CCDAmount/tokenAmount) (serviceFeeRecipient: Address) + +For each of the signature checking endpoints the signing data is as follows:: + + WithdrawNativeCurrencySigningData ::= (to: Receiver) (ccdAmount: CCDAmount) (data: AdditionalData) (signingData: SigningData) + + WithdrawCis2TokensSigningData ::= (to: Receiver) (tokenAmount: tokenAmount) (tokenId: tokenID) (cis2TokenContractAddress: ContractAddress) (data: AdditionalData) (signingData: SigningData) + + InternalNativeCurrencyTransferSigningData ::= (from: PublicKeyEd25519) (to: PublicKeyEd25519) (ccdAmount: CCDAmount) (signingData: SigningData) + + InternalCis2TokensTransferSigningData ::= (from: PublicKeyEd25519) (to: PublicKeyEd25519) (tokenAmount: tokenAmount) (tokenID: TokenID) (cis2TokenContractAddress: ContractAddress) (signingData: SigningData) - SigningData ::= (contract_address: ContractAddress) (entrypoint: EntrypointName) (nonce: Nonce) (timestamp: Timestamp) Logged events ------------- @@ -223,7 +234,7 @@ The ``NonceEvent`` is serialized as: First a byte with the value of 250, followe ``DepositNativeCurrencyEvent`` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -A ``DepositNativeCurrencyEvent`` SHALL be logged for every `depositNativeCurrency` function invoke. +A ``DepositNativeCurrencyEvent`` SHALL be logged for every ``depositNativeCurrency`` function invoke. The ``DepositNativeCurrencyEvent`` is serialized as: First a byte with the value of 249, followed by the :ref:`CIS-5-CCDAmount` (``ccdAmount``), the :ref:`CIS-5-Address` (``from``), and a :ref:`CIS-5-PublicKeyEd25519` (``to``):: @@ -232,18 +243,18 @@ The ``DepositNativeCurrencyEvent`` is serialized as: First a byte with the value ``DepositCis2TokensEvent`` ^^^^^^^^^^^^^^^^^^^^^^^^^^ -A ``DepositCis2TokensEvent`` SHALL be logged for every `depositCis2Tokens` function invoke. +A ``DepositCis2TokensEvent`` SHALL be logged for every ``depositCis2Tokens`` function invoke. The ``DepositCis2TokensEvent`` is serialized as: First a byte with the value of 248, followed by the :ref:`CIS-5-TokenAmount` (``tokenAmount``), :ref:`CIS-5-TokenID` (``TokenID``), -:ref:`CIS-5-ContractAddress` (``contractAddress``), the :ref:`CIS-5-Address` (``from``), and a :ref:`CIS-5-PublicKeyEd25519` (``to``):: +:ref:`CIS-5-ContractAddress` (``cis2TokenContractAddress``), the :ref:`CIS-5-Address` (``from``), and a :ref:`CIS-5-PublicKeyEd25519` (``to``):: - DepositCis2TokensEvent ::= (248: Byte) (tokenAmount: TokenAmount) (tokenId: TokenID) (contractAddress: ContractAddress) (from: Address) (to: PublicKeyEd25519) + DepositCis2TokensEvent ::= (248: Byte) (tokenAmount: TokenAmount) (tokenId: TokenID) (cis2TokenContractAddress: ContractAddress) (from: Address) (to: PublicKeyEd25519) ``WithdrawNativeCurrencyEvent`` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -A ``WithdrawNativeCurrencyEvent`` SHALL be logged for every `withdrawNativeCurrency` function invoke. +A ``WithdrawNativeCurrencyEvent`` SHALL be logged for every ``withdrawNativeCurrency`` function invoke. The ``WithdrawNativeCurrencyEvent`` is serialized as: First a byte with the value of 247, followed by the :ref:`CIS-5-CCDAmount` (``ccdAmount``), a :ref:`CIS-5-PublicKeyEd25519` (``from``), and the :ref:`CIS-5-Address` (``to``):: @@ -252,18 +263,18 @@ The ``WithdrawNativeCurrencyEvent`` is serialized as: First a byte with the valu ``WithdrawCis2TokensEvent`` ^^^^^^^^^^^^^^^^^^^^^^^^^^^ -A ``WithdrawCis2TokensEvent`` SHALL be logged for every `withdrawCis2Tokens` function invoke. +A ``WithdrawCis2TokensEvent`` SHALL be logged for every ``withdrawCis2Tokens`` function invoke. The ``WithdrawCis2TokensEvent`` is serialized as: First a byte with the value of 246, followed by the :ref:`CIS-5-TokenAmount` (``tokenAmount``), :ref:`CIS-5-TokenID` (``TokenID``), -:ref:`CIS-5-ContractAddress` (``contractAddress``), a :ref:`CIS-5-PublicKeyEd25519` (``from``), and the :ref:`CIS-5-Address` (``to``):: +:ref:`CIS-5-ContractAddress` (``cis2TokenContractAddress``), a :ref:`CIS-5-PublicKeyEd25519` (``from``), and the :ref:`CIS-5-Address` (``to``):: - WithdrawCis2TokensEvent ::= (246: Byte) (tokenAmount: TokenAmount) (tokenId: TokenID) (contractAddress: ContractAddress) (from: PublicKeyEd25519) (to: Address) + WithdrawCis2TokensEvent ::= (246: Byte) (tokenAmount: TokenAmount) (tokenId: TokenID) (cis2TokenContractAddress: ContractAddress) (from: PublicKeyEd25519) (to: Address) ``InternalNativeCurrencyTransferEvent`` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -A ``InternalNativeCurrencyTransferEvent`` SHALL be logged for every `internalNativeCurrencyTransfer` function invoke. +A ``InternalNativeCurrencyTransferEvent`` SHALL be logged for every ``internalNativeCurrencyTransfer`` function invoke. The ``InternalNativeCurrencyTransferEvent`` is serialized as: First a byte with the value of 245, followed by the :ref:`CIS-5-CCDAmount` (``ccdAmount``), a :ref:`CIS-5-PublicKeyEd25519` (``from``), and the :ref:`CIS-5-PublicKeyEd25519` (``to``):: @@ -272,13 +283,13 @@ The ``InternalNativeCurrencyTransferEvent`` is serialized as: First a byte with ``InternalCis2TokensTransferEvent`` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -A ``InternalCis2TokensTransferEvent`` SHALL be logged for every `internalCis2TokensTransfer` function invoke. +A ``InternalCis2TokensTransferEvent`` SHALL be logged for every ``internalCis2TokensTransfer`` function invoke. The ``InternalCis2TokensTransferEvent`` is serialized as: First a byte with the value of 244, followed by the :ref:`CIS-5-TokenAmount` (``tokenAmount``), :ref:`CIS-5-TokenID` (``TokenID``), -:ref:`CIS-5-ContractAddress` (``contractAddress``), a :ref:`CIS-5-PublicKeyEd25519` (``from``), and the :ref:`CIS-5-PublicKeyEd25519` (``to``):: +:ref:`CIS-5-ContractAddress` (``cis2TokenContractAddress``), a :ref:`CIS-5-PublicKeyEd25519` (``from``), and the :ref:`CIS-5-PublicKeyEd25519` (``to``):: - InternalCis2TokensTransferEvent ::= (244: Byte) (tokenAmount: TokenAmount) (tokenId: TokenID) (contractAddress: ContractAddress) (from: PublicKeyEd25519) (to: PublicKeyEd25519) + InternalCis2TokensTransferEvent ::= (244: Byte) (tokenAmount: TokenAmount) (tokenId: TokenID) (cis2TokenContractAddress: ContractAddress) (from: PublicKeyEd25519) (to: PublicKeyEd25519) @@ -337,7 +348,7 @@ of a CIS-2 token contract. The function deposits/assigns the send CIS-2 token am The smart contract wallet is not required to check if the invoking contract is a CIS-2 token contract or has some reasonable receive hook logic implemented. If no additional authorization is added to this function, similar caution should be applied as if you would directly interact with any CIS-2 token contract. Only interact with a CIS-2 token contract or value its recorded token balance if you checked its smart - contract logic or reasonable social reputation are given to the project/CIS-2 token contract. + contract logic or reasonable social reputation is given to the project/CIS-2 token contract. Parameter ~~~~~~~~~ @@ -360,7 +371,7 @@ Requirements ^^^^^^^^^^^^^^^^^^^^^^^^^^ The function executes a list of token withdrawals of CCDs (native currency) to native accounts and/or smart contracts out of the smart contract wallet. -When transferring CCD to a contract address, a ccd receive hook function MUST be triggered. +When transferring CCD to a contract address, a CCD receive hook function MUST be triggered. Parameter ~~~~~~~~~ @@ -382,7 +393,7 @@ the receiving address :ref:`CIS-2-Receiver` (``to``), a :ref:`CIS-5-CCDAmount` ( CCD Receive hook parameter ~~~~~~~~~~~~~~~~~~~~~~~~~~ -The parameter for the ccd receive hook function contains information about the transfer and some additional data bytes. +The parameter for the CCD receive hook function contains information about the transfer and some additional data bytes. It is serialized as: a :ref:`CIS-5-CCDAmount` (``ccdAmount``), a :ref:`CIS-5-PublicKeyEd25519` (``from``), and some aditional data :ref:`CIS-2-AdditionalData` (``data``):: @@ -396,14 +407,14 @@ Requirements - The contract function MUST reject if any of the withdrawals fail to be executed. - The function MUST emit a ``NonceEvent`` and a ``WithdrawNativeCurrencyEvent`` for every withdrawal. - The function MUST reject if the signature verification fails for any withdrawal. -- The function MUST fail, if the CCD balance of the ``signer`` is insufficient to do the withdrawal for any withdrawal. +- The function MUST fail if the CCD balance of the ``signer`` is insufficient to do the withdrawal for any withdrawal. - A function MUST non-strictly decrease the CCD balance of the ``signer`` public key and non-strictly increase the balance of the ``to`` address or fail for any withdrawal. - A withdrawal back to this contract into the ``depositNativeCurrency`` entrypoint MUST be executed as a normal withdrawal. - A withdrawal of a CCD amount of zero MUST be executed as a normal withdrawal. -- A withdrawal of any amount of CCD to a contract address MUST call a ccd receive hook function on the receiving smart contract with a :ref:`ccd receive hook parameter`. -- The contract function MUST reject if the ccd receive hook function called on the contract receiving CCDs rejects for any withdrawal. +- A withdrawal of any amount of CCD to a contract address MUST call a CCD receive hook function on the receiving smart contract with a :ref:`ccd receive hook parameter`. +- The contract function MUST reject if the CCD receive hook function called on the contract receiving CCDs rejects for any withdrawal. - The balance of a public key not owning any CCD amount SHOULD be treated as having a balance of zero. -- The function MUST transfer the ``serviceFee`` to the ``serviceFeeRecipient`` for every withdrawal. +- The function MUST transfer the ``serviceFee`` to the ``serviceFeeRecipient`` for every withdrawal if ``serviceFee!=0``. .. warning:: @@ -442,12 +453,12 @@ Requirements - The function MUST emit a ``NonceEvent`` and a ``WithdrawCis2TokensEvent`` for every withdrawal. - The function MUST reject if the signature verification fails for any withdrawal. - This function MUST call the ``transfer`` function on the CIS-2 token contract for every withdrawal. -- The function MUST fail, if the token balance of the ``signer`` is insufficient to do the withdrawal for any withdrawal. +- The function MUST fail if the token balance of the ``signer`` is insufficient to do the withdrawal for any withdrawal. - A function MUST non-strictly decrease the token balance of the ``signer`` public key and non-strictly increase the balance of the ``to`` address or fail for any withdrawal. - A withdrawal back to this contract into the ``depositCis2Tokens`` entrypoint MUST be executed as a normal withdrawal. - A withdrawal of a token amount of zero MUST be executed as a normal withdrawal. - The balance of a public key not owning any tokens SHOULD be treated as having a balance of zero. -- The function MUST transfer the ``serviceFee`` to the ``serviceFeeRecipient`` for every withdrawal. +- The function MUST transfer the ``serviceFee`` to the ``serviceFeeRecipient`` for every withdrawal if ``serviceFee!=0``. .. _CIS-5-functions-internalNativeCurrencyTransfer: @@ -475,11 +486,11 @@ Requirements - The function MUST emit a ``NonceEvent`` and a ``InternalNativeCurrencyTransferEvent`` for every transfer. - The function MUST reject if the signature verification fails for any transfer. -- The function MUST fail, if the CCD balance of the ``signer`` is insufficient to do the tranfser for any transfer. +- The function MUST fail if the CCD balance of the ``signer`` is insufficient to do the transfer for any transfer. - A function MUST non-strictly decrease the CCD balance of the ``signer`` public key and non-strictly increase the balance of the ``to`` address or fail for any transfer. - A transfer of a CCD amount of zero MUST be executed as a normal transfer. - The balance of a public key not owning any CCD amount SHOULD be treated as having a balance of zero. -- The function MUST transfer the ``serviceFee`` to the ``serviceFeeRecipient`` for every transfer. +- The function MUST transfer the ``serviceFee`` to the ``serviceFeeRecipient`` for every transfer if ``serviceFee!=0``. .. _CIS-5-functions-internalCis2TokensTransfer: @@ -508,11 +519,11 @@ Requirements - The function MUST emit a ``NonceEvent`` and a ``InternalCis2TokensTransferEvent`` for every transfer. - The function MUST reject if the signature verification fails for any of the transfers. -- The function MUST fail, if the token balance of the ``signer`` is insufficient to do the transfer for any transfer. +- The function MUST fail if the token balance of the ``signer`` is insufficient to do the transfer for any transfer. - A function MUST non-strictly decrease the token balance of the ``signer`` public key and non-strictly increase the balance of the ``to`` address or fail for any transfer. - A transfer of a token amount of zero MUST be executed as a normal transfer. - The balance of a public key not owning any tokens SHOULD be treated as having a balance of zero. -- The function MUST transfer the ``serviceFee`` to the ``serviceFeeRecipient`` for every transfer. +- The function MUST transfer the ``serviceFee`` to the ``serviceFeeRecipient`` for every transfer if ``serviceFee!=0``. .. _CIS-5-functions-balanceOfNativeCurrency: @@ -524,7 +535,7 @@ The function queries the CCD balances of a list of public keys. Parameter ~~~~~~~~~ -The parameter consists of a list public keys. +The parameter consists of a list of public keys. It is serialized as: 2 bytes for the number of queries (``n``) and then this number of queries (``queries``). A query is serialized as a :ref:`CIS-5-PublicKeyEd25519` (``publicKey``):: @@ -582,7 +593,7 @@ It is serialized as: 2 bytes for the number of token amounts (``n``) and then th Requirements ~~~~~~~~~~~~ -- The balance of an public key not owning any amount of a token type SHOULD be treated as having a balance of zero. +- The balance of a public key not owning any amount of a token type SHOULD be treated as having a balance of zero. - The number of results in the response MUST correspond to the number of the queries in the parameter. - The order of results in the response MUST correspond to the order of queries in the parameter. - The contract function MUST NOT increase or decrease the CCD balance or token balance of any public key for any token type. From 276300469613277eddaefd698ac00c56b481ac47 Mon Sep 17 00:00:00 2001 From: Doris Benda Date: Thu, 21 Mar 2024 21:45:20 +0200 Subject: [PATCH 07/10] Address comments --- source/CIS/cis-2.rst | 2 + source/CIS/cis-5.rst | 110 +++++++++++++++++++++---------------------- source/index.rst | 4 +- 3 files changed, 58 insertions(+), 58 deletions(-) diff --git a/source/CIS/cis-2.rst b/source/CIS/cis-2.rst index 933b2d7..87ad981 100644 --- a/source/CIS/cis-2.rst +++ b/source/CIS/cis-2.rst @@ -187,6 +187,8 @@ A transfer is a token ID, an amount of tokens to be transferred, and the ``from` When transferring tokens to a contract address, additional information for a receive function hook to trigger is required. +.. _CIS-2-TransferParameter: + Parameter ~~~~~~~~~ diff --git a/source/CIS/cis-5.rst b/source/CIS/cis-5.rst index c84d7c0..bd09221 100644 --- a/source/CIS/cis-5.rst +++ b/source/CIS/cis-5.rst @@ -1,16 +1,14 @@ .. _CIS-5: -========================================================= -CIS-5: Smart Contract Wallet Standard (Chaperone Account) -========================================================= +================================================================ +Draft: CIS-5: Smart Contract Wallet Standard (Chaperone Account) +================================================================ .. list-table:: :stub-columns: 1 * - Created - Mar 17, 2024 - * - Final - - Mar 28, 2024 * - Supported versions - | Smart contract version 1 or newer | (Protocol version 4 or newer) @@ -63,25 +61,15 @@ General types and serialization ``TokenID`` ^^^^^^^^^^^ -- The token ID SHALL be able to encode all possible Token IDs from the ``CIS-2 TokenID standard`` (:ref:`CIS-2-TokenID`) - A token ID is serialized as 1 byte for the size (``n``) of the identifier, followed by this number of bytes for the token id (``id``):: TokenID ::= (n: Byte) (id: Byteⁿ) -.. note:: - - Token IDs (as defined in the CIS-2 standard) can be as small as a single byte (by setting the first byte to the value 0) - or as big as 256 bytes. - The token ID in the CIS-5 standard needs to be able to encode up to 256 bytes long Token IDs as a result. - .. _CIS-5-TokenAmount: ``TokenAmount`` ^^^^^^^^^^^^^^^ -- The token amount SHALL be able to encode all possible tokenAmounts from the ``CIS-2 TokenAmount standard`` (:ref:`CIS-2-TokenAmount`). An amount of a token type is an unsigned integer up to 2^256 - 1. - It is serialized using the LEB128_ variable-length unsigned integer encoding, with the additional constraint that the total number of bytes of the encoding MUST not exceed 37 bytes:: TokenAmount ::= (x: Byte) => x if x < 2^7 @@ -194,16 +182,28 @@ It is serialized as 64 bytes:: SignatureEd25519 ::= (signature: Byte⁶⁴) +.. _CIS-5-ChainContext: + +``ChainContext`` +^^^^^^^^^^^^^^^^^^ + +A short string (up to 64 characters) in hex-encoding. +The string describes the chain context (e.g. the genesisHash is a suitable candidate) to prevent re-playing signatures across the testnet/mainnet chain. + +It is serialized as: First byte encodes the length (``n``) of the string, followed by this many bytes for the string characters:: + + ChainContext ::= (n: Byte) (characters: Byteⁿ) + .. _CIS-5-SigningData: ``SigningData`` ^^^^^^^^^^^^^^^ -Signing data contains metadata for the signature that is used to check whether the signed message is designated for the correct contract and entrypoint, and that it is not expired. +Signing data contains metadata for the signature that is used to check whether the signed message is designated for the correct chain, contract, entrypoint, and that it is not expired or has a nonce mismatch, and the serviceFee commitment is included. -It is serialized as :ref:`CIS-5-ContractAddress` (``contract_address``), :ref:`CIS-5-EntrypointName` (``entrypoint``), :ref:`CIS-5-Nonce` (``nonce``), :ref:`CIS-5-Timestamp` (``timestamp``), :ref:`CIS-5-CCDAmount`/:ref:`CIS-5-TokenAmount` (``serviceFee``), and :ref:`CIS-5-Address` (``serviceFeeRecipient``):: +It is serialized as :ref:`CIS-5-ChainContext` (``chain_context``), :ref:`CIS-5-ContractAddress` (``contract_address``), :ref:`CIS-5-EntrypointName` (``entrypoint``), :ref:`CIS-5-Nonce` (``nonce``), :ref:`CIS-5-Timestamp` (``timestamp``), :ref:`CIS-5-CCDAmount`/:ref:`CIS-5-TokenAmount` (``serviceFee``), and :ref:`CIS-5-Address` (``serviceFeeRecipient``):: - SigningData ::= (contract_address: ContractAddress) (entrypoint: EntrypointName) (nonce: Nonce) (timestamp: Timestamp) (serviceFee: CCDAmount/tokenAmount) (serviceFeeRecipient: Address) + SigningData ::= (chain_context: String) (contract_address: ContractAddress) (entrypoint: EntrypointName) (nonce: Nonce) (timestamp: Timestamp) (serviceFee: CCDAmount/tokenAmount) (serviceFeeRecipient: Address) For each of the signature checking endpoints the signing data is as follows:: @@ -227,14 +227,14 @@ Other events logged by the smart contract SHOULD NOT have a first byte colliding A ``NonceEvent`` SHALL be logged for every signature checking function invoke. -The ``NonceEvent`` is serialized as: First a byte with the value of 250, followed by the :ref:`CIS-5-Nonce` (``nonce``) that was used in the PermitMessage, and an :ref:`CIS-5-AccountAddress` (``sponsoree``):: +The ``NonceEvent`` is serialized as: First a byte with the value of 250, followed by the :ref:`CIS-5-Nonce` (``nonce``) that is used in the SigningData, and an :ref:`CIS-5-AccountAddress` (``sponsoree``):: NonceEvent ::= (250: Byte) (nonce: Nonce) (sponsoree: AccountAddress) ``DepositNativeCurrencyEvent`` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -A ``DepositNativeCurrencyEvent`` SHALL be logged for every ``depositNativeCurrency`` function invoke. +A ``DepositNativeCurrencyEvent`` SHALL be logged ever time an amount of CCD received by the contract is assigned to a public key. The ``DepositNativeCurrencyEvent`` is serialized as: First a byte with the value of 249, followed by the :ref:`CIS-5-CCDAmount` (``ccdAmount``), the :ref:`CIS-5-Address` (``from``), and a :ref:`CIS-5-PublicKeyEd25519` (``to``):: @@ -243,7 +243,7 @@ The ``DepositNativeCurrencyEvent`` is serialized as: First a byte with the value ``DepositCis2TokensEvent`` ^^^^^^^^^^^^^^^^^^^^^^^^^^ -A ``DepositCis2TokensEvent`` SHALL be logged for every ``depositCis2Tokens`` function invoke. +A ``DepositCis2TokensEvent`` SHALL be logged ever time a token amount received by the contract is assigned to a public key. The ``DepositCis2TokensEvent`` is serialized as: First a byte with the value of 248, followed by the :ref:`CIS-5-TokenAmount` (``tokenAmount``), :ref:`CIS-5-TokenID` (``TokenID``), @@ -254,7 +254,7 @@ The ``DepositCis2TokensEvent`` is serialized as: First a byte with the value of ``WithdrawNativeCurrencyEvent`` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -A ``WithdrawNativeCurrencyEvent`` SHALL be logged for every ``withdrawNativeCurrency`` function invoke. +A ``WithdrawNativeCurrencyEvent`` SHALL be logged ever time an amount of CCD held by a public key is withdrawn to an address. The ``WithdrawNativeCurrencyEvent`` is serialized as: First a byte with the value of 247, followed by the :ref:`CIS-5-CCDAmount` (``ccdAmount``), a :ref:`CIS-5-PublicKeyEd25519` (``from``), and the :ref:`CIS-5-Address` (``to``):: @@ -263,7 +263,7 @@ The ``WithdrawNativeCurrencyEvent`` is serialized as: First a byte with the valu ``WithdrawCis2TokensEvent`` ^^^^^^^^^^^^^^^^^^^^^^^^^^^ -A ``WithdrawCis2TokensEvent`` SHALL be logged for every ``withdrawCis2Tokens`` function invoke. +A ``WithdrawCis2TokensEvent`` SHALL be logged ever time a token amount held by a public key is withdrawn to an address. The ``WithdrawCis2TokensEvent`` is serialized as: First a byte with the value of 246, followed by the :ref:`CIS-5-TokenAmount` (``tokenAmount``), :ref:`CIS-5-TokenID` (``TokenID``), @@ -274,7 +274,7 @@ The ``WithdrawCis2TokensEvent`` is serialized as: First a byte with the value of ``InternalNativeCurrencyTransferEvent`` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -A ``InternalNativeCurrencyTransferEvent`` SHALL be logged for every ``internalNativeCurrencyTransfer`` function invoke. +A ``InternalNativeCurrencyTransferEvent`` SHALL be logged ever time an amount of CCD held by a public key is transferred to another public key within the contract. The ``InternalNativeCurrencyTransferEvent`` is serialized as: First a byte with the value of 245, followed by the :ref:`CIS-5-CCDAmount` (``ccdAmount``), a :ref:`CIS-5-PublicKeyEd25519` (``from``), and the :ref:`CIS-5-PublicKeyEd25519` (``to``):: @@ -283,7 +283,7 @@ The ``InternalNativeCurrencyTransferEvent`` is serialized as: First a byte with ``InternalCis2TokensTransferEvent`` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -A ``InternalCis2TokensTransferEvent`` SHALL be logged for every ``internalCis2TokensTransfer`` function invoke. +A ``InternalCis2TokensTransferEvent`` SHALL be logged ever time a token amount held by a public key is transferred to another public key within the contract. The ``InternalCis2TokensTransferEvent`` is serialized as: First a byte with the value of 244, followed by the :ref:`CIS-5-TokenAmount` (``tokenAmount``), :ref:`CIS-5-TokenID` (``TokenID``), @@ -291,7 +291,9 @@ The ``InternalCis2TokensTransferEvent`` is serialized as: First a byte with the InternalCis2TokensTransferEvent ::= (244: Byte) (tokenAmount: TokenAmount) (tokenId: TokenID) (cis2TokenContractAddress: ContractAddress) (from: PublicKeyEd25519) (to: PublicKeyEd25519) +.. note:: + The CIS-5 events SHALL enable off-chain applications to compute off-chain all balances that the public keys are holding. .. _CIS-5-functions: @@ -324,11 +326,6 @@ The parameter is a ``PublicKeyEd25519``. See the serialization rules in :ref:`CIS-5-PublicKeyEd25519`. -Requirements -~~~~~~~~~~~~ - -- The function MUST emit a ``DepositNativeCurrencyEvent``. - .. _CIS-5-functions-depositCis2Tokens: ``depositCis2Tokens`` @@ -337,11 +334,6 @@ Requirements This function SHOULD be called through the receive hook mechanism (:ref:`CIS-2-Receive-Hook-Function`) of a CIS-2 token contract. The function deposits/assigns the send CIS-2 token amount to a public key (``PublicKeyEd25519``). -.. note:: - - If a use case wants to mint and deposit tokens to a public key in one transaction. - The CIS2 token has to have a mint function that calls this smart contract wallet ``depositCis2Tokens`` function via a hook mechanism. - .. note:: The ``depositCis2Tokens`` function can be called by any smart contract. It is up to the exact implementation of the smart contract wallet whether it should trust the caller or not. @@ -362,7 +354,6 @@ and the serialization rules in :ref:`CIS-5-PublicKeyEd25519`. Requirements ~~~~~~~~~~~~ -- The function MUST emit a ``DepositCis2TokensEvent``. - The function SHOULD check that a contract is the caller since only a contract can implement a receive hook mechanism. .. _CIS-5-functions-withdrawNativeCurrency: @@ -380,11 +371,14 @@ The parameter is a list of withdrawals. It is serialized as: 2 bytes representing the number of withdrawals (``n``) followed by the bytes for this number of withdrawals. -Each withdrawal is serialized as: a :ref:`CIS-5-PublicKeyEd25519` (``signer``), a :ref:`CIS-5-SignatureEd25519` (``signature``), -a :ref:`CIS-5-TimeStamp` (``expiryTime``), a :ref:`CIS-5-Nonce` (``nonce``), a :ref:`CIS-5-CCDAmount` (``serviceFee``), an :ref:`CIS-5-Address` (``serviceFeeRecipient``), -the receiving address :ref:`CIS-2-Receiver` (``to``), a :ref:`CIS-5-CCDAmount` (``ccdAmount``), and some additional data :ref:`CIS-2-AdditionalData` (``data``):: +Each ``NativeCurrencyWithdrawal`` is serialized as: a :ref:`CIS-5-PublicKeyEd25519` (``signer``), a :ref:`CIS-5-SignatureEd25519` (``signature``), +a :ref:`CIS-5-TimeStamp` (``expiryTime``), a :ref:`CIS-5-Nonce` (``nonce``), a :ref:`CIS-5-CCDAmount` (``serviceFee``), an :ref:`CIS-5-Address` (``serviceFeeRecipient``), 2 bytes representing the number of simple withdraws (``m``) followed by the bytes for this number of simple withdraws (``simple_withdraw``). + +Each ``NativeCurrencyWithdrawalBatch`` is serialized as: the receiving address :ref:`CIS-2-Receiver` (``to``), the :ref:`CIS-5-CCDAmount` (``ccdAmount``), and some additional data :ref:`CIS-2-AdditionalData` (``data``):: - NativeCurrencyWithdrawal ::= (signer: PublicKeyEd25519) (signature: SignatureEd25519) (expiryTime: TimeStamp) (nonce: u64) (serviceFee: CCDAmount) (serviceFeeRecipient: Address) (to: Receiver) (ccdAmount: CCDAmount) (data: AdditionalData) + NativeCurrencyWithdrawalBatch ::= (to: Receiver) (ccdAmount: CCDAmount) (data: AdditionalData) + + NativeCurrencyWithdrawal ::= (signer: PublicKeyEd25519) (signature: SignatureEd25519) (expiryTime: TimeStamp) (nonce: u64) (serviceFee: CCDAmount) (serviceFeeRecipient: Address) (m: Byte²) (simple_withdraw: NativeCurrencyWithdrawalBatchᵐ) NativeCurrencyWithdrawParameter ::= (n: Byte²) (withdrawal: NativeCurrencyWithdrawalⁿ) @@ -395,7 +389,7 @@ CCD Receive hook parameter The parameter for the CCD receive hook function contains information about the transfer and some additional data bytes. -It is serialized as: a :ref:`CIS-5-CCDAmount` (``ccdAmount``), a :ref:`CIS-5-PublicKeyEd25519` (``from``), and some aditional data :ref:`CIS-2-AdditionalData` (``data``):: +It is serialized as: a :ref:`CIS-5-CCDAmount` (``ccdAmount``), a :ref:`CIS-5-PublicKeyEd25519` (``from``), and some additional data :ref:`CIS-2-AdditionalData` (``data``):: CCDReceiveHookParameter ::= (ccdAmount: CCDAmount) (from: PublicKeyEd25519) (data: AdditionalData) @@ -405,7 +399,6 @@ Requirements - The list of withdrawals MUST be executed in order. - The contract function MUST reject if any of the withdrawals fail to be executed. -- The function MUST emit a ``NonceEvent`` and a ``WithdrawNativeCurrencyEvent`` for every withdrawal. - The function MUST reject if the signature verification fails for any withdrawal. - The function MUST fail if the CCD balance of the ``signer`` is insufficient to do the withdrawal for any withdrawal. - A function MUST non-strictly decrease the CCD balance of the ``signer`` public key and non-strictly increase the balance of the ``to`` address or fail for any withdrawal. @@ -438,10 +431,10 @@ The parameter is a list of withdrawals. It is serialized as: 2 bytes representing the number of withdrawals (``n``) followed by the bytes for this number of withdrawals. Each withdrawal is serialized as: a :ref:`CIS-5-PublicKeyEd25519` (``signer``), a :ref:`CIS-5-SignatureEd25519` (``signature``), -a :ref:`CIS-5-TimeStamp` (``expiryTime``), a :ref:`CIS-5-Nonce` (``nonce``), a :ref:`CIS-5-CCDAmount` (``serviceFee``), an :ref:`CIS-5-Address` (``serviceFeeRecipient``), -the receiving address :ref:`CIS-2-Receiver` (``to``), a :ref:`CIS-5-TokenAmount` (``tokenAmount``), a :ref:`CIS-5-TokenID` (``tokenID``), a :ref:`CIS-5-ContractAddress` (``cis2TokenContractAddress``), and some additional data :ref:`CIS-2-AdditionalData` (``data``):: +a :ref:`CIS-5-TimeStamp` (``expiryTime``), a :ref:`CIS-5-Nonce` (``nonce``), a :ref:`CIS-5-TokenAmount` (``serviceFee``), an :ref:`CIS-5-Address` (``serviceFeeRecipient``), +a :ref:`CIS-5-ContractAddress` (``cis2TokenContractAddress``), and :ref:`CIS-2-TransferParameter` (``transferParameter``):: - Cis2TokensWithdrawal ::= (signer: PublicKeyEd25519) (signature: SignatureEd25519) (expiryTime: TimeStamp) (nonce: u64) (serviceFee: CCDAmount) (serviceFeeRecipient: Address) (to: Receiver) (tokenAmount: tokenAmount) (tokenId: tokenID) (cis2TokenContractAddress: ContractAddress) (data: AdditionalData) + Cis2TokensWithdrawal ::= (signer: PublicKeyEd25519) (signature: SignatureEd25519) (expiryTime: TimeStamp) (nonce: u64) (serviceFee: TokenAmount) (serviceFeeRecipient: Address) (cis2TokenContractAddress: ContractAddress) (transferParameter: TransferParameter) Cis2TokensWithdrawParameter ::= (n: Byte²) (withdrawal: Cis2TokensWithdrawalⁿ) @@ -450,7 +443,6 @@ Requirements - The list of withdrawals MUST be executed in order. - The contract function MUST reject if any of the withdrawals fail to be executed. -- The function MUST emit a ``NonceEvent`` and a ``WithdrawCis2TokensEvent`` for every withdrawal. - The function MUST reject if the signature verification fails for any withdrawal. - This function MUST call the ``transfer`` function on the CIS-2 token contract for every withdrawal. - The function MUST fail if the token balance of the ``signer`` is insufficient to do the withdrawal for any withdrawal. @@ -473,18 +465,22 @@ The parameter is a list of internal transfers. It is serialized as: 2 bytes representing the number of transfers (``n``) followed by the bytes for this number of internal transfers. -Each transfer is serialized as: a :ref:`CIS-5-PublicKeyEd25519` (``signer``), a :ref:`CIS-5-SignatureEd25519` (``signature``), +Each ``NativeCurrencyInternalTransfer`` is serialized as: a :ref:`CIS-5-PublicKeyEd25519` (``signer``), a :ref:`CIS-5-SignatureEd25519` (``signature``), a :ref:`CIS-5-TimeStamp` (``expiryTime``), a :ref:`CIS-5-Nonce` (``nonce``), a :ref:`CIS-5-CCDAmount` (``serviceFee``), an :ref:`CIS-5-Address` (``serviceFeeRecipient``), -a :ref:`CIS-5-PublicKeyEd25519` (``from``), a :ref:`CIS-5-PublicKeyEd25519` (``to``), and a :ref:`CIS-5-CCDAmount` (``ccdAmount``):: +2 bytes representing the number of simple transfers (``m``) followed by the bytes for this number of simple transfers (``simple_transfer``). + +Each ``NativeCurrencyInternalTransferBatch`` is serialized as: a :ref:`CIS-5-PublicKeyEd25519` (``from``), a :ref:`CIS-5-PublicKeyEd25519` (``to``), and a :ref:`CIS-5-CCDAmount` (``ccdAmount``):: + + NativeCurrencyInternalTransferBatch ::= (from: PublicKeyEd25519) (to: PublicKeyEd25519) (ccdAmount: CCDAmount) + + NativeCurrencyInternalTransfer ::= (signer: PublicKeyEd25519) (signature: SignatureEd25519) (expiryTime: TimeStamp) (nonce: u64) (serviceFee: CCDAmount) (serviceFeeRecipient: Address) (m: Byte²) (simple_transfer: NativeCurrencyInternalTransferBatchᵐ) - NativeCurrencyInternalTransfer ::= (signer: PublicKeyEd25519) (signature: SignatureEd25519) (expiryTime: TimeStamp) (nonce: u64) (serviceFee: CCDAmount) (serviceFeeRecipient: Address) (from: PublicKeyEd25519) (to: PublicKeyEd25519) (ccdAmount: CCDAmount) NativeCurrencyInternalTransferParameter ::= (n: Byte²) (transfer: NativeCurrencyInternalTransfer) Requirements ~~~~~~~~~~~~ -- The function MUST emit a ``NonceEvent`` and a ``InternalNativeCurrencyTransferEvent`` for every transfer. - The function MUST reject if the signature verification fails for any transfer. - The function MUST fail if the CCD balance of the ``signer`` is insufficient to do the transfer for any transfer. - A function MUST non-strictly decrease the CCD balance of the ``signer`` public key and non-strictly increase the balance of the ``to`` address or fail for any transfer. @@ -506,18 +502,22 @@ The parameter is a list of internal transfers. It is serialized as: 2 bytes representing the number of transfers (``n``) followed by the bytes for this number of internal transfers. -Each transfer is serialized as: a :ref:`CIS-5-PublicKeyEd25519` (``signer``), a :ref:`CIS-5-SignatureEd25519` (``signature``), -a :ref:`CIS-5-TimeStamp` (``expiryTime``), a :ref:`CIS-5-Nonce` (``nonce``), a :ref:`CIS-5-CCDAmount` (``serviceFee``), an :ref:`CIS-5-Address` (``serviceFeeRecipient``), -a :ref:`CIS-5-PublicKeyEd25519` (``from``), a :ref:`CIS-5-PublicKeyEd25519` (``to``), a :ref:`CIS-5-TokenAmount` (``tokenAmount``), a :ref:`CIS-5-TokenID` (``tokenID``), and a :ref:`CIS-5-ContractAddress` (``cis2TokenContractAddress``):: +Each ``Cis2TokensInternalTransfer`` is serialized as: a :ref:`CIS-5-PublicKeyEd25519` (``signer``), a :ref:`CIS-5-SignatureEd25519` (``signature``), +a :ref:`CIS-5-TimeStamp` (``expiryTime``), a :ref:`CIS-5-Nonce` (``nonce``), a :ref:`CIS-5-TokenAmount` (``serviceFee``), an :ref:`CIS-5-Address` (``serviceFeeRecipient``), +2 bytes representing the number of simple transfers (``m``) followed by the bytes for this number of simple transfers (``simple_transfer``). + +Each ``Cis2TokensInternalTransferBatch`` is serialized as: a :ref:`CIS-5-PublicKeyEd25519` (``from``), a :ref:`CIS-5-PublicKeyEd25519` (``to``), a :ref:`CIS-5-TokenAmount` (``tokenAmount``), a :ref:`CIS-5-TokenID` (``tokenID``), and a :ref:`CIS-5-ContractAddress` (``cis2TokenContractAddress``):: + + Cis2TokensInternalTransferBatch ::= (from: PublicKeyEd25519) (to: PublicKeyEd25519) (tokenAmount: tokenAmount) (tokenID: TokenID) (cis2TokenContractAddress: ContractAddress) + + Cis2TokensInternalTransfer ::= (signer: PublicKeyEd25519) (signature: SignatureEd25519) (expiryTime: TimeStamp) (nonce: u64) (serviceFee: TokenAmount) (serviceFeeRecipient: Address) (m: Byte²) (simple_transfer: Cis2TokensInternalTransferBatchᵐ) - Cis2TokensInternalTransfer ::= (signer: PublicKeyEd25519) (signature: SignatureEd25519) (expiryTime: TimeStamp) (nonce: u64) (serviceFee: CCDAmount) (serviceFeeRecipient: Address) (from: PublicKeyEd25519) (to: PublicKeyEd25519) (tokenAmount: tokenAmount) (tokenID: TokenID) (cis2TokenContractAddress: ContractAddress) Cis2TokensInternalTransferParameter ::= (n: Byte²) (transfer: Cis2TokensInternalTransfer) Requirements ~~~~~~~~~~~~ -- The function MUST emit a ``NonceEvent`` and a ``InternalCis2TokensTransferEvent`` for every transfer. - The function MUST reject if the signature verification fails for any of the transfers. - The function MUST fail if the token balance of the ``signer`` is insufficient to do the transfer for any transfer. - A function MUST non-strictly decrease the token balance of the ``signer`` public key and non-strictly increase the balance of the ``to`` address or fail for any transfer. diff --git a/source/index.rst b/source/index.rst index e11ace6..5c15858 100644 --- a/source/index.rst +++ b/source/index.rst @@ -22,8 +22,6 @@ Concordium Interoperability Specifications CIS/cis-3 CIS/cis-4 CIS/cis-5 -<<<<<<< HEAD CIS/cis-6 -======= ID/concordium-did.rst ->>>>>>> fb33efb (Add withdrawCis2Tokens function) + From 97825dbfff879c35cec049d64bf7298c6dbfc243 Mon Sep 17 00:00:00 2001 From: Doris Benda Date: Fri, 17 May 2024 18:45:25 +0300 Subject: [PATCH 08/10] Update CIS5 standard --- source/CIS/cis-5.rst | 296 +++++++++++++++++++++++-------------------- 1 file changed, 159 insertions(+), 137 deletions(-) diff --git a/source/CIS/cis-5.rst b/source/CIS/cis-5.rst index bd09221..c6b2c48 100644 --- a/source/CIS/cis-5.rst +++ b/source/CIS/cis-5.rst @@ -1,8 +1,8 @@ .. _CIS-5: -================================================================ -Draft: CIS-5: Smart Contract Wallet Standard (Chaperone Account) -================================================================ +===================================== +CIS-5: Smart Contract Wallet Standard +===================================== .. list-table:: :stub-columns: 1 @@ -20,16 +20,12 @@ Draft: CIS-5: Smart Contract Wallet Standard (Chaperone Account) Abstract ======== -A standard interface for defining a smart contract wallet that can hold and transfer native currency and CIS-2 tokens. -Native currency/CIS-2 tokens can be deposited into the smart contract wallet by +A standard interface for defining a smart contract wallet that can hold and transfer CCDs and CIS-2 tokens. +CCDs/CIS-2 tokens can be deposited into the smart contract wallet by specifying to which public key the deposit should be assigned. -The holder of the corresponding private key is the only entity that can authorize -to transfer tokens/currency in a self-custodial manner -from the public key balance (assigned in the smart contract) to some new accounts/smart contracts/public keys. - The holder of the corresponding private key does not have to submit transactions -on chain to transfer its native currency/CIS-2 token balance, +on chain to transfer/withdraw its CCD/CIS-2 token balances, but instead, it can generate a valid signature, identify a willing third party to submit its signature on-chain (a service fee can be added to financially incentivize a third party to do so). @@ -77,6 +73,17 @@ It is serialized using the LEB128_ variable-length unsigned integer encoding, wi .. _LEB128: https://en.wikipedia.org/wiki/LEB128 +.. _CIS-5-ExternalTokenAmount: + +``CIS5-ExternalTokenAmount`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +A CIS-2 token amount on a blockchain defined by the amount, token id and smart contract it represents. + +It is serialized as a :ref:`CIS-5-TokenAmount` (``tokenAmount``), a :ref:`CIS-5-TokenId` (``tokenId``), and a :ref:`CIS-5-ContractAddress` (``cis2TokenContractAddress``):: + + ExternalTokenAmount ::= (tokenAmount: TokenAmount) (tokenId: TokenId) (cis2TokenContractAddress: ContractAddress) + .. _CIS-5-AccountAddress: ``AccountAddress`` @@ -185,35 +192,14 @@ It is serialized as 64 bytes:: .. _CIS-5-ChainContext: ``ChainContext`` -^^^^^^^^^^^^^^^^^^ - -A short string (up to 64 characters) in hex-encoding. -The string describes the chain context (e.g. the genesisHash is a suitable candidate) to prevent re-playing signatures across the testnet/mainnet chain. - -It is serialized as: First byte encodes the length (``n``) of the string, followed by this many bytes for the string characters:: - - ChainContext ::= (n: Byte) (characters: Byteⁿ) - -.. _CIS-5-SigningData: - -``SigningData`` -^^^^^^^^^^^^^^^ +^^^^^^^^^^^^^^^^ -Signing data contains metadata for the signature that is used to check whether the signed message is designated for the correct chain, contract, entrypoint, and that it is not expired or has a nonce mismatch, and the serviceFee commitment is included. +The chain context consists of the genesis hash and the contract address to prevent re-playing signatures across the testnet/mainnet chain and smart contracts. -It is serialized as :ref:`CIS-5-ChainContext` (``chain_context``), :ref:`CIS-5-ContractAddress` (``contract_address``), :ref:`CIS-5-EntrypointName` (``entrypoint``), :ref:`CIS-5-Nonce` (``nonce``), :ref:`CIS-5-Timestamp` (``timestamp``), :ref:`CIS-5-CCDAmount`/:ref:`CIS-5-TokenAmount` (``serviceFee``), and :ref:`CIS-5-Address` (``serviceFeeRecipient``):: +It is serialized as: First 32 bytes defining the genesisHash (its hex string representation converted into bytes), +followed by 8 bytes for the index of the smart contract address and 8 bytes for the subindex of the smart contract address:: - SigningData ::= (chain_context: String) (contract_address: ContractAddress) (entrypoint: EntrypointName) (nonce: Nonce) (timestamp: Timestamp) (serviceFee: CCDAmount/tokenAmount) (serviceFeeRecipient: Address) - -For each of the signature checking endpoints the signing data is as follows:: - - WithdrawNativeCurrencySigningData ::= (to: Receiver) (ccdAmount: CCDAmount) (data: AdditionalData) (signingData: SigningData) - - WithdrawCis2TokensSigningData ::= (to: Receiver) (tokenAmount: tokenAmount) (tokenId: tokenID) (cis2TokenContractAddress: ContractAddress) (data: AdditionalData) (signingData: SigningData) - - InternalNativeCurrencyTransferSigningData ::= (from: PublicKeyEd25519) (to: PublicKeyEd25519) (ccdAmount: CCDAmount) (signingData: SigningData) - - InternalCis2TokensTransferSigningData ::= (from: PublicKeyEd25519) (to: PublicKeyEd25519) (tokenAmount: tokenAmount) (tokenID: TokenID) (cis2TokenContractAddress: ContractAddress) (signingData: SigningData) + ChainContext ::= (genesisHash: Byte³²) (index: Byte⁸) (subindex: Byte⁸) Logged events @@ -225,20 +211,20 @@ Other events logged by the smart contract SHOULD NOT have a first byte colliding ``NonceEvent`` ^^^^^^^^^^^^^^ -A ``NonceEvent`` SHALL be logged for every signature checking function invoke. +A ``NonceEvent`` SHALL be logged every time a signature is successfully processed and considered valid by the contract. -The ``NonceEvent`` is serialized as: First a byte with the value of 250, followed by the :ref:`CIS-5-Nonce` (``nonce``) that is used in the SigningData, and an :ref:`CIS-5-AccountAddress` (``sponsoree``):: +The ``NonceEvent`` is serialized as: First a byte with the value of 250, followed by the :ref:`CIS-5-Nonce` (``nonce``) that is used in the SigningData, and an :ref:`CIS-5-PublicKeyEd25519` (``sponsoree``):: - NonceEvent ::= (250: Byte) (nonce: Nonce) (sponsoree: AccountAddress) + NonceEvent ::= (250: Byte) (nonce: Nonce) (sponsoree: PublicKeyEd25519) -``DepositNativeCurrencyEvent`` -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +``DepositCcdEvent`` +^^^^^^^^^^^^^^^^^^^ -A ``DepositNativeCurrencyEvent`` SHALL be logged ever time an amount of CCD received by the contract is assigned to a public key. +A ``DepositCcdEvent`` SHALL be logged ever time an amount of CCD received by the contract is assigned to a public key. -The ``DepositNativeCurrencyEvent`` is serialized as: First a byte with the value of 249, followed by the :ref:`CIS-5-CCDAmount` (``ccdAmount``), the :ref:`CIS-5-Address` (``from``), and a :ref:`CIS-5-PublicKeyEd25519` (``to``):: +The ``DepositCcdEvent`` is serialized as: First a byte with the value of 249, followed by the :ref:`CIS-5-CCDAmount` (``ccdAmount``), the :ref:`CIS-5-Address` (``from``), and a :ref:`CIS-5-PublicKeyEd25519` (``to``):: - DepositNativeCurrencyEvent ::= (249: Byte) (ccdAmount: CCDAmount) (from: Address) (to: PublicKeyEd25519) + DepositCcdEvent ::= (249: Byte) (ccdAmount: CCDAmount) (from: Address) (to: PublicKeyEd25519) ``DepositCis2TokensEvent`` ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -251,14 +237,14 @@ The ``DepositCis2TokensEvent`` is serialized as: First a byte with the value of DepositCis2TokensEvent ::= (248: Byte) (tokenAmount: TokenAmount) (tokenId: TokenID) (cis2TokenContractAddress: ContractAddress) (from: Address) (to: PublicKeyEd25519) -``WithdrawNativeCurrencyEvent`` -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +``WithdrawCcdEvent`` +^^^^^^^^^^^^^^^^^^^^ -A ``WithdrawNativeCurrencyEvent`` SHALL be logged ever time an amount of CCD held by a public key is withdrawn to an address. +A ``WithdrawCcdEvent`` SHALL be logged ever time an amount of CCD held by a public key is withdrawn to an address. -The ``WithdrawNativeCurrencyEvent`` is serialized as: First a byte with the value of 247, followed by the :ref:`CIS-5-CCDAmount` (``ccdAmount``), a :ref:`CIS-5-PublicKeyEd25519` (``from``), and the :ref:`CIS-5-Address` (``to``):: +The ``WithdrawCcdEvent`` is serialized as: First a byte with the value of 247, followed by the :ref:`CIS-5-CCDAmount` (``ccdAmount``), a :ref:`CIS-5-PublicKeyEd25519` (``from``), and the :ref:`CIS-5-Address` (``to``):: - DepositNativeCurrencyEvent ::= (247: Byte) (ccdAmount: CCDAmount) (from: PublicKeyEd25519) (to: Address) + WithdrawCcdEvent ::= (247: Byte) (ccdAmount: CCDAmount) (from: PublicKeyEd25519) (to: Address) ``WithdrawCis2TokensEvent`` ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -271,25 +257,25 @@ The ``WithdrawCis2TokensEvent`` is serialized as: First a byte with the value of WithdrawCis2TokensEvent ::= (246: Byte) (tokenAmount: TokenAmount) (tokenId: TokenID) (cis2TokenContractAddress: ContractAddress) (from: PublicKeyEd25519) (to: Address) -``InternalNativeCurrencyTransferEvent`` -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +``TransferCcdEvent`` +^^^^^^^^^^^^^^^^^^^^ -A ``InternalNativeCurrencyTransferEvent`` SHALL be logged ever time an amount of CCD held by a public key is transferred to another public key within the contract. +A ``TransferCcdEvent`` SHALL be logged ever time an amount of CCD held by a public key is transferred to another public key within the contract. -The ``InternalNativeCurrencyTransferEvent`` is serialized as: First a byte with the value of 245, followed by the :ref:`CIS-5-CCDAmount` (``ccdAmount``), a :ref:`CIS-5-PublicKeyEd25519` (``from``), and the :ref:`CIS-5-PublicKeyEd25519` (``to``):: +The ``TransferCcdEvent`` is serialized as: First a byte with the value of 245, followed by the :ref:`CIS-5-CCDAmount` (``ccdAmount``), a :ref:`CIS-5-PublicKeyEd25519` (``from``), and the :ref:`CIS-5-PublicKeyEd25519` (``to``):: - InternalNativeCurrencyTransferEvent ::= (245: Byte) (ccdAmount: CCDAmount) (from: PublicKeyEd25519) (to: PublicKeyEd25519) + TransferCcdEvent ::= (245: Byte) (ccdAmount: CCDAmount) (from: PublicKeyEd25519) (to: PublicKeyEd25519) -``InternalCis2TokensTransferEvent`` -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +``TransferCis2TokensEvent`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^ -A ``InternalCis2TokensTransferEvent`` SHALL be logged ever time a token amount held by a public key is transferred to another public key within the contract. +A ``TransferCis2TokensEvent`` SHALL be logged ever time a token amount held by a public key is transferred to another public key within the contract. -The ``InternalCis2TokensTransferEvent`` is serialized as: First a byte with the value of 244, followed by the +The ``TransferCis2TokensEvent`` is serialized as: First a byte with the value of 244, followed by the :ref:`CIS-5-TokenAmount` (``tokenAmount``), :ref:`CIS-5-TokenID` (``TokenID``), :ref:`CIS-5-ContractAddress` (``cis2TokenContractAddress``), a :ref:`CIS-5-PublicKeyEd25519` (``from``), and the :ref:`CIS-5-PublicKeyEd25519` (``to``):: - InternalCis2TokensTransferEvent ::= (244: Byte) (tokenAmount: TokenAmount) (tokenId: TokenID) (cis2TokenContractAddress: ContractAddress) (from: PublicKeyEd25519) (to: PublicKeyEd25519) + TransferCis2TokensEvent ::= (244: Byte) (tokenAmount: TokenAmount) (tokenId: TokenID) (cis2TokenContractAddress: ContractAddress) (from: PublicKeyEd25519) (to: PublicKeyEd25519) .. note:: @@ -302,22 +288,22 @@ Contract functions A smart contract implementing this standard MUST export the following functions: -- :ref:`CIS-5-functions-depositNativeCurrency` +- :ref:`CIS-5-functions-depositCcd` - :ref:`CIS-5-functions-depositCis2Tokens` -- :ref:`CIS-5-functions-withdrawNativeCurrency` +- :ref:`CIS-5-functions-withdrawCcd` - :ref:`CIS-5-functions-withdrawCis2Tokens` -- :ref:`CIS-5-functions-internalNativeCurrencyTransfer` -- :ref:`CIS-5-functions-internalCis2TokensTransfer` -- :ref:`CIS-5-functions-balanceOfNativeCurrency` -- :ref:`CIS-5-functions-balanceOfCis2Tokens` +- :ref:`CIS-5-functions-transferCcd` +- :ref:`CIS-5-functions-transferCis2Tokens` +- :ref:`CIS-5-functions-ccdBalanceOf` +- :ref:`CIS-5-functions-cis2BalanceOf` -.. _CIS-5-functions-depositNativeCurrency: +.. _CIS-5-functions-depositCcd: -``depositNativeCurrency`` -^^^^^^^^^^^^^^^^^^^^^^^^^ +``depositCcd`` +^^^^^^^^^^^^^^ -The function is payable and deposits/assigns the send CCDAmount (native currency) to a public key (``PublicKeyEd25519``). +The function is payable and deposits/assigns the send CCDAmount to a public key (``PublicKeyEd25519``). Parameter ~~~~~~~~~ @@ -356,12 +342,12 @@ Requirements - The function SHOULD check that a contract is the caller since only a contract can implement a receive hook mechanism. -.. _CIS-5-functions-withdrawNativeCurrency: +.. _CIS-5-functions-withdrawCcd: -``withdrawNativeCurrency`` -^^^^^^^^^^^^^^^^^^^^^^^^^^ +``withdrawCcd`` +^^^^^^^^^^^^^^^ -The function executes a list of token withdrawals of CCDs (native currency) to native accounts and/or smart contracts out of the smart contract wallet. +The function executes a list of token withdrawals of CCDs to native accounts and/or smart contracts out of the smart contract wallet. When transferring CCD to a contract address, a CCD receive hook function MUST be triggered. Parameter @@ -369,30 +355,39 @@ Parameter The parameter is a list of withdrawals. -It is serialized as: 2 bytes representing the number of withdrawals (``n``) followed by the bytes for this number of withdrawals. +It is serialized as: 2 bytes representing the number of withdrawals (``n``) followed by the bytes for this number of ``withdrawals``. + +Each ``WithdrawBatchCcdAmount`` is serialized as: a :ref:`CIS-5-PublicKeyEd25519` (``signer``), a :ref:`CIS-5-SignatureEd25519` (``signature``), and a ``WithdrawMessageCcdAmount`` (``message``). -Each ``NativeCurrencyWithdrawal`` is serialized as: a :ref:`CIS-5-PublicKeyEd25519` (``signer``), a :ref:`CIS-5-SignatureEd25519` (``signature``), -a :ref:`CIS-5-TimeStamp` (``expiryTime``), a :ref:`CIS-5-Nonce` (``nonce``), a :ref:`CIS-5-CCDAmount` (``serviceFee``), an :ref:`CIS-5-Address` (``serviceFeeRecipient``), 2 bytes representing the number of simple withdraws (``m``) followed by the bytes for this number of simple withdraws (``simple_withdraw``). +Each ``WithdrawMessageCcdAmount`` is serialized as: an :ref:`CIS-5-EntrypointName` (``entryPoint``), a :ref:`CIS-5-TimeStamp` (``expiryTime``), a :ref:`CIS-5-Nonce` (``nonce``), a :ref:`CIS-5-PublicKeyEd25519` (``serviceFeeRecipient``), a :ref:`CIS-5-CCDAmount` (``serviceFee``), 2 bytes representing the number of simple withdraws (``m``) followed by the bytes for this number of simple withdraws (``simpleWithdraws``). -Each ``NativeCurrencyWithdrawalBatch`` is serialized as: the receiving address :ref:`CIS-2-Receiver` (``to``), the :ref:`CIS-5-CCDAmount` (``ccdAmount``), and some additional data :ref:`CIS-2-AdditionalData` (``data``):: +Each ``WithdrawCcdAmount`` is serialized as: the receiving address :ref:`CIS-2-Receiver` (``to``), the :ref:`CIS-5-CCDAmount` (``withdrawAmount``), and some additional data :ref:`CIS-2-AdditionalData` (``data``):: - NativeCurrencyWithdrawalBatch ::= (to: Receiver) (ccdAmount: CCDAmount) (data: AdditionalData) + WithdrawCcdAmount ::= (to: Receiver) (withdrawAmount: CCDAmount) (data: AdditionalData) - NativeCurrencyWithdrawal ::= (signer: PublicKeyEd25519) (signature: SignatureEd25519) (expiryTime: TimeStamp) (nonce: u64) (serviceFee: CCDAmount) (serviceFeeRecipient: Address) (m: Byte²) (simple_withdraw: NativeCurrencyWithdrawalBatchᵐ) + WithdrawMessageCcdAmount ::= (entryPoint: EntrypointName) (expiryTime: TimeStamp) (nonce: u64) (serviceFeeRecipient: PublicKeyEd25519) (serviceFee: CCDAmount) (m: Byte²) (simpleWithdraws: WithdrawCcdAmountᵐ) - NativeCurrencyWithdrawParameter ::= (n: Byte²) (withdrawal: NativeCurrencyWithdrawalⁿ) + WithdrawBatchCcdAmount ::= (signer: PublicKeyEd25519) (signature: SignatureEd25519) (message: WithdrawMessageCcdAmount) + + WithdrawParameterCcdAmount ::= (n: Byte²) (withdrawals: WithdrawBatchCcdAmountⁿ) .. _CIS-5-functions-transfer-ccd-receive-hook-parameter: CCD Receive hook parameter ~~~~~~~~~~~~~~~~~~~~~~~~~~ -The parameter for the CCD receive hook function contains information about the transfer and some additional data bytes. +The parameter for the CCD receive hook function contains some additional data bytes. + +It is serialized as: some additional data :ref:`CIS-2-AdditionalData` (``data``):: -It is serialized as: a :ref:`CIS-5-CCDAmount` (``ccdAmount``), a :ref:`CIS-5-PublicKeyEd25519` (``from``), and some additional data :ref:`CIS-2-AdditionalData` (``data``):: + CCDReceiveHookParameter ::= (data: AdditionalData) - CCDReceiveHookParameter ::= (ccdAmount: CCDAmount) (from: PublicKeyEd25519) (data: AdditionalData) +Generating a valid signature +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +To generate a valid signature for the entry point, the following bytes have to be signed:: + + WithdrawCCDSigningData ::= (chainContext: ChainContext) (param: WithdrawParameterCcdAmount) Requirements ~~~~~~~~~~~~ @@ -401,13 +396,13 @@ Requirements - The contract function MUST reject if any of the withdrawals fail to be executed. - The function MUST reject if the signature verification fails for any withdrawal. - The function MUST fail if the CCD balance of the ``signer`` is insufficient to do the withdrawal for any withdrawal. -- A function MUST non-strictly decrease the CCD balance of the ``signer`` public key and non-strictly increase the balance of the ``to`` address or fail for any withdrawal. -- A withdrawal back to this contract into the ``depositNativeCurrency`` entrypoint MUST be executed as a normal withdrawal. +- A function MUST non-strictly decrease the CCD balance of the ``signer```s public key and non-strictly increase the balance of the ``to`` address or fail for any withdrawal. +- A withdrawal back to this contract into the ``depositCcd`` entrypoint MUST be executed as a normal withdrawal. - A withdrawal of a CCD amount of zero MUST be executed as a normal withdrawal. - A withdrawal of any amount of CCD to a contract address MUST call a CCD receive hook function on the receiving smart contract with a :ref:`ccd receive hook parameter`. - The contract function MUST reject if the CCD receive hook function called on the contract receiving CCDs rejects for any withdrawal. - The balance of a public key not owning any CCD amount SHOULD be treated as having a balance of zero. -- The function MUST transfer the ``serviceFee`` to the ``serviceFeeRecipient`` for every withdrawal if ``serviceFee!=0``. +- The function MUST transfer the ``serviceFee`` to the ``serviceFeeRecipient`` for each batch withdrawal if ``serviceFee!=0``. .. warning:: @@ -428,15 +423,28 @@ Parameter The parameter is a list of withdrawals. -It is serialized as: 2 bytes representing the number of withdrawals (``n``) followed by the bytes for this number of withdrawals. +It is serialized as: 2 bytes representing the number of withdrawals (``n``) followed by the bytes for this number of ``withdrawals``. + +Each ``WithdrawBatchTokenAmount`` is serialized as: a :ref:`CIS-5-PublicKeyEd25519` (``signer``), a :ref:`CIS-5-SignatureEd25519` (``signature``), and a ``WithdrawMessageTokenAmount`` (``message``). + +Each ``WithdrawMessageTokenAmount`` is serialized as: an :ref:`CIS-5-EntrypointName` (``entryPoint``), a :ref:`CIS-5-TimeStamp` (``expiryTime``), a :ref:`CIS-5-Nonce` (``nonce``), a :ref:`CIS-5-PublicKeyEd25519` (``serviceFeeRecipient``), a :ref:`CIS-5-ExternalTokenAmount` (``serviceFee``), 2 bytes representing the number of simple withdraws (``m``) followed by the bytes for this number of simple withdraws (``simpleWithdraws``). + +Each ``WithdrawTokenAmount`` is serialized as: the receiving address :ref:`CIS-2-Receiver` (``to``), the :ref:`CIS-5-ExternalTokenAmount` (``withdrawAmount``), and some additional data :ref:`CIS-2-AdditionalData` (``data``):: + + WithdrawTokenAmount ::= (to: Receiver) (withdrawAmount: ExternalTokenAmount) (data: AdditionalData) -Each withdrawal is serialized as: a :ref:`CIS-5-PublicKeyEd25519` (``signer``), a :ref:`CIS-5-SignatureEd25519` (``signature``), -a :ref:`CIS-5-TimeStamp` (``expiryTime``), a :ref:`CIS-5-Nonce` (``nonce``), a :ref:`CIS-5-TokenAmount` (``serviceFee``), an :ref:`CIS-5-Address` (``serviceFeeRecipient``), -a :ref:`CIS-5-ContractAddress` (``cis2TokenContractAddress``), and :ref:`CIS-2-TransferParameter` (``transferParameter``):: + WithdrawMessageTokenAmount ::= (entryPoint: EntrypointName) (expiryTime: TimeStamp) (nonce: u64) (serviceFeeRecipient: PublicKeyEd25519) (serviceFee: ExternalTokenAmount) (m: Byte²) (simpleWithdraws: WithdrawTokenAmountᵐ) - Cis2TokensWithdrawal ::= (signer: PublicKeyEd25519) (signature: SignatureEd25519) (expiryTime: TimeStamp) (nonce: u64) (serviceFee: TokenAmount) (serviceFeeRecipient: Address) (cis2TokenContractAddress: ContractAddress) (transferParameter: TransferParameter) + WithdrawBatchTokenAmount ::= (signer: PublicKeyEd25519) (signature: SignatureEd25519) (message: WithdrawMessageTokenAmount) - Cis2TokensWithdrawParameter ::= (n: Byte²) (withdrawal: Cis2TokensWithdrawalⁿ) + WithdrawParameterTokenAmount ::= (n: Byte²) (withdrawals: WithdrawBatchTokenAmountⁿ) + +Generating a valid signature +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +To generate a valid signature for the entry point, the following bytes have to be signed:: + + WithdrawTokensSigningData ::= (chainContext: ChainContext) (param: WithdrawParameterTokenAmount) Requirements ~~~~~~~~~~~~ @@ -450,85 +458,102 @@ Requirements - A withdrawal back to this contract into the ``depositCis2Tokens`` entrypoint MUST be executed as a normal withdrawal. - A withdrawal of a token amount of zero MUST be executed as a normal withdrawal. - The balance of a public key not owning any tokens SHOULD be treated as having a balance of zero. -- The function MUST transfer the ``serviceFee`` to the ``serviceFeeRecipient`` for every withdrawal if ``serviceFee!=0``. +- The function MUST transfer the ``serviceFee`` to the ``serviceFeeRecipient`` for each batch withdrawal if ``serviceFee!=0``. -.. _CIS-5-functions-internalNativeCurrencyTransfer: +.. _CIS-5-functions-transferCcd: -``internalNativeCurrencyTransfer`` -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -The function executes a list of CCD internal transfers to public keys within the smart contract wallet. +``transferCcd`` +^^^^^^^^^^^^^^^ +The function executes a list of CCD transfers to public keys within the smart contract wallet. Parameter ~~~~~~~~~ -The parameter is a list of internal transfers. +The parameter is a list of transfers. + +It is serialized as: 2 bytes representing the number of transfers (``n``) followed by the bytes for this number of ``transfers``. + +Each ``TransferBatchCcdAmount`` is serialized as: a :ref:`CIS-5-PublicKeyEd25519` (``signer``), a :ref:`CIS-5-SignatureEd25519` (``signature``), and a ``TransferMessageCcdAmount`` (``message``). -It is serialized as: 2 bytes representing the number of transfers (``n``) followed by the bytes for this number of internal transfers. +Each ``TransferMessageCcdAmount`` is serialized as: an :ref:`CIS-5-EntrypointName` (``entryPoint``), a :ref:`CIS-5-TimeStamp` (``expiryTime``), a :ref:`CIS-5-Nonce` (``nonce``), a :ref:`CIS-5-PublicKeyEd25519` (``serviceFeeRecipient``), a :ref:`CIS-5-CCDAmount` (``serviceFee``), 2 bytes representing the number of simple transfers (``m``) followed by the bytes for this number of simple transers (``simpleTransfers``). -Each ``NativeCurrencyInternalTransfer`` is serialized as: a :ref:`CIS-5-PublicKeyEd25519` (``signer``), a :ref:`CIS-5-SignatureEd25519` (``signature``), -a :ref:`CIS-5-TimeStamp` (``expiryTime``), a :ref:`CIS-5-Nonce` (``nonce``), a :ref:`CIS-5-CCDAmount` (``serviceFee``), an :ref:`CIS-5-Address` (``serviceFeeRecipient``), -2 bytes representing the number of simple transfers (``m``) followed by the bytes for this number of simple transfers (``simple_transfer``). +Each ``TransferCcdAmount`` is serialized as: the receiving :ref:`CIS-5-PublicKeyEd25519` (``to``), and the :ref:`CIS-5-CCDAmount` (``transferAmount``):: -Each ``NativeCurrencyInternalTransferBatch`` is serialized as: a :ref:`CIS-5-PublicKeyEd25519` (``from``), a :ref:`CIS-5-PublicKeyEd25519` (``to``), and a :ref:`CIS-5-CCDAmount` (``ccdAmount``):: + TransferCcdAmount ::= (to: PublicKeyEd25519) (transferAmount: CCDAmount) - NativeCurrencyInternalTransferBatch ::= (from: PublicKeyEd25519) (to: PublicKeyEd25519) (ccdAmount: CCDAmount) + TransferMessageCcdAmount ::= (entryPoint: EntrypointName) (expiryTime: TimeStamp) (nonce: u64) (serviceFeeRecipient: PublicKeyEd25519) (serviceFee: CCDAmount) (m: Byte²) (simpleTransfers: TransferCcdAmountᵐ) - NativeCurrencyInternalTransfer ::= (signer: PublicKeyEd25519) (signature: SignatureEd25519) (expiryTime: TimeStamp) (nonce: u64) (serviceFee: CCDAmount) (serviceFeeRecipient: Address) (m: Byte²) (simple_transfer: NativeCurrencyInternalTransferBatchᵐ) + TransferBatchCcdAmount ::= (signer: PublicKeyEd25519) (signature: SignatureEd25519) (message: TransferMessageCcdAmount) - NativeCurrencyInternalTransferParameter ::= (n: Byte²) (transfer: NativeCurrencyInternalTransfer) + TransferParameterCcdAmount ::= (n: Byte²) (transfers: TransferBatchCcdAmount) +Generating a valid signature +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +To generate a valid signature for the entry point, the following bytes have to be signed:: + + TransferCCDSigningData ::= (chainContext: ChainContext) (param: TransferParameterCcdAmount) Requirements ~~~~~~~~~~~~ - The function MUST reject if the signature verification fails for any transfer. - The function MUST fail if the CCD balance of the ``signer`` is insufficient to do the transfer for any transfer. -- A function MUST non-strictly decrease the CCD balance of the ``signer`` public key and non-strictly increase the balance of the ``to`` address or fail for any transfer. +- A function MUST non-strictly decrease the CCD balance of the ``signer`` public key and non-strictly increase the balance of the ``to`` public key or fail for any transfer. - A transfer of a CCD amount of zero MUST be executed as a normal transfer. - The balance of a public key not owning any CCD amount SHOULD be treated as having a balance of zero. -- The function MUST transfer the ``serviceFee`` to the ``serviceFeeRecipient`` for every transfer if ``serviceFee!=0``. +- The function MUST transfer the ``serviceFee`` to the ``serviceFeeRecipient`` for each batch transfer if ``serviceFee!=0``. -.. _CIS-5-functions-internalCis2TokensTransfer: +.. _CIS-5-functions-transferCis2Tokens: -``internalCis2TokensTransfer`` -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +``transferCis2Tokens`` +^^^^^^^^^^^^^^^^^^^^^^ -The function executes a list of token internal transfers to public keys within the smart contract wallet. +The function executes a list of token transfers to public keys within the smart contract wallet. Parameter ~~~~~~~~~ -The parameter is a list of internal transfers. +The parameter is a list of transfers. + +It is serialized as: 2 bytes representing the number of transfers (``n``) followed by the bytes for this number of ``transfers``. + +Each ``TransferBatchTokenAmount`` is serialized as: a :ref:`CIS-5-PublicKeyEd25519` (``signer``), a :ref:`CIS-5-SignatureEd25519` (``signature``), and a ``TransferMessageTokenAmount`` (``message``). + +Each ``TransferMessageTokenAmount`` is serialized as: an :ref:`CIS-5-EntrypointName` (``entryPoint``), a :ref:`CIS-5-TimeStamp` (``expiryTime``), a :ref:`CIS-5-Nonce` (``nonce``), a :ref:`CIS-5-PublicKeyEd25519` (``serviceFeeRecipient``), a :ref:`CIS-5-ExternalTokenAmount` (``serviceFee``), 2 bytes representing the number of simple transfers (``m``) followed by the bytes for this number of simple transfers (``simpleTransfers``). + +Each ``TransferTokenAmount`` is serialized as: the receiving :ref:`CIS-5-PublicKeyEd25519` (``to``), the :ref:`CIS-5-ExternalTokenAmount` (``transferAmount``):: -It is serialized as: 2 bytes representing the number of transfers (``n``) followed by the bytes for this number of internal transfers. + TransferTokenAmount ::= (to: PublicKeyEd25519) (transferAmount: ExternalTokenAmount) -Each ``Cis2TokensInternalTransfer`` is serialized as: a :ref:`CIS-5-PublicKeyEd25519` (``signer``), a :ref:`CIS-5-SignatureEd25519` (``signature``), -a :ref:`CIS-5-TimeStamp` (``expiryTime``), a :ref:`CIS-5-Nonce` (``nonce``), a :ref:`CIS-5-TokenAmount` (``serviceFee``), an :ref:`CIS-5-Address` (``serviceFeeRecipient``), -2 bytes representing the number of simple transfers (``m``) followed by the bytes for this number of simple transfers (``simple_transfer``). + TransferMessageTokenAmount ::= (entryPoint: EntrypointName) (expiryTime: TimeStamp) (nonce: u64) (serviceFeeRecipient: PublicKeyEd25519) (serviceFee: ExternalTokenAmount) (m: Byte²) (simpletransfers: TransferTokenAmountᵐ) -Each ``Cis2TokensInternalTransferBatch`` is serialized as: a :ref:`CIS-5-PublicKeyEd25519` (``from``), a :ref:`CIS-5-PublicKeyEd25519` (``to``), a :ref:`CIS-5-TokenAmount` (``tokenAmount``), a :ref:`CIS-5-TokenID` (``tokenID``), and a :ref:`CIS-5-ContractAddress` (``cis2TokenContractAddress``):: + TransferBatchTokenAmount ::= (signer: PublicKeyEd25519) (signature: SignatureEd25519) (message: TransferMessageTokenAmount) - Cis2TokensInternalTransferBatch ::= (from: PublicKeyEd25519) (to: PublicKeyEd25519) (tokenAmount: tokenAmount) (tokenID: TokenID) (cis2TokenContractAddress: ContractAddress) + TransferParameterTokenAmount ::= (n: Byte²) (transfers: TransferBatchTokenAmountⁿ) - Cis2TokensInternalTransfer ::= (signer: PublicKeyEd25519) (signature: SignatureEd25519) (expiryTime: TimeStamp) (nonce: u64) (serviceFee: TokenAmount) (serviceFeeRecipient: Address) (m: Byte²) (simple_transfer: Cis2TokensInternalTransferBatchᵐ) - Cis2TokensInternalTransferParameter ::= (n: Byte²) (transfer: Cis2TokensInternalTransfer) +Generating a valid signature +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +To generate a valid signature for the entry point, the following bytes have to be signed:: + + TransferTokensSigningData ::= (chainContext: ChainContext) (param: TransferParameterTokenAmount) Requirements ~~~~~~~~~~~~ - The function MUST reject if the signature verification fails for any of the transfers. - The function MUST fail if the token balance of the ``signer`` is insufficient to do the transfer for any transfer. -- A function MUST non-strictly decrease the token balance of the ``signer`` public key and non-strictly increase the balance of the ``to`` address or fail for any transfer. +- A function MUST non-strictly decrease the token balance of the ``signer`` public key and non-strictly increase the balance of the ``to`` public key or fail for any transfer. - A transfer of a token amount of zero MUST be executed as a normal transfer. - The balance of a public key not owning any tokens SHOULD be treated as having a balance of zero. -- The function MUST transfer the ``serviceFee`` to the ``serviceFeeRecipient`` for every transfer if ``serviceFee!=0``. +- The function MUST transfer the ``serviceFee`` to the ``serviceFeeRecipient`` for each batch transfer if ``serviceFee!=0``. -.. _CIS-5-functions-balanceOfNativeCurrency: +.. _CIS-5-functions-ccdBalanceOf: -``balanceOfNativeCurrency`` -^^^^^^^^^^^^^^^^^^^^^^^^^^^ +``ccdBalanceOf`` +^^^^^^^^^^^^^^^^ The function queries the CCD balances of a list of public keys. @@ -537,12 +562,9 @@ Parameter The parameter consists of a list of public keys. -It is serialized as: 2 bytes for the number of queries (``n``) and then this number of queries (``queries``). -A query is serialized as a :ref:`CIS-5-PublicKeyEd25519` (``publicKey``):: - - NativeCurrencyBalanceOfQuery ::= (publicKey: PublicKeyEd25519) +It is serialized as: 2 bytes for the number of public keys (``n``) and then this number of :ref:`CIS-5-PublicKeyEd25519` (``publicKeys``):: - NativeCurrencyBalanceOfParameter ::= (n: Byte²) (queries: NativeCurrencyBalanceOfQueryⁿ) + CCDBalanceOfParameter ::= (n: Byte²) (publicKeys: PublicKeyEd25519ⁿ) Response ~~~~~~~~ @@ -551,21 +573,21 @@ The function output response is a list of CCD amounts. It is serialized as: 2 bytes for the number of CCD amounts (``n``) and then this number of :ref:`CIS-5-CCDAmount` (``results``):: - NativeCurrencyBalanceOfResponse ::= (n: Byte²) (results: CCDAmountⁿ) + CCDBalanceOfResponse ::= (n: Byte²) (results: CCDAmountⁿ) Requirements ~~~~~~~~~~~~ - The balance of a public key not owning any CCD SHOULD be treated as having a balance of zero. -- The number of results in the response MUST correspond to the number of the queries in the parameter. -- The order of results in the response MUST correspond to the order of queries in the parameter. +- The number of results in the response MUST correspond to the number of the public keys in the parameter. +- The order of results in the response MUST correspond to the order of public keys in the parameter. - The contract function MUST NOT increase or decrease the CCD balance or token balance of any public key for any token type. -.. _CIS-5-functions-balanceOfCis2Tokens: +.. _CIS-5-functions-cis2BalanceOf: -``balanceOfCis2Tokens`` -^^^^^^^^^^^^^^^^^^^^^^^ +``cis2BalanceOf`` +^^^^^^^^^^^^^^^^^ The function queries the token balances of a list of public keys for given token IDs, and CIS-2 token contract addresses. From 6661d4595404888f8cc98afe5f5d6807cc54c299 Mon Sep 17 00:00:00 2001 From: Doris Benda Date: Thu, 23 May 2024 09:50:58 +0300 Subject: [PATCH 09/10] Address comments --- source/CIS/cis-5.rst | 46 ++++++++++++++++++++++++-------------------- 1 file changed, 25 insertions(+), 21 deletions(-) diff --git a/source/CIS/cis-5.rst b/source/CIS/cis-5.rst index c6b2c48..0afa098 100644 --- a/source/CIS/cis-5.rst +++ b/source/CIS/cis-5.rst @@ -9,6 +9,8 @@ CIS-5: Smart Contract Wallet Standard * - Created - Mar 17, 2024 + * - Final + - May 23, 2024 * - Supported versions - | Smart contract version 1 or newer | (Protocol version 4 or newer) @@ -24,10 +26,10 @@ A standard interface for defining a smart contract wallet that can hold and tran CCDs/CIS-2 tokens can be deposited into the smart contract wallet by specifying to which public key the deposit should be assigned. -The holder of the corresponding private key does not have to submit transactions +The holder of the corresponding private key does not submit transactions on chain to transfer/withdraw its CCD/CIS-2 token balances, but instead, it can generate a valid signature, identify a willing third -party to submit its signature on-chain (a service fee can be added to financially incentivize a third party to do so). +party to submit its signature in a transaction on-chain (a service fee can be added to financially incentivize a third party to do so). The three main actions in the smart contract that can be taken: @@ -37,8 +39,9 @@ The three main actions in the smart contract that can be taken: - *withdraw*: withdraws the balance out of the smart contract wallet to a native account or smart contract. -The goal of this standard is to simplify the account creation onboarding flow on Concordium -allowing for CIS-5 smart contract wallets to be supported as first-class citizens in Concordium wallets and tooling. +The goal of this standard is to create an alternative simplified onboarding flow +without the inconvenience of a native account creation on Concordium. +Allowing for CIS-5 smart contract wallets to be supported as first-class citizens in Concordium wallets and tooling. Specification ============= @@ -57,6 +60,7 @@ General types and serialization ``TokenID`` ^^^^^^^^^^^ +The token ID is from the CIS-2 standard :ref:`CIS-2-TokenID`. A token ID is serialized as 1 byte for the size (``n``) of the identifier, followed by this number of bytes for the token id (``id``):: TokenID ::= (n: Byte) (id: Byteⁿ) @@ -66,6 +70,7 @@ A token ID is serialized as 1 byte for the size (``n``) of the identifier, follo ``TokenAmount`` ^^^^^^^^^^^^^^^ +The token amount is from the CIS-2 standard :ref:`CIS-2-TokenAmount`. It is serialized using the LEB128_ variable-length unsigned integer encoding, with the additional constraint that the total number of bytes of the encoding MUST not exceed 37 bytes:: TokenAmount ::= (x: Byte) => x if x < 2^7 @@ -220,7 +225,7 @@ The ``NonceEvent`` is serialized as: First a byte with the value of 250, followe ``DepositCcdEvent`` ^^^^^^^^^^^^^^^^^^^ -A ``DepositCcdEvent`` SHALL be logged ever time an amount of CCD received by the contract is assigned to a public key. +A ``DepositCcdEvent`` SHALL be logged every time an amount of CCD received by the contract is assigned to a public key. The ``DepositCcdEvent`` is serialized as: First a byte with the value of 249, followed by the :ref:`CIS-5-CCDAmount` (``ccdAmount``), the :ref:`CIS-5-Address` (``from``), and a :ref:`CIS-5-PublicKeyEd25519` (``to``):: @@ -229,7 +234,7 @@ The ``DepositCcdEvent`` is serialized as: First a byte with the value of 249, fo ``DepositCis2TokensEvent`` ^^^^^^^^^^^^^^^^^^^^^^^^^^ -A ``DepositCis2TokensEvent`` SHALL be logged ever time a token amount received by the contract is assigned to a public key. +A ``DepositCis2TokensEvent`` SHALL be logged every time a token amount received by the contract is assigned to a public key. The ``DepositCis2TokensEvent`` is serialized as: First a byte with the value of 248, followed by the :ref:`CIS-5-TokenAmount` (``tokenAmount``), :ref:`CIS-5-TokenID` (``TokenID``), @@ -240,7 +245,7 @@ The ``DepositCis2TokensEvent`` is serialized as: First a byte with the value of ``WithdrawCcdEvent`` ^^^^^^^^^^^^^^^^^^^^ -A ``WithdrawCcdEvent`` SHALL be logged ever time an amount of CCD held by a public key is withdrawn to an address. +A ``WithdrawCcdEvent`` SHALL be logged every time an amount of CCD held by a public key is withdrawn to an address. The ``WithdrawCcdEvent`` is serialized as: First a byte with the value of 247, followed by the :ref:`CIS-5-CCDAmount` (``ccdAmount``), a :ref:`CIS-5-PublicKeyEd25519` (``from``), and the :ref:`CIS-5-Address` (``to``):: @@ -249,7 +254,7 @@ The ``WithdrawCcdEvent`` is serialized as: First a byte with the value of 247, f ``WithdrawCis2TokensEvent`` ^^^^^^^^^^^^^^^^^^^^^^^^^^^ -A ``WithdrawCis2TokensEvent`` SHALL be logged ever time a token amount held by a public key is withdrawn to an address. +A ``WithdrawCis2TokensEvent`` SHALL be logged every time a token amount held by a public key is withdrawn to an address. The ``WithdrawCis2TokensEvent`` is serialized as: First a byte with the value of 246, followed by the :ref:`CIS-5-TokenAmount` (``tokenAmount``), :ref:`CIS-5-TokenID` (``TokenID``), @@ -260,7 +265,7 @@ The ``WithdrawCis2TokensEvent`` is serialized as: First a byte with the value of ``TransferCcdEvent`` ^^^^^^^^^^^^^^^^^^^^ -A ``TransferCcdEvent`` SHALL be logged ever time an amount of CCD held by a public key is transferred to another public key within the contract. +A ``TransferCcdEvent`` SHALL be logged every time an amount of CCD held by a public key is transferred to another public key within the contract. The ``TransferCcdEvent`` is serialized as: First a byte with the value of 245, followed by the :ref:`CIS-5-CCDAmount` (``ccdAmount``), a :ref:`CIS-5-PublicKeyEd25519` (``from``), and the :ref:`CIS-5-PublicKeyEd25519` (``to``):: @@ -269,7 +274,7 @@ The ``TransferCcdEvent`` is serialized as: First a byte with the value of 245, f ``TransferCis2TokensEvent`` ^^^^^^^^^^^^^^^^^^^^^^^^^^^ -A ``TransferCis2TokensEvent`` SHALL be logged ever time a token amount held by a public key is transferred to another public key within the contract. +A ``TransferCis2TokensEvent`` SHALL be logged every time a token amount held by a public key is transferred to another public key within the contract. The ``TransferCis2TokensEvent`` is serialized as: First a byte with the value of 244, followed by the :ref:`CIS-5-TokenAmount` (``tokenAmount``), :ref:`CIS-5-TokenID` (``TokenID``), @@ -279,7 +284,7 @@ The ``TransferCis2TokensEvent`` is serialized as: First a byte with the value of .. note:: - The CIS-5 events SHALL enable off-chain applications to compute off-chain all balances that the public keys are holding. + The collection of all CIS-5 events emitted by a smart contract instance implementing CIS-5 SHALL enable off-chain applications to compute off-chain all non-zero balances that the public keys are holding. .. _CIS-5-functions: @@ -359,13 +364,13 @@ It is serialized as: 2 bytes representing the number of withdrawals (``n``) foll Each ``WithdrawBatchCcdAmount`` is serialized as: a :ref:`CIS-5-PublicKeyEd25519` (``signer``), a :ref:`CIS-5-SignatureEd25519` (``signature``), and a ``WithdrawMessageCcdAmount`` (``message``). -Each ``WithdrawMessageCcdAmount`` is serialized as: an :ref:`CIS-5-EntrypointName` (``entryPoint``), a :ref:`CIS-5-TimeStamp` (``expiryTime``), a :ref:`CIS-5-Nonce` (``nonce``), a :ref:`CIS-5-PublicKeyEd25519` (``serviceFeeRecipient``), a :ref:`CIS-5-CCDAmount` (``serviceFee``), 2 bytes representing the number of simple withdraws (``m``) followed by the bytes for this number of simple withdraws (``simpleWithdraws``). +Each ``WithdrawMessageCcdAmount`` is serialized as: an :ref:`CIS-5-EntrypointName` (``entryPoint``), a :ref:`CIS-5-Timestamp` (``expiryTime``), a :ref:`CIS-5-Nonce` (``nonce``), a :ref:`CIS-5-PublicKeyEd25519` (``serviceFeeRecipient``), a :ref:`CIS-5-CCDAmount` (``serviceFee``), 2 bytes representing the number of simple withdraws (``m``) followed by the bytes for this number of simple withdraws (``simpleWithdraws``). Each ``WithdrawCcdAmount`` is serialized as: the receiving address :ref:`CIS-2-Receiver` (``to``), the :ref:`CIS-5-CCDAmount` (``withdrawAmount``), and some additional data :ref:`CIS-2-AdditionalData` (``data``):: WithdrawCcdAmount ::= (to: Receiver) (withdrawAmount: CCDAmount) (data: AdditionalData) - WithdrawMessageCcdAmount ::= (entryPoint: EntrypointName) (expiryTime: TimeStamp) (nonce: u64) (serviceFeeRecipient: PublicKeyEd25519) (serviceFee: CCDAmount) (m: Byte²) (simpleWithdraws: WithdrawCcdAmountᵐ) + WithdrawMessageCcdAmount ::= (entryPoint: EntrypointName) (expiryTime: Timestamp) (nonce: Nonce) (serviceFeeRecipient: PublicKeyEd25519) (serviceFee: CCDAmount) (m: Byte²) (simpleWithdraws: WithdrawCcdAmountᵐ) WithdrawBatchCcdAmount ::= (signer: PublicKeyEd25519) (signature: SignatureEd25519) (message: WithdrawMessageCcdAmount) @@ -406,8 +411,7 @@ Requirements .. warning:: - Be aware of transferring CCDs to a non-existing account address or contract address. - This specification by itself does not include a standard that has to be followed. + Be aware of transferring CCDs to a non-existing account address or contract address which results in an error on Concordium. Checking the existence of an account address/ contract address would ideally be done off-chain before the message is even sent to the smart contract. .. _CIS-5-functions-withdrawCis2Tokens: @@ -427,13 +431,13 @@ It is serialized as: 2 bytes representing the number of withdrawals (``n``) foll Each ``WithdrawBatchTokenAmount`` is serialized as: a :ref:`CIS-5-PublicKeyEd25519` (``signer``), a :ref:`CIS-5-SignatureEd25519` (``signature``), and a ``WithdrawMessageTokenAmount`` (``message``). -Each ``WithdrawMessageTokenAmount`` is serialized as: an :ref:`CIS-5-EntrypointName` (``entryPoint``), a :ref:`CIS-5-TimeStamp` (``expiryTime``), a :ref:`CIS-5-Nonce` (``nonce``), a :ref:`CIS-5-PublicKeyEd25519` (``serviceFeeRecipient``), a :ref:`CIS-5-ExternalTokenAmount` (``serviceFee``), 2 bytes representing the number of simple withdraws (``m``) followed by the bytes for this number of simple withdraws (``simpleWithdraws``). +Each ``WithdrawMessageTokenAmount`` is serialized as: an :ref:`CIS-5-EntrypointName` (``entryPoint``), a :ref:`CIS-5-Timestamp` (``expiryTime``), a :ref:`CIS-5-Nonce` (``nonce``), a :ref:`CIS-5-PublicKeyEd25519` (``serviceFeeRecipient``), a :ref:`CIS-5-ExternalTokenAmount` (``serviceFee``), 2 bytes representing the number of simple withdraws (``m``) followed by the bytes for this number of simple withdraws (``simpleWithdraws``). Each ``WithdrawTokenAmount`` is serialized as: the receiving address :ref:`CIS-2-Receiver` (``to``), the :ref:`CIS-5-ExternalTokenAmount` (``withdrawAmount``), and some additional data :ref:`CIS-2-AdditionalData` (``data``):: WithdrawTokenAmount ::= (to: Receiver) (withdrawAmount: ExternalTokenAmount) (data: AdditionalData) - WithdrawMessageTokenAmount ::= (entryPoint: EntrypointName) (expiryTime: TimeStamp) (nonce: u64) (serviceFeeRecipient: PublicKeyEd25519) (serviceFee: ExternalTokenAmount) (m: Byte²) (simpleWithdraws: WithdrawTokenAmountᵐ) + WithdrawMessageTokenAmount ::= (entryPoint: EntrypointName) (expiryTime: Timestamp) (nonce: Nonce) (serviceFeeRecipient: PublicKeyEd25519) (serviceFee: ExternalTokenAmount) (m: Byte²) (simpleWithdraws: WithdrawTokenAmountᵐ) WithdrawBatchTokenAmount ::= (signer: PublicKeyEd25519) (signature: SignatureEd25519) (message: WithdrawMessageTokenAmount) @@ -475,13 +479,13 @@ It is serialized as: 2 bytes representing the number of transfers (``n``) follow Each ``TransferBatchCcdAmount`` is serialized as: a :ref:`CIS-5-PublicKeyEd25519` (``signer``), a :ref:`CIS-5-SignatureEd25519` (``signature``), and a ``TransferMessageCcdAmount`` (``message``). -Each ``TransferMessageCcdAmount`` is serialized as: an :ref:`CIS-5-EntrypointName` (``entryPoint``), a :ref:`CIS-5-TimeStamp` (``expiryTime``), a :ref:`CIS-5-Nonce` (``nonce``), a :ref:`CIS-5-PublicKeyEd25519` (``serviceFeeRecipient``), a :ref:`CIS-5-CCDAmount` (``serviceFee``), 2 bytes representing the number of simple transfers (``m``) followed by the bytes for this number of simple transers (``simpleTransfers``). +Each ``TransferMessageCcdAmount`` is serialized as: an :ref:`CIS-5-EntrypointName` (``entryPoint``), a :ref:`CIS-5-Timestamp` (``expiryTime``), a :ref:`CIS-5-Nonce` (``nonce``), a :ref:`CIS-5-PublicKeyEd25519` (``serviceFeeRecipient``), a :ref:`CIS-5-CCDAmount` (``serviceFee``), 2 bytes representing the number of simple transfers (``m``) followed by the bytes for this number of simple transers (``simpleTransfers``). Each ``TransferCcdAmount`` is serialized as: the receiving :ref:`CIS-5-PublicKeyEd25519` (``to``), and the :ref:`CIS-5-CCDAmount` (``transferAmount``):: TransferCcdAmount ::= (to: PublicKeyEd25519) (transferAmount: CCDAmount) - TransferMessageCcdAmount ::= (entryPoint: EntrypointName) (expiryTime: TimeStamp) (nonce: u64) (serviceFeeRecipient: PublicKeyEd25519) (serviceFee: CCDAmount) (m: Byte²) (simpleTransfers: TransferCcdAmountᵐ) + TransferMessageCcdAmount ::= (entryPoint: EntrypointName) (expiryTime: Timestamp) (nonce: Nonce) (serviceFeeRecipient: PublicKeyEd25519) (serviceFee: CCDAmount) (m: Byte²) (simpleTransfers: TransferCcdAmountᵐ) TransferBatchCcdAmount ::= (signer: PublicKeyEd25519) (signature: SignatureEd25519) (message: TransferMessageCcdAmount) @@ -520,13 +524,13 @@ It is serialized as: 2 bytes representing the number of transfers (``n``) follow Each ``TransferBatchTokenAmount`` is serialized as: a :ref:`CIS-5-PublicKeyEd25519` (``signer``), a :ref:`CIS-5-SignatureEd25519` (``signature``), and a ``TransferMessageTokenAmount`` (``message``). -Each ``TransferMessageTokenAmount`` is serialized as: an :ref:`CIS-5-EntrypointName` (``entryPoint``), a :ref:`CIS-5-TimeStamp` (``expiryTime``), a :ref:`CIS-5-Nonce` (``nonce``), a :ref:`CIS-5-PublicKeyEd25519` (``serviceFeeRecipient``), a :ref:`CIS-5-ExternalTokenAmount` (``serviceFee``), 2 bytes representing the number of simple transfers (``m``) followed by the bytes for this number of simple transfers (``simpleTransfers``). +Each ``TransferMessageTokenAmount`` is serialized as: an :ref:`CIS-5-EntrypointName` (``entryPoint``), a :ref:`CIS-5-Timestamp` (``expiryTime``), a :ref:`CIS-5-Nonce` (``nonce``), a :ref:`CIS-5-PublicKeyEd25519` (``serviceFeeRecipient``), a :ref:`CIS-5-ExternalTokenAmount` (``serviceFee``), 2 bytes representing the number of simple transfers (``m``) followed by the bytes for this number of simple transfers (``simpleTransfers``). Each ``TransferTokenAmount`` is serialized as: the receiving :ref:`CIS-5-PublicKeyEd25519` (``to``), the :ref:`CIS-5-ExternalTokenAmount` (``transferAmount``):: TransferTokenAmount ::= (to: PublicKeyEd25519) (transferAmount: ExternalTokenAmount) - TransferMessageTokenAmount ::= (entryPoint: EntrypointName) (expiryTime: TimeStamp) (nonce: u64) (serviceFeeRecipient: PublicKeyEd25519) (serviceFee: ExternalTokenAmount) (m: Byte²) (simpletransfers: TransferTokenAmountᵐ) + TransferMessageTokenAmount ::= (entryPoint: EntrypointName) (expiryTime: Timestamp) (nonce: Nonce) (serviceFeeRecipient: PublicKeyEd25519) (serviceFee: ExternalTokenAmount) (m: Byte²) (simpletransfers: TransferTokenAmountᵐ) TransferBatchTokenAmount ::= (signer: PublicKeyEd25519) (signature: SignatureEd25519) (message: TransferMessageTokenAmount) From d53271534d6e0b83ffc910af716570a74e4a6a0d Mon Sep 17 00:00:00 2001 From: Doris Benda Date: Thu, 23 May 2024 10:11:08 +0300 Subject: [PATCH 10/10] Update to use general bytes for the receive CCD hook function --- source/CIS/cis-5.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/CIS/cis-5.rst b/source/CIS/cis-5.rst index 0afa098..7907828 100644 --- a/source/CIS/cis-5.rst +++ b/source/CIS/cis-5.rst @@ -383,9 +383,9 @@ CCD Receive hook parameter The parameter for the CCD receive hook function contains some additional data bytes. -It is serialized as: some additional data :ref:`CIS-2-AdditionalData` (``data``):: +It is serialized as several bytes:: - CCDReceiveHookParameter ::= (data: AdditionalData) + CCDReceiveHookParameter ::= (data: Byteᵐ) Generating a valid signature ~~~~~~~~~~~~~~~~~~~~~~~~~~~~