swift airdrop_我如何构建多令牌Airdrop Central来分发ERC20令牌

swift airdrop

by Pablo Ruiz

帕勃罗·鲁伊斯(Pablo Ruiz)

我如何构建多令牌Airdrop Central来分发ERC20令牌 (How I built a multi-token Airdrop Central to distribute ERC20 tokens)

Every now and then, while browsing questions on Ethereum Stack Exchange — the go-to site for questions related to Solidity development, and for me, the go-to place to contribute to the dev community — I see the following question:

时不时地 ,在以太坊Stack Exchange上浏览问题时-有关Solidity开发的问题的访问站点,而对我来说,这是为开发人员社区做出贡献的去处-我看到以下问题:

“How to do an airdrop of my tokens.”

“如何对我的代币进行空投 。”

In the context of a Token Sale campaign, an Airdrop refers to sending tokens to multiple accounts for free. This is a trend that has recently become popular to promote upcoming ICOs / Token Crowdsales.

在代币销售活动中,空投是指免费向多个帐户发送代币。 这种趋势最近变得越来越流行,以促进即将到来的ICO /代币众筹。

Some of these airdrops are done as a time and/or volume based campaign, where people are told that if they own some amount of tokens by some date, they will receive more tokens.

这些空投中的一些是作为基于时间和/或数量的运动来完成的,人们被告知如果他们在某个日期之前拥有一定数量的代币,他们将获得更多的代币。

Some other airdrops are even done in an unsolicited manner. Teams will just send tokens to random accounts from a list. If you were on that list and you happen to check your balance for that token, you will see them.

其他一些空投甚至是以未经请求的方式完成的。 团队只会将令牌从列表发送到随机帐户。 如果您在该列表中,并且碰巧检查了该令牌的余额,则会看到它们。

There are also a few sites that allow users to subscribe to find out how to willingly participate in these airdrops. They will typically ask you to subscribe to some mailing list or give you referral links to participate in token sales.

也有一些站点允许用户订阅以了解如何自愿参加这些空投。 他们通常会要求您订阅一些邮件列表或给您推荐链接以参与令牌销售。

令牌空投通常是如何完成的 (How Token Airdrops are Typically Done)

There are a few ways these token airdrops are handled by teams.

团队可以使用几种方式来处理这些令牌空投。

  • Some of them do it manually. They just build a list on an spreadsheet, and then proceed to manually transfer the tokens to each account.

    其中一些是手动执行的。 他们只是在电子表格上建立一个列表,然后继续将令牌手动转移到每个帐户。
  • Others build a very simple smart contract, which receives an array of addresses, and proceeds to transfer some amount of tokens to each of those address.

    其他人则建立了一个非常简单的智能合约,该合约接收地址数组,然后继续将一定数量的令牌转移到这些地址中的每一个。
  • Others also use a smart contract to allow people to proactively withdraw tokens they have been assigned beforehand.

    其他人还使用智能合约,使人们可以主动提取预先分配的令牌。

I haven’t yet seen a solution that allows people to just sign up and then receive any tokens sent by multiple teams.

我还没有看到一种允许人们注册然后接收多个团队发送的令牌的解决方案

令牌空投中央 (The Token Airdrop Central)

In this article, I’m going to describe how I built a smart contract that works as a central for airdrops. Basically, people can subscribe to this airdrop central, and from then on, when a team performs an airdrop to the central, the subscribed users can withdraw their share of the airdrop for free.

在本文中,我将描述如何建立一个智能合约来充当空投中心。 基本上,人们可以订阅此空投中心,然后,当团队对中心进行空投时,订阅的用户可以免费撤回其空投份额。

On the other hand, teams doing airdrops can just send the tokens to this central which will get evenly distributed to all users subscribed at that time.The Airdrop Central keeps 2% of those tokens as a fee for the service.

另一方面,进行空投的团队可以将令牌发送到该中心,该令牌将平均分配给当时订阅的所有用户。空投中心保留这些令牌的2%作为服务费。

Its important to notice that this Airdrop Central allows any teams to drop their tokens for the existing community to withdraw. The list of users is shared among all teams. So the more people each team reaches out to individually, the more people that will benefit from tokens airdropped by other teams.

