搭建一个可众筹的ERC777代币

这篇文章主要介绍了搭建一个可众筹的ERC777代币 ,文中通过代码以及文档配合进行讲解,很详细,它对在座的每个人的研究和工作具有很经典的参考价值。 如果需要,让我们与区块链资料网一起学习。

https://www.interchains.cc/22579.html

搭建一个可众筹的ERC777代币是很好的区块链资料,他说明了区块链当中的经典原理,可以给我们提供资料,搭建一个可众筹的ERC777代币学习起来其实是很简单的,

不多的几个较为抽象的概念也很容易理解,之所以很多人感觉搭建一个可众筹的ERC777代币比较复杂,一方面是因为大多数的文档没有做到由浅入深地讲解,概念上没有注意先后顺序,给读者的理解带来困难

搭建一个可众筹的ERC777代币

假设有这样一个需求:你为了实现一个伟大的理想,需要筹集100个ETH作为启动资金,所以你发行了一个ERC777代币作为凭证,同时布署了一个众筹合约,你的支持者可以通过众筹合约向你购买代币,兑换比例为1ETH:100ERC777

分析

大家都知道,ERC777向后兼容ERC20,ERC20的接口方法在ERC777中同样适用. 所以在Openzeppelin的众筹合约中,通过buyTokens()逻辑进行购买代币的操作,buyTokens()方法又会触发一个_deliverTokens()的内部方法进行转账.来看一下代码:

function _deliverTokens(address beneficiary, uint256 tokenAmount) internal {     _token.safeTransfer(beneficiary, tokenAmount); }

代码中的_token就是众筹所发售的代币,而safeTransfer()方法是一个套用在token身上的library

//Crowdsale.sol using SafeERC20 for IERC20; IERC20 private _token;

在SafeERC20.sol的library中可以找到safeTransfer的实现方法:

//SafeERC20.sol function safeTransfer(IERC20 token, address to, uint256 value) internal {     callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); }

所以从代码中可以看到,众筹合约还是通过token.transfer方法进行购买代币后的转账的.所以我们如果使用ERC777进行众筹,肯定是可以兼容的.

注意,下面的例子中使用Openzeppelin的AllowanceCrowdsale众筹方法,前面讲的_deliverTokens()方法中将会被重写,转而使用token.transferFrom方法

ERC777合约

请先初始化truffle环境和安装了openzeppelin

ERC777合约代码

