在加密货币的几乎每个领域,支付都是一个反复出现的话题,特别是向多个质押者提供支付。例如,DAO希望为多个计划提供资金,DEX希望合并向某些参与者分配交易费用,或者团队希望将代币作为月薪分发给团队成员。智能合约使我们能够自动化这些类型的支付功能,这就限制了人工管理支付所导致的潜在错误,并允许我们将宝贵的时间花在其他生产性任务上。今天,我们将学习如何创建自己的ERC20代币支付拆分器,它可以合并到任何项目中!先决条件和设置
下面的内容要求你对Solidity有点熟悉,不过任何人都可以学习。项目架构
我们将创建两个合约。第一个将是ERC20代币支付拆分智能合约,第二个将是模拟池智能合约。ERC20代币支付拆分器智能合约将是抽象的,并持有用于管理收付方及其各自支付部分的逻辑和数据。模拟池将继承ERC20代币支付拆分器,以便我们可以自动将支付分发给多个质押者。在两个合约中拆分支付功能的原因有两个:展示在真实世界的用例中代币支付拆分合约的使用确保代币支付拆分合约足够灵活,任何人都可以选择并集成到自己的项目中OpenZeppelin已有一个名为PaymentSplitter
SafeERC20
paymentToken是我们用于支付的ERC20代币的地址。_totalShares提供来自所有收款人的份额相加。_totalTokenReleased是已支付给所有收款人的支付代币总额。_payees提供了当前所有收款人地址的数组。_shares是收款人地址与分配给他们的份额数量的映射。_tokenReleased是收款人地址到支付代币数量的映射。现在放置一个接受三个参数的构造函数。第一个参数是我们希望在合约部署中初始化的收款人的数组。第二个参数是每个收款人的份额数组。第三个是将用于支付的ERC20代币的地址。pragmasolidity0
paymentToken=_paymentToken;}构造函数包含一个require语句,以确保两个数组具有相同的长度,以便每个收款人都有分配给他们的份额。还有另一个require语句,以确保合约初始化与至少有一个收款人。还有一个for循环,它将每个收款人及其份额分配我们上面创建的变量。这是通过一个名为_addPayee的函数完成的,我们将很快创建这个函数。构造函数就绪后,再添加几个函数来调用和获取合约变量。pragmasolidity0
functionshares(addressaccount)publicviewreturns(uint256){return_shares;}functionpayee(uint256index)publicviewreturns(address){return_payees;}现在我们将创建用于添加收款人的函数。pragmasolidity0
_addPayee是我们在构造函数中调用的用于设置收款人数组的函数。这个函数有两个参数,收款人的帐户和与其相关的份额数量。然后它会检查账户是否为零地址,份额是否大于零,以及该账户是否已经注册为收款人。如果所有检查都通过,那么我们将数据添加到各自的变量中。现在让我们添加一个函数来支持将代币分发给收款人。pragmasolidity0
Release是一个任何人都可以调用的函数,它接受一个现有收款人帐户的参数。来分析一下这个函数中发生了什么。首先,它检查帐户是否有分配给它的份额。然后,它创建一个名为tokenTotalReceived的变量,该变量将合约的当前代币余额与之前释放的代币总数相加。创建另一个称为payment的变量,该变量确定收到的代币总额中有多少是欠账户的,然后减去多少已经释放到账户。然后,一个require语句检查当前支付金额是否大于零(即,当前是否欠下了更多代币)。如果该检查通过,则更新账户的tokenReleased,并更新totalTokenReleased。最后,支付给账户的代币金额被转账。现在函数已经就位了!但是这个合约还有一件事要做....事件!我们将在合约中添加两个事件,将事件添加到合约顶部是一个良好的实践。pragmasolidity0
functionrelease(addressaccount)publicvirtual{///existingFunctionCodeemitPaymentReleased(account,payment);}现在代币支付拆分合约已经建立!为了理解这在真实场景中是如何工作的,让我们创建一个模拟池合约,它将导入代币支付拆分器。创建模拟池合约
空白支票公司BMAC宣布清算并将赎回其IPO中发行的所有普通股:4月22日消息,Blockchain Moon Acquisition Corp.(BMAC)今天宣布,由于公司无法在其经修订和重述的公司注册证书所要求的期限内完成初始业务合并,因此打算根据其章程的规定解散和清算,并将赎回其IPO中发行的所有普通股。每股赎回价格约为10
}在这份合约中,导入三样东西。首先是OpenZeppelin的Ownable实用程序,它在某些函数上使用唯一的onlyOwner修饰符。第二个是SafeERC20,它允许安全的ERC20代币转账,正如将在合约中看到。第三个是我们的TokenPaymentSplitter合约。在MockPool构造函数中,我们需要TokenPaymentSplitter提供相同的三个参数,我们只是将它们传递给我们继承的合约。在这个合约中添加了另一个函数,drainTo。它实际上与TokenPaymentSplitter合约没有任何关系。它只是在另一个没有设置为支付代币的ERC20代币被发送到池时的一种安全机制,然后有一种方法让合约所有者释放该代币。测试合约
链上随机生成NFT项目Owls24小时交易额超500万美元:3月5日消息,据NFTGo.io数据显示,FreeMint的链上随机生成NFT项目Owls24小时交易额达503万美元,截止发稿该系列NFT地板价暂报0.37ETH。Owls总量9999枚,每枚Owls都是在Mint时使用伪随机种子在链上随机生成的。NFT Metadata本身也存储在链上,并在每次调用token URI()时动态构建为SVG。[2023/3/5 12:43:17]
测试智能合约与创建它们同样重要。这些合约处理的资产通常是属于其他人的,所以作为开发人员,我们有责任确保这些资产按照他们应该的方式工作,并且我们的测试可以覆盖几乎所有的边缘情况。将在这里进行的测试是一些示例,以显示TokenPaymentSplitter智能合约按照我们的预期工作。在处理自己的项目时,可能希望创建专门适合自己的用例的测试。为了支持我们的测试,我们希望包含一个ERC20代币,为此,我们将创建一个新的solididity文件,该文件导入OpenZepplinERC20模板以供我们的测试使用。在合约文件夹中,创建一个名为Imports.sol的新文件,并包括以下代码:pragmasolidity^0.8.0;import"现在,在test文件夹中创建一个名为test.js的文件。在这个文件的顶部,我们将导入支持我们的测试的包。const{expect}=require('chai')const{ethers}=require('hardhat')现在,为了设置测试,我们将首先创建必要的变量,创建beforeEach函数,该函数在每次测试之前调用,并创建一个空的describe函数,该函数将很快包含我们的测试。describe('TokenPaymentSplitterTests',()=>{letdeployerletaccount1letaccount2letaccount3letaccount4lettestPaymentTokenletmockPoolbeforeEach(async()=>{=awaitethers.getSigners()constTestPaymentToken=awaitethers.getContractFactory('ERC20PresetMinterPauser')testPaymentToken=awaitTestPaymentToken.deploy('TestPaymentToken','TPT')awaittestPaymentToken.deployed(。)describe('Addpayeeswithvaryingamountsanddistributepayments',async()=>{}}在这些部分就位后,让我们进入这些测试的核心部分!支付代币平均分配给多个收款人
在我们的第一个测试中,我们想看看当我们部署一个包含平均分配份额的收款人列表的合约时会发生什么。下面是测试代码。it('paymenttokenisdistributedevenlytomultiplepayees',async()=>{payeeAddressArray=payeeShareArray=constMockPool=awaitethers.getContractFactory('MockPool')mockPool=awaitMockPool.deploy(payeeAddressArray,payeeShareArray,testPaymentToken.address)awaitmockPool.deployed()awaittestPaymentToken.mint(mockPool.address,100000)awaitmockPool.connect(account1).release(account1.address)awaitmockPool.connect(account2).release(account2.address)awaitmockPool.connect(account3).release(account3.address)awaitmockPool.connect(account4).release(account4.address)constaccount1TokenBalance=awaittestPaymentToken.balanceOf(account1.address)constaccount2TokenBalance=awaittestPaymentToken.balanceOf(account2.address)constaccount3TokenBalance=awaittestPaymentToken.balanceOf(account3.address)constaccount4TokenBalance=awaittestPaymentToken.balanceOf(account4.address)expect(account1TokenBalance).to.equal(25000)expect(account2TokenBalance).to.equal(25000)expect(account3TokenBalance).to.equal(25000)expect(account4TokenBalance).to.equal(25000。)在这个测试中,我们将合约分配给4个收款人,每个人都有10个相同的份额。然后我们向合约发送100000单位的testPaymentToken,并向每个收款人发放付款。在测试中可以注意到,每个收款人都在调用函数来向自己释放代币。支付代币不均匀地分配给多个收款人
外媒:若DigitalBits交易失败,币安或成为国际米兰新的主要球衣赞助商:8月13日消息,据都灵媒体Tuttosport报道,鉴于与DigitalBits的协议存在巨大不确定性,币安或将成为国际米兰足球俱乐部未来的选择之一。
DigitalBits已经成为罗马体育俱乐部一年的球衣赞助商,至少在本赛季开始,他们将成为国米的主要球衣赞助商。在今晚与莱切的意甲揭幕战中,这家加密货币公司的标志将出现在国米球衣的正面。
然而,目前还不清楚双方的合作还能持续多久,因为该公司目前面临的严重财务问题已经导致他们推迟了对国米的首付款。
据报道,国米意识到,鉴于DigitalBits的不确定性,他们可能不得不寻找新的球衣赞助商,币安将是他们的选择之一。(Sempre Inter)[2022/8/13 12:23:39]
在第二个测试中,我们希望确保即使每个收款人的份额分配不均,数学计算仍然有效。it('paymenttokenisdistributedunevenlytomultiplepayees',async()=>{payeeAddressArray=payeeShareArray=constMockPool=awaitethers.getContractFactory('MockPool')mockPool=awaitMockPool.deploy(payeeAddressArray,payeeShareArray,testPaymentToken.address)awaitmockPool.deployed()awaittestPaymentToken.mint(mockPool.address,100000)awaitmockPool.connect(account1).release(account1.address)awaitmockPool.connect(account2).release(account2.address)awaitmockPool.connect(account3).release(account3.address)awaitmockPool.connect(account4).release(account4.address)constmockPoolTestPaymentTokenBalance=awaittestPaymentToken.balanceOf(mockPool.address)constaccount1TokenBalance=awaittestPaymentToken.balanceOf(account1.address)constaccount2TokenBalance=awaittestPaymentToken.balanceOf(account2.address)constaccount3TokenBalance=awaittestPaymentToken.balanceOf(account3.address)constaccount4TokenBalance=awaittestPaymentToken.balanceOf(account4.address)expect(mockPoolTestPaymentTokenBalance).to.equal(1)expect(account1TokenBalance).to.equal(30303)expect(account2TokenBalance).to.equal(15151)expect(account3TokenBalance).to.equal(33333)expect(account4TokenBalance).to.equal(21212。)看起来收款人还能拿到钱,但注意到什么了吗?合约中还剩下一个单位的支付代币!由于Solidity没有小数,当它达到最低单位时,它通常会四舍五入,这可能会导致合约尘埃飞扬,就像我们在这里看到的。不过不用担心,因为我们预计未来会有支付代币流入合约,所以它将继续分发。支付代币不均匀地分配给多个收款人,并将额外的支付代币发送到池中
STEPN :在APE REALM强化Sneaker将有50%几率强化成为创世Sneaker:8月6日消息,STEPN公布APE REALM中的创世Sneaker获取规则: 8月6日20:00到8月13日20:00在APE REALM进行Sneaker强化,将有50%几率使强化后的Sneaker变成创世Sneaker(APE Genesis Sneaker)。
创世Sneaker强化上限200双,奖励将立刻生效,同时Genesis Sneaker ID将从未使用的Genesis ID编号(G1 - 20,000 之间)随机抽取。此外,一旦生成200个创世Sneaker后,活动将提前结束。[2022/8/6 12:06:31]
这与之前的测试类似,不过在资金被释放给收款人之间增加了更多支付代币发送到池中。这表明,随着支付代币不断流入模拟池合约,数学仍然可以确保收款人收到正确的金额。it('paymenttokenisdistributedunevenlytomultiplepayeeswithadditionalpaymenttokensenttopool',async()=>{payeeAddressArray=payeeShareArray=constMockPool=awaitethers.getContractFactory('MockPool')mockPool=awaitMockPool.deploy(payeeAddressArray,payeeShareArray,testPaymentToken.address)awaitmockPool.deployed()awaittestPaymentToken.mint(mockPool.address,100000)awaitmockPool.connect(account1).release(account1.address)awaitmockPool.connect(account2).release(account2.address)awaittestPaymentToken.mint(mockPool.address,100000)awaitmockPool.connect(account3).release(account3.address)awaitmockPool.connect(account4).release(account4.address)awaitmockPool.connect(account1).release(account1.address)awaitmockPool.connect(account2).release(account2.address)constmockPoolTestPaymentTokenBalance=awaittestPaymentToken.balanceOf(mockPool.address)constaccount1TokenBalance=awaittestPaymentToken.balanceOf(account1.address)constaccount2TokenBalance=awaittestPaymentToken.balanceOf(account2.address)constaccount3TokenBalance=awaittestPaymentToken.balanceOf(account3.address)constaccount4TokenBalance=awaittestPaymentToken.balanceOf(account4.address)expect(mockPoolTestPaymentTokenBalance).to.equal(1)expect(account1TokenBalance).to.equal(60606)expect(account2TokenBalance).to.equal(30303)expect(account3TokenBalance).to.equal(66666)expect(account4TokenBalance).to.equal(42424。)现在所有的测试都就绪了,是时候运行它们了,看看它们是否工作!在项目根文件夹中,使用npxhardhattest启动测试。如果一切都是正确的,那么你应该看到如下图所示的所有绿色格子。
如上所述,我们需要做更多的测试,以确保整个项目/协议按照预期工作,支付拆分器是它的集成部分。这将意味着更多的单元测试来覆盖所有可用的功能,以及更复杂的集成测试,这取决于具体用例。总结
支付是许多加密协议的一个常见方面,有几种方法可以解决它们。今天我们学习了一种管理支付的方法,尽管用户甚至可以在此合约的基础上构建以满足您的特定需求,如跨多个代币启用支付,添加额外的收款人或移除收款人,或在一个函数调用中同时分发所有支付。Source:https://medium.com/coinmonks/create-an-erc20-token-payment-splitting-smart-contract-c79436470ccc本文来自去中心化金融社区,星球日报经授权转载。
标签:TOKTOKEKENTOKENimtoken官方最新版greathealthtokenimtoken为何被别人转走Keys Token
头条 a16z高管计划本周与美国国会及白宫官员会面,以推动Web3相关立法a16z高管计划本周与美国国会及白宫官员会面讨论Web3的监管问题.
1900/1/1 0:00:008月11日,我们看到了有史以来最大的一次加密货币黑客攻击。PolyNetwork的6.11亿美元被盗。被黑客攻击的数量巨大,并不是此次黑客攻击的唯一特点.
1900/1/1 0:00:00撰文:AndrewThurman编辑:南风DAOs的去中心化属性及其对对充满活力的、忠诚的社区的依赖,可能会让那些只为利益而来的投资者失望。越来越多的以太坊爱好者相信,DAOs(去中心化自治组织)可能是工作、文化社区和人类组织的未来.
1900/1/1 0:00:00经Odaily星球日报不完全统计,9月6日-9月12日当周公布的海内外区块链融资事件共27起,和一周前持平;已披露融资总额约2亿美元,较上周呈下降趋势.
1900/1/1 0:00:00作者:SpencerApplebaum这篇文章是《Layers1和Layer2的价值捕获》的续作。它也建立在《分叉DeFi协议》的一些想法之上。在这些文章中,我们探讨了Layer1和我们当时称为Layer2代币的潜在价值捕获机制.
1900/1/1 0:00:00图片来源:网络作者:AmyLiu据CNBC报道,知情人士透露,GrayscaleInvestments计划在本周初提交申请,将全球最大的比特币基金转换为现货ETF.
1900/1/1 0:00:00