I create a smart contract to sell my token.I am following the Dapp University(youtube channel) course.
I have done unit testing of smart contract.All test cases pass.
And I am trying to buy token on my client side application.So there is transaction failed.And this error comes VM Exception while processing transaction: revert:
Then I test buyTokens() function in truffle console.So,The same error comes.
Here is my solidity code:-
pragma solidity ^0.4.2;
import "./DappToken.sol";
contract DappTokenSale {
address admin;
DappToken public tokenContract;
uint256 public tokenPrice;
uint256 public tokensSold;
event Sell(address _buyer, uint256 _amount);
function DappTokenSale(DappToken _tokenContract, uint256 _tokenPrice) public {
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(this) >= _numberOfTokens);
require(tokenContract.transfer(msg.sender, _numberOfTokens));
tokensSold += _numberOfTokens;
Sell(msg.sender, _numberOfTokens);
}
// Ending Token DappTokenSale
function endSale() public {
// Require admin
require (msg.sender == admin);
// Transfer remaing DappToken to admin
require(tokenContract.transfer(admin,tokenContract.balanceOf(this)));
// Destroy Contract
selfdestruct(admin);
}
}
Here is my "DappToken" solidity code:-
pragma solidity ^0.4.2;
/**
* The contractName contract does this and that...
*/
contract DappToken {
// Name
string public name = "DappToken";
// Symbol
string public symbol = 'DAPP';
//standard
string public standard = 'DApp Token v1.0';
uint256 public totalSupply;
event Transfer(
address indexed _form,
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;
function DappToken (uint256 _intialSupply) public {
balanceOf[msg.sender] = _intialSupply;
totalSupply = _intialSupply;
//allcate the intial supply
}
//Transfar
function transfer(address _to,uint256 _value) public returns (bool success){
// Exception if account does not enough
require (balanceOf[msg.sender] >= _value);
// Transfar the balance
balanceOf[msg.sender] -= _value;
balanceOf[_to] += _value;
// Transfar Event
Transfer(msg.sender,_to,_value);
// Return a boolean
return true;
}
// approve
function approve(address _spender,uint256 _value) public returns (bool success){
//allowence
allowance[msg.sender][_spender] = _value;
// Approve event
Approval(msg.sender,_spender,_value);
return true;
}
// transfer form
function transferFrom(address _from, address _to, uint256 _value) public returns (bool success) {
require(_value <= balanceOf[_from]);
require(_value <= allowance[_from][msg.sender]);
// change the balance
balanceOf[_from] -= _value;
//update the balance
balanceOf[_to] += _value;
allowance[_from][msg.sender] -= _value;
emit Transfer(_from,_to,_value);
return true;
}
}
Here is my "test.js" code:-
var DappToken = artifacts.require('./DappToken.sol');
var DappTokenSale = artifacts.require('./DappTokenSale.sol');
contract('DappTokenSale', function(accounts) {
var tokenInstance;
var tokenSaleInstance;
var admin = accounts[0];
var buyer = accounts[1];
var tokenPrice = 1000000000000000; // in wei
var tokensAvailable = 750000;
var numberOfTokens;
it('initializes the contract with the correct values', function() {
return DappTokenSale.deployed().then(function(instance) {
tokenSaleInstance = instance;
return tokenSaleInstance.address
}).then(function(address) {
assert.notEqual(address, 0x0, 'has contract address');
return tokenSaleInstance.tokenContract();
}).then(function(address) {
assert.notEqual(address, 0x0, 'has token contract address');
return tokenSaleInstance.tokenPrice();
}).then(function(price) {
assert.equal(price, tokenPrice, 'token price is correct');
});
});
it('facilitates token buying', function() {
return DappToken.deployed().then(function(instance) {
// Grab token instance first
tokenInstance = instance;
return DappTokenSale.deployed();
}).then(function(instance) {
// Then grab token sale instance
tokenSaleInstance = instance;
// Provision 75% of all tokens to the token sale
return tokenInstance.transfer(tokenSaleInstance.address, tokensAvailable, { from: admin })
}).then(function(receipt) {
numberOfTokens = 10;
return tokenSaleInstance.buyTokens(numberOfTokens, { from: buyer, value: numberOfTokens * tokenPrice })
}).then(function(receipt) {
assert.equal(receipt.logs.length, 1, 'triggers one event');
assert.equal(receipt.logs[0].event, 'Sell', 'should be the "Sell" event');
assert.equal(receipt.logs[0].args._buyer, buyer, 'logs the account that purchased the tokens');
assert.equal(receipt.logs[0].args._amount, numberOfTokens, 'logs the number of tokens purchased');
return tokenSaleInstance.tokensSold();
}).then(function(amount) {
assert.equal(amount.toNumber(), numberOfTokens, 'increments the number of tokens sold');
return tokenInstance.balanceOf(buyer);
}).then(function(balance) {
assert.equal(balance.toNumber(), numberOfTokens);
return tokenInstance.balanceOf(tokenSaleInstance.address);
}).then(function(balance) {
assert.equal(balance.toNumber(), tokensAvailable - numberOfTokens);
// Try to buy tokens different from the ether value
return tokenSaleInstance.buyTokens(numberOfTokens, { from: buyer, value: 1 });
}).then(assert.fail).catch(function(error) {
assert(error.message.indexOf('revert') >= 0, 'msg.value must equal number of tokens in wei');
return tokenSaleInstance.buyTokens(800000, { from: buyer, value: numberOfTokens * tokenPrice })
}).then(assert.fail).catch(function(error) {
assert(error.message.indexOf('revert') >= 0, 'cannot purchase more tokens than available');
});
});
it('ends token sale', function() {
return DappToken.deployed().then(function(instance) {
// Grab token instance first
tokenInstance = instance;
return DappTokenSale.deployed();
}).then(function(instance) {
// Then grab token sale instance
tokenSaleInstance = instance;
// Try to end sale from account other than the admin
return tokenSaleInstance.endSale({ from: buyer });
}).then(assert.fail).catch(function(error) {
assert(error.message.indexOf('revert' >= 0, 'must be admin to end sale'));
// End sale as admin
return tokenSaleInstance.endSale({ from: admin });
}).then(function(receipt) {
return tokenInstance.balanceOf(admin);
}).then(function(balance) {
assert.equal(balance.toNumber(), 999990, 'returns all unsold dapp tokens to admin');
// Check that token price was reset when selfDestruct was called
// return tokenSaleInstance.tokenPrice();
// }).then(function(price) {
// assert.equal(price.toNumber(), 0, 'token price was reset');
});
});
});
I am new in this field.What is this error mean and why this error comes??Any one tell me What I mistake in code??.
require()
inbuyTokens()
and try again. Does it fail? Then start uncommenting, when you determine which line is failing you can inspect it in more detail.