重要的是要注意,该Airdrop Central允许任何团队丢弃其令牌以供现有社区撤回。 用户列表在所有团队之间共享。 因此,每个团队与个人接触的人越多,将从其他团队空投的代币中受益的人就越多。

As a side note, it’s worth mentioning that this solution is not completely decentralized, as it depends on an owner to review and approve submissions. This mechanism is in place to prevent potential security issues related to having to trust unknown 3rd party contracts (ERC20 tokens submitted by teams). I couldn’t allow just anyone to submit any contract address, which could contain malicious code instead of the typical ERC20 token.

附带说明一下,值得一提的是,此解决方案并未完全分散,因为它取决于所有者来审核和批准提交的内容。 该机制可以防止潜在的安全问题,这些问题与必须信任未知的第三方合同(团队提交的ERC20令牌)有关。 我不允许任何人提交任何合同地址,该地址可能包含恶意代码,而不是典型的ERC20令牌。

The Airdrop Central has not been deployed on any network yet, as I’d like to thoroughly test it first. In the meantime, you can check the code (and even submit any bugs or suggestions) on my Github Repository:

Airdrop Central尚未部署在任何网络上,因为我想先对其进行全面测试。 同时,您可以在我的Github存储库中检查代码(甚至提交任何错误或建议):

  • If you are a user wanting to receive tokens, please add your address to this list. When I deploy the Airdrop Central to the mainnet, I’ll add your account to it so you can receive tokens from the get-go. Once teams start doing airdrops to it, you will be able to withdraw tokens for free.

    如果您是想要接收令牌的用户, 请将您的地址添加到此列表中。 当我将Airdrop Central部署到主网上时,我会将您的帐户添加到其中,以便您可以从一开始就收到令牌。 一旦团队开始对其进行空投,您将可以免费提取代币。

  • If you are a team looking into an easy way to send tokens to promote your Token Sale, please follow the instructions below to start the verification process.

    如果您是一个团队,希望通过一种简单的方法来发送代币以促进代币销售,请按照以下说明开始验证过程。

Once I deploy the Airdrop Central to the mainnet, I’ll accept/reject the submissions. Open an Issue on the Airdrop Central’s Github Repository with the tag “Submission” and the following title: [Token Symbol] — [Token Name] — [Token Address] — [Token Owner Address]. The token should already be deployed on the mainnet so the smart contract can be reviewed. An admin will notify you when it gets approved by leaving you a message on the Github Issue you created.

将Airdrop Central部署到主网后,我将接受/拒绝提交的内容。 在Airdrop Central的Github存储库上以标签“ Submission”和以下标题打开一个问题[令牌符号]-[令牌名称]-[令牌地址]-[令牌所有者地址] 。 令牌应该已经部署在主网上,以便可以查看智能合约。 管理员在获得批准后会通过在您创建的Github问题上给您留下一条消息来通知您。

这个怎么运作 (How it Works)

For the end users: Users sign up to the Token Central. Then, when a team airdrops tokens, the users can check how many of them they were awarded (based on how many were sent and how many users were signed to the central at that time) and withdraw them. All they need to know to withdraw their share of the tokens is the address of the token contract.

对于最终用户:用户注册到令牌中心。 然后,当团队空投令牌时,用户可以检查他们被授予了多少令牌(基于当时发送了多少令牌以及向中央签名的用户数量)并撤回了令牌。 他们需要提取令牌的全部内容就是令牌合同的地址。

For the teams: Submissions first have to be approved. Given that the Airdrop Central contract interacts with unknown and potentially harmful 3rd party contracts, it has to be approved by the central’s owner or designated admins before a token is accepted. The admins will basically have to check that the address submitted corresponds to an ERC20 compliant token contract and that it doesn’t contain any malicious code.

对于团队:首先必须批准提交。 鉴于Airdrop Central合同会与未知且可能有害的第三方合同进行交互,因此在接受令牌之前,必须先由Central的所有者或指定的管理员批准。 管理员基本上必须检查提交的地址是否符合ERC20兼容令牌协议,并且其中不包含任何恶意代码。

