简体   繁体   English

如何运行一个成功的 Solidity 智能合约测试脚本?

[英]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您可以在下面找到代码

  • my ERC20 token contract我的 ERC20 代币合约
  • my crowd-sale contract and its test script (specifically the part that is failing)我的众筹合同及其测试脚本(特别是失败的部分)
  • the deployment script部署脚本
  • and finally the error I am getting when I run my test最后是我运行测试时遇到的错误

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.

相关问题 Solidity:在智能合约中填充结构 - Solidity: populating a struct in a smart contract 如何从 Javascript 向 Solidity 智能合约 function 输入数据? - How to input data to a solidity smart contract function from Javascript? 智能合约:如何在 React 中获得 Solidity function 的回报? - Smart contract: How to get return of Solidity function in React? 如何使用安全帽和以太币监控 Solidity 智能合约上的事件? - How to monitor events on an Solidity Smart Contract using hardhat and ethers? 接受JavaScript中的参数以发送到Solidity智能合约 - Accepting parameters in javascript to send to solidity smart contract 是否可以从特定帐户在我的前端运行我的 Solidity 智能合约 function - Is it possible to run my Solidity Smart Contract function on my frontend from a specific account 如何为javascript / truffle中的每个测试创建新的以太坊/实体合约 - how to create new ethereum/solidity contract for each test in javascript/truffle 如何实现智能合约添加eth地址记录以在solidity中引用特定的ENS子域名 - How to implement smart contract to add eth address record to refer the specific ENS subdomain name in solidity 使用 javascript 调用 Solidity 智能合约来铸造代币似乎不起作用 - Calling solidity smart contract with javascript to mint token does not seem to work 我们可以更新部署在 Hedera 测试网中的 Solidity 智能合约吗? - Can we update solidity smart contract which is deployed in Hedera TestNet?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM