支付 - OpenZeppelin 文档

本文档介绍了OpenZeppelin Contracts库中与支付相关的实用工具,包括PaymentSplitter,用于将以太币支付分配给多个账户,以及PullPayment,它实现了一种安全的资金发送方式,接收者需要主动提取资金。此外,还介绍了Escrow合约,用于在满足条件前持有资金。

你当前阅读的不是此文档的最新版本。5.x 是最新版本。

支付

|---|---| | | 建议在 https://docs.openzeppelin.com/contracts/api/payment 查看此文档 |

与发送和接收付款相关的实用程序。示例包括 PullPayment,它在向第三方发送资金时实现了最佳的安全实践,以及 PaymentSplitter 用于接收多个受益人之间的传入付款。

|---|---| | | 当与不受信任的第三方之间转移资金时,始终存在重入的安全风险。如果你想了解更多关于此的信息以及保护免受其侵害的方法,请查看我们的博客文章 伊斯坦布尔之后的重入。 |

实用工具

PaymentSplitter

此合约允许在一组帐户之间分配以太币付款。发送者无需知道 以太币将以这种方式分配,因为它由合约透明地处理。

分配可以是等份,也可以是任何其他任意比例。指定此方式的方法是将每个 帐户分配给一定数量的份额。在此合约收到的所有以太币中,每个帐户都能够提取 与其分配的总份额百分比成比例的金额。

PaymentSplitter 遵循提取付款模型。这意味着付款不会自动转发到 帐户,而是保留在此合约中,并且通过调用 release 来触发实际转移。 函数。

函数

事件

constructor(address[] payees, uint256[] shares_) public

创建 PaymentSplitter 的实例,其中 payees 中的每个帐户都分配了 shares 数组中匹配位置的份额数量。

payees 中的所有地址都必须为非零。两个数组必须具有相同的非零长度,并且 payees 中不得有重复项。

receive() external

收到的以太币将使用 PaymentReceived 事件记录。请注意,这些事件并非完全 可靠:合约有可能在不触发此函数的情况下收到以太币。这只会影响 事件的可靠性,而不是以太币的实际分配。

要了解更多关于此的信息,请参阅 Solidity 文档中的 回退\ 函数

totalShares() → uint256 public

获取收款人持有的总份额。

totalReleased() → uint256 public

获取已释放的以太币总额。

shares(address account) → uint256 public

获取帐户持有的份额数量。

released(address account) → uint256 public

获取已释放给收款人的以太币数量。

payee(uint256 index) → address public

获取收款人编号 index 的地址。

release(address payable account) public

根据 account 的股份总额百分比及其之前的提取,触发向 account 转移欠其的以太币金额。

PayeeAdded(address account, uint256 shares) event
PaymentReleased(address to, uint256 amount) event
PaymentReceived(address from, uint256 amount) event

PullPayment

提取付款 策略的简单实现,其中付款合约不直接与 收款人帐户交互,收款人帐户必须自行提取其付款。

在安全方面,提取付款通常被认为是发送 以太币的最佳实践。它可以防止收款人阻止执行,并消除重入问题。

|---|---| | | 如果你想了解更多关于重入以及替代方法的信息<br>保护免受其侵害,请查看我们的博客文章<br>伊斯坦布尔之后的重入。 |

要使用,请从 PullPayment 合约派生,并使用 _asyncTransfer 而不是 Solidity 的 transfer 函数。收款人可以使用 payments 查询其应付款项,并使用 withdrawPayments 检索它们。

函数

constructor() internal
withdrawPayments(address payable payee) public

提取累积的付款,将所有 gas 转发给收款人。

请注意,任何帐户都可以调用此函数,而不仅仅是 payee。 这意味着不了解 PullPayment 协议的合约仍然可以 通过让一个单独的帐户调用 withdrawPayments 来接收资金。

|---|---| | | 转发所有 gas 会打开重入漏洞的大门。<br>确保你信任收款人,或者<br>要么遵循检查-效果-交互模式,要么使用 ReentrancyGuard。 |

payments(address dest) → uint256 public

返回欠某个地址的付款。

_asyncTransfer(address dest, uint256 amount) internal

由付款人调用以存储发送的金额作为要提取的信用额度。 以这种方式发送的资金存储在中间的 Escrow 合约中,因此 没有在提取之前花费它们的危险。

托管

Escrow

基本托管合约,持有指定给收款人的资金,直到他们 提取它们。

预期用法:此合约(以及派生的托管合约)应该是一个 独立的合约,仅与实例化它的合约交互。 这样,可以保证所有以太币都将按照 Escrow 规则处理,并且无需检查继承树中的 payable 函数或 转移。使用托管作为其 付款方法的合约应该是其所有者,并提供重定向到 托管的存款和提取的公共方法。

函数

可拥有

事件

可拥有

depositsOf(address payee) → uint256 public
deposit(address payee) public

存储发送的金额作为要提取的信用额度。

withdraw(address payable payee) public

提取收款人的累积余额,将所有 gas 转发给 收款人。

|---|---| | | 转发所有 gas 会打开重入漏洞的大门。<br>确保你信任收款人,或者<br>要么遵循检查-效果-交互模式,要么使用 ReentrancyGuard。 |

Deposited(address payee, uint256 weiAmount) event
Withdrawn(address payee, uint256 weiAmount) event

ConditionalEscrow

仅当满足条件时才允许提取的基础抽象托管。 预期用法:请参阅 Escrow。此处适用相同的使用指南。

函数

托管

可拥有

事件

托管

可拥有

withdrawalAllowed(address payee) → bool public

返回是否允许某个地址提取其资金。要由派生合约实现。

withdraw(address payable payee) public

RefundEscrow

为受益人持有资金,由多个 各方存入的托管。 预期用法:请参阅 Escrow。此处适用相同的使用指南。 所有者帐户(即实例化此 合约的合约)可能会存入资金,关闭存款期,并允许 受益人提取或退款给存款人。与 RefundEscrow 的所有交互 都将通过所有者合约进行。

函数

ConditionalEscrow

托管

可拥有

事件

托管

可拥有

constructor(address payable beneficiary_) public

构造函数。

state() → enum RefundEscrow.State public
beneficiary() → address payable public
deposit(address refundee) public

存储以后可能被退还的资金。

close() public

允许受益人提取其资金,拒绝 进一步的存款。

enableRefunds() public

允许进行退款,拒绝 进一步的存款。

beneficiaryWithdraw() public

提取受益人的资金。

withdrawalAllowed(address) → bool public

返回是否允许退款人提取其存款(获得退款)。重写后的函数接收一个 “payee”参数,但我们在此处忽略它,因为该条件是全局的,而不是每个收款人的。

RefundsClosed() event
RefundsEnabled() event

← 数学

预设 →

  • 原文链接: docs.openzeppelin.com/co...
  • 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
OpenZeppelin
OpenZeppelin
江湖只有他的大名,没有他的介绍。