Once the team and token are approved, they can make as many airdrops as they want using the same account and token address. The owner of the central keeps 2% of the submitted tokens as a fee for using the service, and the rest are stored within the contract, available for the users to withdraw. Each airdrop has an expiration date. Tokens not withdrawn by users by that date can be retrieved by the team.

团队和令牌获得批准后,他们可以使用相同的帐户和令牌地址进行任意数量的空投。 中心的所有者保留所提交令牌的2%作为使用服务的费用,其余的令牌存储在合同中,供用户提取。 每个空投都有一个截止日期。 团队可以检索到该日期尚未被用户撤回的令牌。

使用空投中央合同 (Using the Airdrop Central Contract)

For end users:

对于最终用户:

  1. Sign up to the Airdrop Central by executing the signUpForAirdrops() function. This will subscribe you to future airdrops.

    通过执行signUpForAirdrops()函数注册到Airdrop Central。 这将使您订阅将来的空投。

  2. Call getTokensAvailableToMe(address _tokenAddress) to check how many tokens you are entitled to for the given token, based on whether or not the corresponding airdrop expired and how many tokens you already withdrew.

    调用getTokensAvailableToMe(address _tokenAddress) ,以根据相应的空投是否过期以及已经撤出的令牌来检查给定令牌有多少令牌。

  3. If you want to withdraw your tokens, call withdrawTokens(address _tokenAddress) which will check the tokens available with the same logic as above and transfer them.

    如果要提取令牌,请调用withdrawTokens(address _tokenAddress) ,它将使用与上述相同的逻辑检查可用令牌并进行传输。

  4. You should now be able to call balanceOf(address _owner) on the token contract to see the tokens added to your balance.

    现在,您应该可以调用令牌合约上的balanceOf(address _owner)来查看添加到余额中的令牌。

For teams:

对于团队:

  1. Submit your token information as explained above.

    如上所述提交您的令牌信息。
  2. Once the submission is approved, you’ll be able to do the airdrop. First, you need to give an allowance for the tokens to the Airdrop Central on your ERC20 token. You can do that by calling approve() on the token and passing the address of the Airdrop Central and the amount to allow. Don’t do this until your submission has been approved. Furthermore, only call approve() — don’t call transfer() or you will lose your tokens.

    一旦提交被批准,您就可以进行空投。 首先,您需要为ERC20令牌上的空投中心提供令牌配额。 您可以通过在令牌上调用approve()并传递空投中心的地址和允许的金额来实现。 在您的提交被批准之前,请勿这样做。 此外,仅调用approve()-不调用transfer(),否则您将丢失令牌。

  3. Once you have given the Airdrop Central an allowance on the tokens you own, you can initiate the airdrop by calling the function airdropTokens(address _tokenAddress, uint _totalTokensToDistribute, uint _expirationTime)

    一旦为空投中心分配了自己拥有的令牌,您就可以通过调用函数airdropTokens(address _tokenAddress, uint _totalTokensToDistribute, uint _expirationTime)来启动空投。

    where:

    哪里:

    address _tokenAddress is the address of the token you submitted.

    address _tokenAddress是您提交的令牌的地址。

    address _tokenAddress is the address of the token you submitted.uint _totalTokensToDistribute is the total tokens to distribute.

    address _tokenAddress是您提交的令牌的地址。 uint _totalTokensToDistribute是要分发的令牌总数。

    address _tokenAddress is the address of the token you submitted.uint _totalTokensToDistribute is the total tokens to distribute.uint _expirationTime is how long (in seconds) will the airdrop last.

    address _tokenAddress是您提交的令牌的地址。 uint _totalTokensToDistribute是要分发的令牌总数。 uint _expirationTime是空投持续多长时间(以秒为单位)。

  4. Optional step: You can execute returnTokensToAirdropper(address _tokenAddress) to get back the tokens that were not collected once the expiration date has been reached.

    可选步骤:您可以执行returnTokensToAirdropper(address _tokenAddress)来获取到达到期日期后未收集的令牌。

Regarding token distribution:

