[英]How To Run A Successful Solidity Smart Contract Test Script?
I have been following this tutorial by Gregory from Dapp University on how to create your own ERC20 token along with a crowd-sale smart contract.我一直在关注Dapp 大学Gregory 的这篇关于如何创建自己的 ERC20 代币以及一个众筹智能合约的教程。 I have been successful so far, but I am stuck where I need to make the buytokens() function work so a transfer of tokens from the address of the crowd-sale contract to the buyer's can take place.
到目前为止,我已经成功了,但是我被困在需要使 buytokens() 函数工作的地方,以便可以将代币从众售合同的地址转移到买方的地址。 The test I am about to show makes use of the async/await pattern, different from what is on the video tutorial.
我即将展示的测试使用了 async/await 模式,与视频教程中的不同。 Below you can find the code of
您可以在下面找到代码
Thanks for your help.谢谢你的帮助。
Development Environment开发环境
Truffle v5.4.18 (core: 5.4.18)
Solidity - 0.8.9 (solc-js)
Node v16.1.0
Web3.js v1.5.3
Crowd-sale Contract众售合约
// SPDX-License-Identifier: MIT
pragma solidity >=0.7.0;
import "./NzouaToken.sol";
contract NzouaTokenSale {
address admin;
NzouaToken public tokenContract;
uint256 public tokenPrice;
uint256 public tokensSold;
event Sell(address _buyer, uint256 _amount);
constructor(NzouaToken _tokenContract, uint256 _tokenPrice) {
admin = msg.sender;
tokenContract = _tokenContract;
tokenPrice = _tokenPrice;
}
function multiply(uint x, uint y) internal pure returns(uint z){
require(y == 0 || (z = x * y) / y == x);
}
function buyTokens(uint256 _numberOfTokens) public payable{
require(msg.value == multiply(_numberOfTokens, tokenPrice));
require(tokenContract.balanceOf(address(this)) >= _numberOfTokens);
require(tokenContract.transfer(msg.sender, _numberOfTokens));
tokensSold += _numberOfTokens;
emit Sell(msg.sender, _numberOfTokens);
}
}
ERC20 Token Contract ERC20 代币合约
// SPDX-License-Identifier: MIT
pragma solidity >=0.7.0;
contract NzouaToken {
string public name = "Nzouat Token";
string public symbol = "NZT";
uint256 public totalSupply;
event Transfer(
address indexed _from,
address indexed _to,
uint256 _value
);
event Approval(
address indexed _owner,
address indexed _spender,
uint256 _value
);
mapping(address => uint256) public balanceOf;
mapping(address => mapping(address => uint256)) public allowance;
constructor(uint256 _initialSupply) {
balanceOf[msg.sender] = _initialSupply;
totalSupply = _initialSupply;
}
function transfer(address _to, uint256 _value) public returns(bool success){
require(balanceOf[msg.sender] >= _value, 'The account has low funds');
balanceOf[msg.sender] -= _value;
balanceOf[_to] += _value;
emit Transfer(msg.sender, _to, _value);
return true;
}
function approve(address _spender, uint256 _value) public returns(bool success) {
allowance[msg.sender][_spender] = _value;
emit Approval(msg.sender, _spender, _value);
return true;
}
function transferFrom(address _from, address _to, uint256 _value) public returns (bool success){
require(_value <= balanceOf[_from]);
require(_value <= allowance[_from][msg.sender]);
balanceOf[_from] -= _value;
balanceOf[_to] += _value;
allowance[_from][msg.sender] -= _value;
emit Transfer(_from, _to, _value);
return true;
}
}
Deployment Script部署脚本
const NzouaToken = artifacts.require("NzouaToken");
const NzouaTokenSale = artifacts.require("NzouaTokenSale");
module.exports = async function (deployer, network, accounts) {
await deployer.deploy(NzouaToken, 1000000); // 1000000 NZT tokens
await deployer.deploy(NzouaTokenSale, NzouaToken.address, 1000000000000000);
};
Unit Testing With Mocha (Part of the crowd-sale test that is failing)使用 Mocha 进行单元测试(失败的众筹测试的一部分)
var NzouaToken = artifacts.require('./NzouaToken');
var NzouaTokenSale = artifacts.require('./NzouaTokenSale');
contract('NzouaTokenSale', async (accounts) => {
let tokenSale;
let token;
let tokenPrice = 1000000000000000; // in wei
const adminAccount = accounts[0];
const buyerAccount = accounts[1];
describe('Facilitates Token Buying', async () => {
it('Required a successful Transfer of Tokens', async () => {
token = await NzouaToken.deployed();
tokenSale = await NzouaTokenSale.deployed();
let tokenSaleBalance;
let buyerBalance;
const numberOfTokens = 10;
const tokensAvailable = 750000;
// try {
let receipt = await token.transfer.call(tokenSale.address, tokensAvailable, {
from: adminAccount
})
tokenSaleBalance = await token.balanceOf(tokenSale.address);
assert.equal(tokenSaleBalance.toNumber(), tokensAvailable, 'Contract received funds.')
await tokenSale.buyTokens(numberOfTokens, {
from: buyerAccount,
value: numberOfTokens * tokenPrice
});
// Grab the new balance of the buyerAccount
buyerBalance = await token.balanceOf(buyerAccount);
buyerBalance = buyerBalance.toNumber()
assert.equal(tokenSaleBalance, numberOfTokens, 'Buyer Balance updated');
// Grab the new balance of the Token Sale Contract
tokenSaleBalance = await token.balanceOf(tokenSale.address);
tokenSaleBalance = tokenSaleBalance.toNumber()
assert.equal(tokenSaleBalance, tokensAvailable - numberOfTokens, 'Token Sale Balance updated');
// } catch (error) {
// // console.log(error.message)
// assert(error.message.indexOf('revert') >= 0, 'Something went wrong while making the transfer');
// }
});
});
});
If I uncomment the try{}catch{} section, the test will pass but it is not the behavior I am expecting.如果我取消对try{}catch{}部分的注释,测试将通过,但这不是我期望的行为。
When I run my test using truffle truffle test
inside the truffle console, All my other tests pass but one, and I get this revert error当我在 truffle 控制台内使用 truffle
truffle test
运行我的测试时,我的所有其他测试都通过了一个,并且我收到了这个还原错误
What am I doing wrong here?我在这里做错了什么?
You are getting error because your transfer
function has this require
您收到错误,因为您的
transfer
功能有此require
require(balanceOf[msg.sender] >= _value, 'The account has low funds');
so make sure your transfer amount is less than msg.sender
's balance所以请确保您的转账金额小于
msg.sender
的余额
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.