这是我的问题:)
"Error:返回的错误:处理事务时的VM异常:还原“在到达传输函数时。我认为这与我的没有任何TotalSupply的令牌有关。
的步骤
令牌智能契约:
pragma solidity 0.5.16;
import "openzeppelin-solidity/contracts/token/ERC20/DetailedERC20.sol";
import "openzeppelin-solidity/contracts/token/ERC20/PausableToken.sol";
contract TokenSPC is PausableToken, DetailedERC20
{
constructor(string memory _name, string memory _symbol, uint8 _decimals, uint256 _amount)
DetailedERC20(_name, _symbol, _decimals)
public
{
require(_amount > 0, "amount has to be greater than 0");
totalSupply_ = _amount.mul(10 ** uint256(_decimals));
balances[msg.sender] = totalSupply_;
emit Transfer(address(0), msg.sender, totalSupply_);
}
} Crowdsale合同:
pragma solidity 0.5.16;
import './TokenSPC.sol';
import "openzeppelin-solidity/contracts/token/ERC20/ERC20.sol";
import "openzeppelin-solidity/contracts/token/ERC20/PausableToken.sol";
import "openzeppelin-solidity/contracts/crowdsale/Crowdsale.sol";
import "openzeppelin-solidity/contracts/crowdsale/validation/CappedCrowdsale.sol";
contract TokenCrowdsale is Crowdsale, CappedCrowdsale {
//Minim invest contrib
//Max invest contrib
uint256 public investorMinCap = 2000000000000000;
uint256 public investorHardCap = 50000000000000000000;
mapping(address => uint256) public contributions;
constructor(
uint256 _rate,
address payable _wallet,
ERC20 _token,
uint256 _cap
)
Crowdsale(_rate, _wallet, _token)
CappedCrowdsale(_cap)
public
{
}
function getUserContribution(address _beneficiary)
public view returns(uint256)
{
return contributions[_beneficiary];
}
function _preValidatePurchase(
address _beneficiary,
uint256 _weiAmount
)
internal
{
super._preValidatePurchase(_beneficiary,_weiAmount);
uint256 _existingContribution = contributions[_beneficiary];
uint256 _newContribution = _existingContribution.add(_weiAmount);
require(_newContribution >= investorMinCap && _newContribution <= investorHardCap);
contributions[_beneficiary] = _newContribution;
}
}测试Crowdsale.test:
import ether from './helpers/ether';
import sendTransaction from './helpers/sendTransaction';
import EVMRevert from './helpers/EVMRevert';
const BN = web3.utils.BN;
require('chai')
.use(require('chai-as-promised'))
.use(require('chai-bn')(BN))
.should();
const Token = artifacts.require('TokenSPC');
const TokenCrowdsale = artifacts.require('TokenCrowdsale');
contract('TokenCrowdsale', function([_, wallet, investor1, investor2]) {
/*before(async function() {
// Transfer extra ether to investor1's account for testing
await web3.eth.sendTransaction({ from: _, to: investor1, value: ether(60) })
await web3.eth.sendTransaction({ from: _, to: investor2, value: ether(20) })
});*/
beforeEach(async function () {
// Token config
this.name = "Seed Project Coin";
this.symbol = "SPC";
this.decimals = 18;
this.amount = 380000000;
// Deploy Token
this.token = await Token.new(
this.name,
this.symbol,
this.decimals,
this.amount
);
// Crowdsale config
this.rate = new BN(500);
this.wallet = wallet;
this.cap = ether(100);
//Invest cap
this.investorMinCap = ether(0.002);
this.investorHardCap = ether(50);
this.crowdsale = await TokenCrowdsale.new(
this.rate,
this.wallet,
this.token.address,
this.cap
);
// Transfer token owern to crowdsale
await this.token.transferOwnership(this.crowdsale.address);
});
describe('token', function() {
it("should check totalSupply", async function() {
const _supp = await this.token.totalSupply();
console.log( " ", "totalSupply =", _supp.toString());
});
});
describe('crowdsale', function() {
it('tracks the rate', async function() {
const _rate = await this.crowdsale.rate();
//console.log( " ", "Rate =", _rate );
//console.log( " ", "this.rate =", this.rate );
_rate.should.be.a.bignumber.that.equals(this.rate);
});
it('tracks the wallet', async function() {
const wallet = await this.crowdsale.wallet();
wallet.should.equal(this.wallet);
});
it('tracks the token', async function() {
const token = await this.crowdsale.token();
token.should.equal(this.token.address);
});
});
//A revoir---------------------------------------------
/* describe('actualization crowdsale', function() {
it('actualize total supply of crowdsale after purchase', async function() {
const originalTotalSupply = await this.token.totalSupply();
this.token.totalSupply_ -= 1;
const newTotalSupply = await this.token.totalSupply();
assert.isTrue(newTotalSupply < originalTotalSupply)
});
});*/
describe('capped crowdsale', async function() {
it('has the correct hard cap', async function() {
const _cap = await this.crowdsale.cap();
_cap.should.be.a.bignumber.that.equals(this.cap);
});
});
//A revoir ---------------------------------------------
/*describe('accepting payments', function() {
it('should accept payments', async function() {
const value = ether(1);
const purchaser = investor2;
await this.crowdsale.sendTransaction({ value : value, from : investor1}).should.be.fulfilled;
await this.crowdsale.buyTokens(investor1, { value: value, from: purchaser }).should.be.fulfilled;
});
});*/
describe('buyTokens()', function() {
describe('when the contrib is less than min cap', function(){
it('rejects the transaction', async function() {
const value = this.investorMinCap - 1;
await this.crowdsale.buyTokens(investor2, { value: value, from: investor2 }).should.be.rejectedWith(EVMRevert);
});
});
describe('when the invest has already met the min cap', function(){
it('allows the invest to contrib below the min cap', async function() {
//isvalid
const value1 = ether(1);
await this.crowdsale.buyTokens(investor1, { value: value1, from: investor1 });
console.log( " ", "inv =", investor1 );
console.log( " ", "value =", value1 );
console.log( " ", "inv.value =", await this.crowdsale.buyTokens(investor1, { value: value1, from: investor1 }) );
//is less then invest cap
const value2 = 1; //wei
await this.crowdsale.buyTokens(investor1, { value: value2, from: investor1 }).should.be.fulfilled;
});
});
});
/*---------------A revoir
describe('when the total contrib exceed the invest hardcap', function(){
it('reject the transaction', async function() {
//first contrib in valid range
const value1 = ether(2);
await this.crowdsale.buyTokens(investor1, { value: value1, from: investor1});
//second is over hardcap
const value2 = ether(49);
await this.crowdsale.buyTokens(investor1, { value: value2, from: investor1}).should.be.rejectedWith(EVMRevert);
});
});
describe('when the contrib is within the valid range', function() {
const value = ether(2);
it('succeeds & updates the contrib amount', async function() {
await this.crowdsale.buyTokens(investor2, { value: value, from: investor2 }).should.be.fulfilled;
const contribution = await this.crowdsale.getUserContribution(investor2);
contribution.should.be.bignumber.equals;
});
});
*/
});设计脚本:
const Token = artifacts.require("./TokenSPC.sol");
const TokenCrowdsale = artifacts.require("./TokenCrowdsale.sol");
const ether = (n) => new web3.utils.BN(web3.utils.toWei(n.toString(), 'ether'));
const duration = {
seconds: function (val) { return val; },
minutes: function (val) { return val * this.seconds(60); },
hours: function (val) { return val * this.minutes(60); },
days: function (val) { return val * this.hours(24); },
weeks: function (val) { return val * this.days(7); },
years: function (val) { return val * this.days(365); },
};
module.exports = async function(deployer, network, accounts) {
const _name = "Seed Project Coin";
const _symbol = "SPC";
const _decimals = 18;
const _amount = 380000000;
await deployer.deploy(Token , _name, _symbol, _decimals, _amount );
const deployedToken = await Token.deployed();
const _rate = 1;
const _wallet = accounts[0]; // TODO: Replace me
const _token = deployedToken.address;
const _cap = ether(100);
await deployer.deploy(
TokenCrowdsale,
_rate,
_wallet,
_token,
_cap
);
return true;
};通过cmd:ganache-cli启动ganache-cli
编译:truffle compile
发射试验:truffle test ./test/TokenCrowdsale.test.js
通过cmd:ganache-cli启动ganache-cli
编译:truffle compile
迁移:truffle migrate
使用控制台:truffle console
松露控制台中的命令:
- TokenSPC.deployed().then(instance => token = instance)
- TokenCrowdsale.deployed().then(instance => crowdsale = instance)
- web3.eth.getAccounts().then(function(acc){ accounts = acc })
- var tokenamount = 100 * 10**18
- token.transfer(accounts[1], tokenamount.toString())
- crowdsale.buyTokens(accounts[1], { from: accounts[1], value: 10000000000000000000 })Crowdsale合同有一个固定的totalSupply,我不想要任何造币券。因此,我希望众包完成交易,购买令牌并将其转移给用户。