关于代币分配:

  • _totalTokensToDistribute is the total amount of tokens you want to distribute. The function will take care of adding the necessary decimals, obtained from the token contract. For example: If you want to airdrop 100 tokens, just enter 100, no matter how many decimals your token has.

    _totalTokensToDistribute是您要分配的令牌总数。 该函数将负责添加从令牌合约中获得的必要小数。 例如:如果您想空投100个令牌,则无论令牌有多少个小数,都只需输入100。

  • The tokens you send will be evenly distributed between all users currently registered. You can check how many registered users the central currently has by calling userSignupCount() in order to approximately figure out how many tokens you want to distribute to each.

    您发送的令牌将在当前注册的所有用户之间平均分配。 您可以通过调用userSignupCount()来检查中心当前拥有多少注册用户,以便大致确定要分配给每个令牌的令牌数量。

  • Users that sign up after the airdrop has been submitted won’t receive tokens from that submission.

    在之后注册的用户 空投已提交,将不会从该提交中接收令牌。

建立空投中心 (Building the Airdrop Central)

The complete, fully commented code can be found on my Github Repository.What follows is a detailed explanation of the most important parts of the code.

完整的,带有注释的代码可以在我的Github存储库中找到。 接下来是对代码最重要部分的详细说明。

管理提交 (Managing Submissions)

As mentioned above, we need to put a few mechanisms in place to prevent just anyone from submitting any contract. Since the Airdrop Central contract interacts with 3rd party token contracts that could contain harmful code, we first need to review each submission to prevent problems.

如上所述,我们需要建立一些机制来防止任何人提交任何合同。 由于Airdrop Central合同与可能包含有害代码的第三方令牌合同进行交互,因此我们首先需要检查每个提交的内容以防止出现问题。

In order to do this we will receive submissions off-chain, review them manually, and then, if everything is ok, approve them.

为此,我们将收到链下提交的内容,手动对其进行审核,然后,如果一切正常,请批准它们。

function approveSubmission(address _airdropper, address _tokenAddress) public onlyAdmin {        require(!airdropperBlacklist[_airdropper]);        require(!tokenBlacklist[_tokenAddress]);                tokenWhitelist[_tokenAddress] = true;    }

At any point, if we detect a problem with either a submitted contract or an account submitting malicious contracts, we can revoke access to the associated tokens and put them in a blacklist to prevent new submissions. Doing this also causes tokens to be inaccessible for withdrawal.

在任何时候,如果我们检测到已提交合同或提交恶意合同的帐户存在问题,我们都可以撤消对关联令牌的访问并将其放入黑名单,以防止新提交。 这样做还会导致无法访问令牌以进行提取。

This could be controversial, as it allows the owner/admins to freeze the tokens within the contract at their will. But on the other hand, it’s the only mechanism we have to fight malicious code that might have gone undetected when the token contract was first approved.

这可能会引起争议,因为它允许所有者/管理员按照自己的意愿冻结合同中的令牌。 但是,另一方面,这是我们必须与唯一在首次批准令牌合同时就未被发现的恶意代码作斗争的机制。

function revokeSubmission(address _airdropper, address _tokenAddress) public onlyAdmin {        if(_tokenAddress != address(0)){            tokenWhitelist[_tokenAddress] = false;            tokenBlacklist[_tokenAddress] = true;        }                if(_airdropper != address(0)){            airdropperBlacklist[_airdropper] = true;        }            }

If, for some reason, we blacklisted the wrong token/account or they were good citizens after all, the owner can remove them from the blacklist. This also re-enables the frozen tokens to be withdrawn.

如果出于某种原因,我们将错误的令牌/帐户列入黑名单,或者毕竟他们是好公民,则所有者可以将其从黑名单中删除。 这也使冻结的令牌重新启用。

用户注册过程 (User Sign-up Process)

Once the Airdrop Central contract has been deployed, users can start signing up. There are two ways to sign users up:

一旦部署了Airdrop Central合同,用户就可以开始注册。 有两种注册用户的方法:

They can do it themselves by calling the following function:

他们可以通过调用以下函数自己完成操作:

function signUpForAirdrops() public ifNotPaused{        require(signups[msg.sender].userAddress == address(0));        signups[msg.sender] = User(msg.sender,now);        userSignupCount++;                E_Signup(msg.sender,now);    }

