language/diem-framework/releases/artifacts/release-1.4.0-rc0/docs/modules/PaymentScripts.md
<a name="0x1_PaymentScripts"></a>
0x1::PaymentScriptsThis module holds all payment related script entrypoints in the Diem Framework. Any account that can hold a balance can use the transaction scripts within this module.
<pre><code><b>use</b> <a href="DiemAccount.md#0x1_DiemAccount">0x1::DiemAccount</a>; </code></pre><a name="0x1_PaymentScripts_peer_to_peer_with_metadata"></a>
peer_to_peer_with_metadata<a name="@Summary_0"></a>
Transfers a given number of coins in a specified currency from one account to another. Transfers over a specified amount defined on-chain that are between two different VASPs, or other accounts that have opted-in will be subject to on-chain checks to ensure the receiver has agreed to receive the coins. This transaction can be sent by any account that can hold a balance, and to any account that can hold a balance. Both accounts must hold balances in the currency being transacted.
<a name="@Technical_Description_1"></a>
Transfers <code>amount</code> coins of type <code>Currency</code> from <code>payer</code> to <code>payee</code> with (optional) associated <code>metadata</code> and an (optional) <code>metadata_signature</code> on the message of the form <code>metadata</code> | <code><a href="../../../../../../move-stdlib/docs/Signer.md#0x1_Signer_address_of">Signer::address_of</a>(payer)</code> | <code>amount</code> | <code><a href="DualAttestation.md#0x1_DualAttestation_DOMAIN_SEPARATOR">DualAttestation::DOMAIN_SEPARATOR</a></code>, that has been signed by the <code>payee</code>'s private key associated with the <code>compliance_public_key</code> held in the <code>payee</code>'s <code><a href="DualAttestation.md#0x1_DualAttestation_Credential">DualAttestation::Credential</a></code>. Both the <code><a href="../../../../../../move-stdlib/docs/Signer.md#0x1_Signer_address_of">Signer::address_of</a>(payer)</code> and <code>amount</code> fields in the <code>metadata_signature</code> must be BCS-encoded bytes, and <code>|</code> denotes concatenation. The <code>metadata</code> and <code>metadata_signature</code> parameters are only required if <code>amount</code> >= <code><a href="DualAttestation.md#0x1_DualAttestation_get_cur_microdiem_limit">DualAttestation::get_cur_microdiem_limit</a></code> XDX and <code>payer</code> and <code>payee</code> are distinct VASPs. However, a transaction sender can opt in to dual attestation even when it is not required (e.g., a DesignatedDealer -> VASP payment) by providing a non-empty <code>metadata_signature</code>. Standardized <code>metadata</code> BCS format can be found in <code>diem_types::transaction::metadata::Metadata</code>.
<a name="@Events_2"></a>
Successful execution of this script emits two events:
<a name="@Parameters_3"></a>
| Name | Type | Description |
|---|---|---|
| <code>Currency</code> | Type | The Move type for the <code>Currency</code> being sent in this transaction. <code>Currency</code> must be an already-registered currency on-chain. |
| <code>payer</code> | <code>signer</code> | The signer of the sending account that coins are being transferred from. |
| <code>payee</code> | <code>address</code> | The address of the account the coins are being transferred to. |
| <code>metadata</code> | <code>vector<u8></code> | Optional metadata about this payment. |
| <code>metadata_signature</code> | <code>vector<u8></code> | Optional signature over <code>metadata</code> and payment information. See |
<a name="@Common_Abort_Conditions_4"></a>
| Error Category | Error Reason | Description |
|---|---|---|
| <code><a href="../../../../../../move-stdlib/docs/Errors.md#0x1_Errors_NOT_PUBLISHED">Errors::NOT_PUBLISHED</a></code> | <code><a href="DiemAccount.md#0x1_DiemAccount_EPAYER_DOESNT_HOLD_CURRENCY">DiemAccount::EPAYER_DOESNT_HOLD_CURRENCY</a></code> | <code>payer</code> doesn't hold a balance in <code>Currency</code>. |
| <code><a href="../../../../../../move-stdlib/docs/Errors.md#0x1_Errors_LIMIT_EXCEEDED">Errors::LIMIT_EXCEEDED</a></code> | <code><a href="DiemAccount.md#0x1_DiemAccount_EINSUFFICIENT_BALANCE">DiemAccount::EINSUFFICIENT_BALANCE</a></code> | <code>amount</code> is greater than <code>payer</code>'s balance in <code>Currency</code>. |
| <code><a href="../../../../../../move-stdlib/docs/Errors.md#0x1_Errors_INVALID_ARGUMENT">Errors::INVALID_ARGUMENT</a></code> | <code><a href="DiemAccount.md#0x1_DiemAccount_ECOIN_DEPOSIT_IS_ZERO">DiemAccount::ECOIN_DEPOSIT_IS_ZERO</a></code> | <code>amount</code> is zero. |
| <code><a href="../../../../../../move-stdlib/docs/Errors.md#0x1_Errors_NOT_PUBLISHED">Errors::NOT_PUBLISHED</a></code> | <code><a href="DiemAccount.md#0x1_DiemAccount_EPAYEE_DOES_NOT_EXIST">DiemAccount::EPAYEE_DOES_NOT_EXIST</a></code> | No account exists at the <code>payee</code> address. |
| <code><a href="../../../../../../move-stdlib/docs/Errors.md#0x1_Errors_INVALID_ARGUMENT">Errors::INVALID_ARGUMENT</a></code> | <code><a href="DiemAccount.md#0x1_DiemAccount_EPAYEE_CANT_ACCEPT_CURRENCY_TYPE">DiemAccount::EPAYEE_CANT_ACCEPT_CURRENCY_TYPE</a></code> | An account exists at <code>payee</code>, but it does not accept payments in <code>Currency</code>. |
| <code><a href="../../../../../../move-stdlib/docs/Errors.md#0x1_Errors_INVALID_STATE">Errors::INVALID_STATE</a></code> | <code><a href="AccountFreezing.md#0x1_AccountFreezing_EACCOUNT_FROZEN">AccountFreezing::EACCOUNT_FROZEN</a></code> | The <code>payee</code> account is frozen. |
| <code><a href="../../../../../../move-stdlib/docs/Errors.md#0x1_Errors_INVALID_ARGUMENT">Errors::INVALID_ARGUMENT</a></code> | <code><a href="DualAttestation.md#0x1_DualAttestation_EMALFORMED_METADATA_SIGNATURE">DualAttestation::EMALFORMED_METADATA_SIGNATURE</a></code> | <code>metadata_signature</code> is not 64 bytes. |
| <code><a href="../../../../../../move-stdlib/docs/Errors.md#0x1_Errors_INVALID_ARGUMENT">Errors::INVALID_ARGUMENT</a></code> | <code><a href="DualAttestation.md#0x1_DualAttestation_EINVALID_METADATA_SIGNATURE">DualAttestation::EINVALID_METADATA_SIGNATURE</a></code> | <code>metadata_signature</code> does not verify on the against the <code>payee'</code>s <code><a href="DualAttestation.md#0x1_DualAttestation_Credential">DualAttestation::Credential</a></code> <code>compliance_public_key</code> public key. |
| <code><a href="../../../../../../move-stdlib/docs/Errors.md#0x1_Errors_LIMIT_EXCEEDED">Errors::LIMIT_EXCEEDED</a></code> | <code><a href="DiemAccount.md#0x1_DiemAccount_EWITHDRAWAL_EXCEEDS_LIMITS">DiemAccount::EWITHDRAWAL_EXCEEDS_LIMITS</a></code> | <code>payer</code> has exceeded its daily withdrawal limits for the backing coins of XDX. |
| <code><a href="../../../../../../move-stdlib/docs/Errors.md#0x1_Errors_LIMIT_EXCEEDED">Errors::LIMIT_EXCEEDED</a></code> | <code><a href="DiemAccount.md#0x1_DiemAccount_EDEPOSIT_EXCEEDS_LIMITS">DiemAccount::EDEPOSIT_EXCEEDS_LIMITS</a></code> | <code>payee</code> has exceeded its daily deposit limits for XDX. |
<a name="@Related_Scripts_5"></a>
<a name="0x1_PaymentScripts_peer_to_peer_by_signers"></a>
peer_to_peer_by_signers<a name="@Summary_6"></a>
Transfers a given number of coins in a specified currency from one account to another by multi-agent transaction. Transfers over a specified amount defined on-chain that are between two different VASPs, or other accounts that have opted-in will be subject to on-chain checks to ensure the receiver has agreed to receive the coins. This transaction can be sent by any account that can hold a balance, and to any account that can hold a balance. Both accounts must hold balances in the currency being transacted.
<a name="@Technical_Description_7"></a>
Transfers <code>amount</code> coins of type <code>Currency</code> from <code>payer</code> to <code>payee</code> with (optional) associated <code>metadata</code>. Dual attestation is not applied to this script as payee is also a signer of the transaction. Standardized <code>metadata</code> BCS format can be found in <code>diem_types::transaction::metadata::Metadata</code>.
<a name="@Events_8"></a>
Successful execution of this script emits two events:
<a name="@Parameters_9"></a>
| Name | Type | Description |
|---|---|---|
| <code>Currency</code> | Type | The Move type for the <code>Currency</code> being sent in this transaction. <code>Currency</code> must be an already-registered currency on-chain. |
| <code>payer</code> | <code>signer</code> | The signer of the sending account that coins are being transferred from. |
| <code>payee</code> | <code>signer</code> | The signer of the receiving account that the coins are being transferred to. |
| <code>metadata</code> | <code>vector<u8></code> | Optional metadata about this payment. |
<a name="@Common_Abort_Conditions_10"></a>
| Error Category | Error Reason | Description |
|---|---|---|
| <code><a href="../../../../../../move-stdlib/docs/Errors.md#0x1_Errors_NOT_PUBLISHED">Errors::NOT_PUBLISHED</a></code> | <code><a href="DiemAccount.md#0x1_DiemAccount_EPAYER_DOESNT_HOLD_CURRENCY">DiemAccount::EPAYER_DOESNT_HOLD_CURRENCY</a></code> | <code>payer</code> doesn't hold a balance in <code>Currency</code>. |
| <code><a href="../../../../../../move-stdlib/docs/Errors.md#0x1_Errors_LIMIT_EXCEEDED">Errors::LIMIT_EXCEEDED</a></code> | <code><a href="DiemAccount.md#0x1_DiemAccount_EINSUFFICIENT_BALANCE">DiemAccount::EINSUFFICIENT_BALANCE</a></code> | <code>amount</code> is greater than <code>payer</code>'s balance in <code>Currency</code>. |
| <code><a href="../../../../../../move-stdlib/docs/Errors.md#0x1_Errors_INVALID_ARGUMENT">Errors::INVALID_ARGUMENT</a></code> | <code><a href="DiemAccount.md#0x1_DiemAccount_ECOIN_DEPOSIT_IS_ZERO">DiemAccount::ECOIN_DEPOSIT_IS_ZERO</a></code> | <code>amount</code> is zero. |
| <code><a href="../../../../../../move-stdlib/docs/Errors.md#0x1_Errors_NOT_PUBLISHED">Errors::NOT_PUBLISHED</a></code> | <code><a href="DiemAccount.md#0x1_DiemAccount_EPAYEE_DOES_NOT_EXIST">DiemAccount::EPAYEE_DOES_NOT_EXIST</a></code> | No account exists at the <code>payee</code> address. |
| <code><a href="../../../../../../move-stdlib/docs/Errors.md#0x1_Errors_INVALID_ARGUMENT">Errors::INVALID_ARGUMENT</a></code> | <code><a href="DiemAccount.md#0x1_DiemAccount_EPAYEE_CANT_ACCEPT_CURRENCY_TYPE">DiemAccount::EPAYEE_CANT_ACCEPT_CURRENCY_TYPE</a></code> | An account exists at <code>payee</code>, but it does not accept payments in <code>Currency</code>. |
| <code><a href="../../../../../../move-stdlib/docs/Errors.md#0x1_Errors_INVALID_STATE">Errors::INVALID_STATE</a></code> | <code><a href="AccountFreezing.md#0x1_AccountFreezing_EACCOUNT_FROZEN">AccountFreezing::EACCOUNT_FROZEN</a></code> | The <code>payee</code> account is frozen. |
| <code><a href="../../../../../../move-stdlib/docs/Errors.md#0x1_Errors_LIMIT_EXCEEDED">Errors::LIMIT_EXCEEDED</a></code> | <code><a href="DiemAccount.md#0x1_DiemAccount_EWITHDRAWAL_EXCEEDS_LIMITS">DiemAccount::EWITHDRAWAL_EXCEEDS_LIMITS</a></code> | <code>payer</code> has exceeded its daily withdrawal limits for the backing coins of XDX. |
| <code><a href="../../../../../../move-stdlib/docs/Errors.md#0x1_Errors_LIMIT_EXCEEDED">Errors::LIMIT_EXCEEDED</a></code> | <code><a href="DiemAccount.md#0x1_DiemAccount_EDEPOSIT_EXCEEDS_LIMITS">DiemAccount::EDEPOSIT_EXCEEDS_LIMITS</a></code> | <code>payee</code> has exceeded its daily deposit limits for XDX. |
<a name="@Related_Scripts_11"></a>
<a name="0x1_PaymentScripts_PeerToPeer"></a>
<pre><code><b>schema</b> <a href="PaymentScripts.md#0x1_PaymentScripts_PeerToPeer">PeerToPeer</a><Currency> { payer: signer; payee: address; amount: u64; metadata: vector<u8>; <b>include</b> <a href="DiemAccount.md#0x1_DiemAccount_TransactionChecks">DiemAccount::TransactionChecks</a>{sender: payer}; <b>let</b> payer_addr = <a href="../../../../../../move-stdlib/docs/Signer.md#0x1_Signer_spec_address_of">Signer::spec_address_of</a>(payer); <b>let</b> cap = <a href="DiemAccount.md#0x1_DiemAccount_spec_get_withdraw_cap">DiemAccount::spec_get_withdraw_cap</a>(payer_addr); <b>include</b> <a href="DiemAccount.md#0x1_DiemAccount_ExtractWithdrawCapAbortsIf">DiemAccount::ExtractWithdrawCapAbortsIf</a>{sender_addr: payer_addr}; <b>include</b> <a href="DiemAccount.md#0x1_DiemAccount_PayFromAbortsIf">DiemAccount::PayFromAbortsIf</a><Currency>{cap: cap}; } </code></pre>The balances of payer and payee change by the correct amount.
<pre><code><b>schema</b> <a href="PaymentScripts.md#0x1_PaymentScripts_PeerToPeer">PeerToPeer</a><Currency> { <b>ensures</b> payer_addr != payee ==> <a href="DiemAccount.md#0x1_DiemAccount_balance">DiemAccount::balance</a><Currency>(payer_addr) == <b>old</b>(<a href="DiemAccount.md#0x1_DiemAccount_balance">DiemAccount::balance</a><Currency>(payer_addr)) - amount; <b>ensures</b> payer_addr != payee ==> <a href="DiemAccount.md#0x1_DiemAccount_balance">DiemAccount::balance</a><Currency>(payee) == <b>old</b>(<a href="DiemAccount.md#0x1_DiemAccount_balance">DiemAccount::balance</a><Currency>(payee)) + amount; <b>ensures</b> payer_addr == payee ==> <a href="DiemAccount.md#0x1_DiemAccount_balance">DiemAccount::balance</a><Currency>(payee) == <b>old</b>(<a href="DiemAccount.md#0x1_DiemAccount_balance">DiemAccount::balance</a><Currency>(payee)); <b>aborts_with</b> [check] <a href="../../../../../../move-stdlib/docs/Errors.md#0x1_Errors_NOT_PUBLISHED">Errors::NOT_PUBLISHED</a>, <a href="../../../../../../move-stdlib/docs/Errors.md#0x1_Errors_INVALID_STATE">Errors::INVALID_STATE</a>, <a href="../../../../../../move-stdlib/docs/Errors.md#0x1_Errors_INVALID_ARGUMENT">Errors::INVALID_ARGUMENT</a>, <a href="../../../../../../move-stdlib/docs/Errors.md#0x1_Errors_LIMIT_EXCEEDED">Errors::LIMIT_EXCEEDED</a>; <b>include</b> <a href="DiemAccount.md#0x1_DiemAccount_PayFromEmits">DiemAccount::PayFromEmits</a><Currency>{cap: cap}; } </code></pre>Access Control: Both the payer and the payee must hold the balances of the Currency. Only Designated Dealers, Parent VASPs, and Child VASPs can hold balances [D1][D2][D3][D4][D5][D6][D7].
<pre><code><b>schema</b> <a href="PaymentScripts.md#0x1_PaymentScripts_PeerToPeer">PeerToPeer</a><Currency> { <b>aborts_if</b> !<b>exists</b><<a href="DiemAccount.md#0x1_DiemAccount_Balance">DiemAccount::Balance</a><Currency>>(payer_addr) <b>with</b> <a href="../../../../../../move-stdlib/docs/Errors.md#0x1_Errors_NOT_PUBLISHED">Errors::NOT_PUBLISHED</a>; <b>aborts_if</b> !<b>exists</b><<a href="DiemAccount.md#0x1_DiemAccount_Balance">DiemAccount::Balance</a><Currency>>(payee) <b>with</b> <a href="../../../../../../move-stdlib/docs/Errors.md#0x1_Errors_INVALID_ARGUMENT">Errors::INVALID_ARGUMENT</a>; } </code></pre> </details>