truffle version):v5.1.20node --version):v12.16.1npm --version):v6.13.4我正在学习DappUniversity : Real Ico的教程,以帮助我构建智能契约功能。我做了很多关于我遇到的错误的研究,并且几乎每次都能找到一个解决方案。但是VM错误是垃圾,什么都没说。而且,我没有发现任何类似我的问题。只有一个话题指出了这样一个事实:大多数情况下,如果不是汽油问题,那是因为我们没有任何令牌可买,这对我来说是正确的。我真的认为这是因为我在众筹中没有任何totalSupply,所以他不能买/转/等等.我被困住了,因为我找不到一个教程或主题来解释如何有固定的总供给。事实上,我的处境有一个问题,就是这个话题:
但是他在大众销售合同的帮助下创造了象征性的合同,而我也不想这样做。我需要找到一种将totalSupply从令牌合同转移到众包合同的方法,并使用松露测试来测试它。
非常感谢你的帮助偷窥!
发布于 2020-05-13 10:45:13
您的集体销售合同没有任何代币可转让给买方。
您可以在测试文件中传输令牌契约的所有权,但是总供应量仍然控制着令牌契约部署器地址。从外观上看,它应该是您的帐户0。
在实例化了两个合同之后,您将需要执行如下操作:
await this.token.transfer(desiredAmountOfTokens, this.crowdsale.address)
发布于 2020-05-15 14:33:39
是的,我很确定这是因为你说我的销售合同没有供应。我本来希望从Token.sol script合同中进行转换,但实际上,我需要在测试脚本中完成吗?所以我不能让它成为一个自动的?我将需要手动转移供应从令牌到众销售后,他们的部署?
非常感谢你抽出时间来!
https://ethereum.stackexchange.com/questions/83178
复制相似问题