$ vim contracts/ERC777Token.sol
pragma solidity ^0.5.0;  import "@openzeppelin/contracts/token/ERC777/ERC777.sol";  contract ERC777Token is ERC777{     constructor(         string memory name, //代币名称         string memory symbol, //代币缩写         uint256 initialSupply, //发行总量         address[] memory defaultOperators //默认操作员数组     ) public ERC777(name, symbol, defaultOperators) {         _mint(msg.sender, msg.sender, initialSupply, "", "");     } } 

众筹合约

我们使用Openzeppelin提供的AllowanceCrowdsale众筹合约为演示,这个合约的功能是众筹的代币将可以从一个发行者账户中发送给购买者账户,所以在布署合约之后,需要发行者将全部代币批准给众筹合约.

合约代码

$ vim contracts/AllowanceCrowdsale.sol
pragma solidity ^0.5.0;  import "@openzeppelin/contracts/crowdsale/Crowdsale.sol"; import "@openzeppelin/contracts/crowdsale/emission/AllowanceCrowdsale.sol";  contract AllowanceCrowdsaleContract is Crowdsale, AllowanceCrowdsale {     constructor(         uint256 rate,           // 兑换比例         address payable wallet, // 接收ETH受益人地址         IERC20 token,           // 代币地址         address tokenWallet     // 代币从这个地址发送     )         AllowanceCrowdsale(tokenWallet)         Crowdsale(rate, wallet, token)         public{} } 

编译合约

$ truffle compile

布署合约

布署脚本

$ vim migrations/2_deploy_ERC777Token.js
const ERC777Token = artifacts.require("ERC777Token"); const AllowanceCrowdsaleContract = artifacts.require("AllowanceCrowdsaleContract"); const { singletons } = require('@openzeppelin/test-helpers');  module.exports = async (deployer, network, accounts) => {     await singletons.ERC1820Registry(accounts[0]);//布署ERC1820注册表(仅测试环境)     const totalSupply = web3.utils.toWei('10000');     const defaultOperators = accounts[1];     const param = [         "My ERC777 Token",   //代币名称         "M7T",              //代币缩写         totalSupply,        //发行总量         [defaultOperators]    //默认操作员[可选],或传入空数组     ]     const ERC777TokenInstance = await deployer.deploy(ERC777Token, ...param);     const crowdsaleParam = [           100,                        //兑换比例1ETH:100ERC777         accounts[1],                //接收ETH受益人地址         ERC777TokenInstance.address,//代币地址         accounts[0]                 //代币从这个地址发送     ]     const AllowanceCrowdsaleInstance = await deployer.deploy(AllowanceCrowdsaleContract, ...crowdsaleParam);     //在布署之后必须将发送者账户中的代币批准给众筹合约     ERC777TokenInstance.approve(AllowanceCrowdsaleInstance.address, web3.utils.toWei(totalSupply.toString(),'ether')); };

在测试环境中布署脚本中必须引用@openzeppelin/test-helpers测试助手,使用它来模拟一个ERC1820注册表,因为ERC777必须向ERC1820注册表注册自己的接口方法;在正式网或Ropsten测试网布署时需要取消掉.

布署合约

请确保一个测试节点在运行

$ truffle migrate

测试合约

编写测试脚本

$ vim test/ERC777Crowdsale.js
const assert = require('assert'); const { contract, accounts, web3 } = require('@openzeppelin/test-environment'); const { ether, makeInterfaceId, constants, singletons, expectEvent } = require('@openzeppelin/test-helpers'); const CrowdsaleContract = contract.fromArtifact("AllowanceCrowdsaleContract"); const ERC777Token = contract.fromArtifact("ERC777Token");  const totalSupply = '10000';//发行总量 const [owner, sender, receiver, purchaser, beneficiary] = accounts; const EthValue = '1'; const rate = '100'; const TokenValue = (EthValue * rate).toString(); const defaultOperators = [sender]; const userData = web3.utils.toHex('A gift');  describe("布署合约", function () {     it('实例化ERC1820注册表', async function () {         ERC1820RegistryInstance = await singletons.ERC1820Registry(owner);     });     it('布署ERC777代币合约', async function () {         ERC777Param = [             "My ERC777 Token",   //代币名称             "M7T",              //代币缩写             ether(totalSupply),      //发行总量             defaultOperators    //默认操作员         ];         ERC777Instance = await ERC777Token.new(...ERC777Param, { from: owner });     });     it('布署众筹合约', async function () {         CrowdsaleParam = [             rate,                                       //兑换比例1ETH:100ERC777             beneficiary,                                //接收ETH受益人地址             ERC777Instance.address,                     //代币地址             owner,                                      //代币从这个地址发送         ]         CrowdsaleInstance = await CrowdsaleContract.new(...CrowdsaleParam, { from: owner });     }); }); describe("布署后首先执行", function () {     it('将代币批准给众筹合约', async function () {         await ERC777Instance.approve(CrowdsaleInstance.address, ether(totalSupply), { from: owner });     }); }); describe("测试ERC777合约基本信息", function () {     it('代币名称: name()', async function () {         assert.equal(ERC777Param[0], await ERC777Instance.name());     });     it('代币缩写: symbol()', async function () {         assert.equal(ERC777Param[1], await ERC777Instance.symbol());     });     it('代币精度: decimals()', async function () {         assert.equal('18', (await ERC777Instance.decimals()).toString());     });     it('代币总量: totalSupply()', async function () {         assert.equal(ERC777Param[2].toString(), (await ERC777Instance.totalSupply()).toString());     });     it('代币最小单位: granularity()', async function () {         assert.equal('1', (await ERC777Instance.granularity()).toString());     }); }); describe("测试通用的众筹方法", function () {     it('ERC777代币地址: token()', async function () {         assert.equal(ERC777Instance.address, await CrowdsaleInstance.token());     });     it('ETH受益人地址: wallet()', async function () {         assert.equal(beneficiary, await CrowdsaleInstance.wallet());     });     it('兑换比例: rate()', async function () {         assert.equal(rate, await CrowdsaleInstance.rate());     });     it('代币现存地址: tokenWallet()', async function () {         assert.equal(owner, await CrowdsaleInstance.tokenWallet());     });      it('测试购买代币方法: buyTokens()', async function () {         let receipt = await CrowdsaleInstance.buyTokens(sender, { value: ether(EthValue), from: sender });         expectEvent(receipt, 'TokensPurchased', {             purchaser: sender,             beneficiary: sender,             value: ether(EthValue),             amount: ether(TokenValue)         });     });     it('测试众筹收入: weiRaised()', async function () {         assert.equal(ether(EthValue).toString(), (await CrowdsaleInstance.weiRaised()).toString());     });      it('购买者账户余额为: balanceOf()', async function () {         assert.equal(ether(TokenValue).toString(), (await ERC777Instance.balanceOf(sender)).toString());     });     it('测试剩余代币数量: remainingTokens()', async function () {         assert.equal(ether((parseInt(totalSupply) - parseInt(TokenValue)).toString()).toString(), (await CrowdsaleInstance.remainingTokens()).toString());     }); });

ERC777代币还可以为自己设置一个发布和收币的钩子合约,每当发送和接收方法被触发时都会调用,具体方法请看我的Github

部分转自网络,侵权联系删除www.interchains.cchttps://www.interchains.cc/22579.html

区块链毕设网(www.interchains.cc)全网最靠谱的原创区块链毕设代做网站 部分资料来自网络,侵权联系删除! 最全最大的区块链源码站 ! QQ3039046426
区块链知识分享网, 以太坊dapp资源网, 区块链教程, fabric教程下载, 区块链书籍下载, 区块链资料下载, 区块链视频教程下载, 区块链基础教程, 区块链入门教程, 区块链资源 » 搭建一个可众筹的ERC777代币

提供最优质的资源集合

立即查看 了解详情