Or an admin can sign them up by calling signupUsersManually(). Notice that, as opposed to a “regular” airdrop, the teams can’t manually add users as we want to avoid “spamming” and adding users without their consent.

或管理员可以通过调用signupUsersManually(). 请注意,与“常规”空投相反,团队无法手动添加用户,因为我们要避免“垃圾邮件”和未经用户同意添加用户。

function signupUsersManually(address _user) public onlyAdmin {        require(signups[_user].userAddress == address(0));        signups[_user] = User(_user,now);        userSignupCount++;                E_Signup(msg.sender,now);    }

Additionally, users can remove themselves from the Airdrop Central to stop receiving tokens. Doing so also prevents them from being able to withdraw pending tokens. As a matter of fact they will be lost to them, so they should think twice before doing so.

此外,用户可以将自己从Airdrop Central中删除,以停止接收令牌。 这样做还会阻止他们提取未决令牌。 事实上,他们会迷失于他们,因此他们在这样做之前应该三思。

令牌空投 (Token Airdrop)

Once a team has had their tokens approved by the Airdrop Central admin, they can perform any amount of airdrops for that token.

团队获得空投中央管理员批准的令牌后,便可以对该令牌执行任意数量的空投。

First, they need to give an allowance of the tokens they want to distribute to the Airdrop Central contract. In order to do that, they need to call the approve() function on the token, specifying how many tokens they want to allow the Airdrop Central to use.

首先,他们需要为要分配给空投中央合同的代币留出余地。 为此,他们需要调用令牌上的approve()函数,并指定要允许Airdrop Central使用的令牌数量。

Once that’s taken care of, they can perform the airdrop by calling the following function:

处理完之后,他们可以通过调用以下函数执行空投:

function airdropTokens(address _tokenAddress, uint _totalTokensToDistribute, uint _expirationTime) public ifNotPaused {        require(tokenWhitelist[_tokenAddress]);        require(!airdropperBlacklist[msg.sender]);                ERC20Basic token = ERC20Basic(_tokenAddress);        require(token.balanceOf(msg.sender) >= _totalTokensToDistribute);                //Multiply number entered by token decimals.        _totalTokensToDistribute = _totalTokensToDistribute.mul(10 ** uint256(token.decimals()));                // Calculate owner's tokens and tokens to airdrop        uint tokensForOwner = _totalTokensToDistribute.mul(ownersCut).div(100);        _totalTokensToDistribute = _totalTokensToDistribute.sub(tokensForOwner);                // Store the airdrop unique id in array (token address + id)        TokenAirdropID memory taid = TokenAirdropID(_tokenAddress,airdroppedTokens[_tokenAddress].length);        TokenAirdrop memory ta = TokenAirdrop(_tokenAddress,airdroppedTokens[_tokenAddress].length,msg.sender,now,now+_expirationTime,_totalTokensToDistribute,_totalTokensToDistribute,userSignupCount);        airdroppedTokens[_tokenAddress].push(ta);        airdrops.push(taid);                // Transfer the tokens        require(token.transferFrom(msg.sender,this,_totalTokensToDistribute));        require(token.transferFrom(msg.sender,owner,tokensForOwner));                E_AirdropSubmitted(_tokenAddress,ta.tokenOwner,ta.totalDropped,ta.airdropDate,ta.airdropExpirationDate);
}

The airdropTokens() function stores the tokens the contract was allowed to use in its internal balance. 2% of them are transferred to the contract owner and the rest are transferred to the contract. It can then distribute it among the users that were subscribed up to that moment.

airdropTokens()函数存储允许合同在其内部余额中使用的令牌。 其中2%已转让给合同所有者,其余的已转让给合同。 然后,它可以将其分发到当时已订阅的用户中。

The team that performed the airdrop can also recover the tokens that remain unclaimed past the expiration date of each airdrop by calling this function:

执行空投的团队还可以通过调用以下函数来恢复在每个空投到期后仍未领取的令牌:

function returnTokensToAirdropper(address _tokenAddress) public ifNotPaused {        require(tokenWhitelist[_tokenAddress]); // Token must be whitelisted first                // Get the token        ERC20Basic token = ERC20Basic(_tokenAddress);                 uint tokensToReturn = 0;                for (uint i =0; i<airdroppedTokens[_tokenAddress].length; i++){            TokenAirdrop storage ta = airdroppedTokens[_tokenAddress][i];            if(msg.sender == ta.tokenOwner &&                airdropHasExpired(_tokenAddress,i)){                                tokensToReturn = tokensToReturn.add(ta.tokenBalance);                ta.tokenBalance = 0;            }        }        require(token.transfer(msg.sender,tokensToReturn));        E_TokensWithdrawn(_tokenAddress,msg.sender,tokensToReturn,now);
}
代币提取 (Token Withdrawal)

The final thing we need to go over is the process by which the users withdraw the tokens they were sent. In order to do that, they need to call the withdrawTokens(address _tokenAddress) function. The function will go over all active (not yet expired or frozen) airdrops of the specified token and transfer them.

我们需要做的最后一件事是用户撤回发送令牌的过程。 为此,他们需要调用withdrawTokens(address _tokenAddress)函数。 该功能将遍历指定令牌的所有活动(尚未过期或冻结)空投并将其传输。

function withdrawTokens(address _tokenAddress) ifNotPaused public {        require(tokenWhitelist[_tokenAddress]); // Token must be whitelisted first                // Get User instance, given the sender account        User storage user = signups[msg.sender];        require(user.userAddress != address(0));                uint totalTokensToTransfer = 0;        // For each airdrop made for this token (token owner may have done several airdrops at any given point)        for (uint i =0; i<airdroppedTokens[_tokenAddress].length; i++){            TokenAirdrop storage ta = airdroppedTokens[_tokenAddress][i];                        uint _withdrawnBalance = user.withdrawnBalances[_tokenAddress][i];                        //Check that user signed up before the airdrop was done. If so, he is entitled to the tokens            //And the airdrop must not have expired            if(ta.airdropDate >= user.signupDate &&                now <= ta.airdropExpirationDate){                                // The user will get a portion of the total tokens airdroped,                // divided by the users at the moment the airdrop was created                uint tokensToTransfer = ta.totalDropped.div(ta.usersAtDate);                                // if the user has not alreay withdrawn the tokens                if(_withdrawnBalance < tokensToTransfer){                    // Register the tokens withdrawn by the user and total tokens withdrawn                    user.withdrawnBalances[_tokenAddress][i] = tokensToTransfer;                    ta.tokenBalance = ta.tokenBalance.sub(tokensToTransfer);                    totalTokensToTransfer = totalTokensToTransfer.add(tokensToTransfer);                                    }            }        }        // Get the token        ERC20Basic token = ERC20Basic(_tokenAddress);         // Transfer tokens from all airdrops that correspond to this user        require(token.transfer(msg.sender,totalTokensToTransfer));                E_TokensWithdrawn(_tokenAddress,msg.sender,totalTokensToTransfer,now);    }
下一步 (Next Steps)

One of the many things I’d like to do next is to build a web interface (a dapp) that allows people to see the latest and upcoming airdrops and subscribe to them.

接下来我要做的许多事情之一就是构建一个Web界面(一个dapp),使人们可以查看最新的和即将到来的空投并进行订阅。

If you are part of a team with an active ERC20 token, or you are planning on launching one and you’d like to use the Airdrop Central to do an airdrop, drop me a line. Otherwise, any feedback and suggestions are greatly appreciated.

如果您是拥有有效ERC20令牌的团队的成员,或者您打算发射一个令牌,而您想使用Airdrop Central进行空投,请给我留言。 否则,将不胜感激任何反馈和建议。

I hope you enjoyed reading this article as much as I enjoyed writing it. I’m currently taking consultancy jobs related to smart contracts development. If you are planning on raising funds through an ICO or building a Blockchain-based product, feel free to get in touch with me.

希望您喜欢阅读这篇文章,也喜欢阅读它。 我目前正在从事与智能合约开发相关的顾问工作。 如果您打算通过ICO筹集资金或构建基于区块链的产品,请随时与我联系。

翻译自: https://www.freecodecamp.org/news/how-i-built-a-multi-token-airdrop-central-to-distribute-erc20-tokens-cb70b6218b5c/

swift airdrop

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值