我正在测试Crowdsale合同(C),它发送已经部署的合同(T)的令牌。这个想法是从T向C发送大量的令牌,然后将它们卖给以太,但是没有什么效果,C甚至没有收到以太。这是Crowdsale合同:
pragma solidity ^0.4.13;
contract ForeignToken {
function balanceOf(address _owner) constant returns (uint256);
function transfer(address _to, uint256 _value) returns (bool);
}
library SafeMath {
function mul(uint256 a, uint256 b) internal constant returns (uint256) {
uint256 c = a * b;
assert(a == 0 || c / a == b);
return c;
}
function div(uint256 a, uint256 b) internal constant returns (uint256) {
uint256 c = a / b;
return c;
}
function sub(uint256 a, uint256 b) internal constant returns (uint256) {
assert(b <= a);
return a - b;
}
function add(uint256 a, uint256 b) internal constant returns (uint256) {
uint256 c = a + b;
assert(c >= a);
return c;
}
}
contract Token {
function issue(address _recipient, uint256 _value) returns (bool success);
function totalSupply() constant returns (uint256 supply);
function unlock() returns (bool success);
}
contract TokenCrowdsale {
using SafeMath for uint256;
// Crowdsale details
address public beneficiary;
address public creator;
address public confirmedBy;
uint256 public maxSupply = 15000000e8;
uint256 public minAcceptedAmount = 10 finney;
bool public purchasingAllowed = false;
// Eth to token rate
uint256 public rate = 2000;
enum Stages {
PreSale,
InProgress,
Ended,
Withdrawn
}
Stages public stage = Stages.PreSale;
// deployed token
Token public deplToken;
// Invested balances
mapping (address => uint256) balances;
/**
* Throw if at stage other than current stage
*
* @param _stage expected stage to test for
*/
modifier atStage(Stages _stage) {
require(stage == _stage);
_;
}
/**
* Throw if sender is not beneficiary
*/
modifier onlyBeneficiary() {
require(beneficiary == msg.sender);
_;
}
/**
* Get balance of `_investor`
*
* @param _investor The address from which the balance will be retrieved
* @return The balance
*/
function balanceOf(address _investor) constant returns (uint256 balance) {
return balances[_investor];
}
function enablePurchasing() onlyBeneficiary atStage(Stages.PreSale) {
purchasingAllowed = true;
stage = Stages.InProgress;
}
function disablePurchasing() onlyBeneficiary atStage(Stages.InProgress) {
purchasingAllowed = false;
stage = Stages.Ended;
}
function enableNewPurchasing() onlyBeneficiary atStage(Stages.Withdrawn) {
purchasingAllowed = true;
stage = Stages.InProgress;
}
/**
* Constructor
*
* @param _tokenAddress The address of the token contact
* @param _beneficiary The address of the wallet for the beneficiary
* @param _creator The address of the wallet for the creator
*/
function TokenCrowdsale(address _tokenAddress, address _beneficiary, address _creator) {
deplToken = Token(_tokenAddress);
beneficiary = _beneficiary;
creator = _creator;
}
/**
* For testing purposes
*
* @return The beneficiary address
*/
function confirmBeneficiary() onlyBeneficiary {
confirmedBy = msg.sender;
}
/**
* Transfer raised amount to the beneficiary address
*/
function withdraw() onlyBeneficiary atStage(Stages.Ended) {
uint256 ethBalance = this.balance;
beneficiary.transfer(ethBalance);
stage = Stages.Withdrawn;
}
/**
* Receives Eth and issue tokens to the sender
*/
function () payable atStage(Stages.InProgress) {
require(purchasingAllowed);
address investor = msg.sender;
uint256 received = (msg.value).div(10e8);
// Enforce min amount
require(received >= minAcceptedAmount);
uint256 tokens = (received).mul(rate);
require(tokens > 0);
require(deplToken.issue(investor, tokens));
balances[investor] = balances[investor].add(received);
//raised += received;
// Check totalSupply raised
if (deplToken.totalSupply() >= maxSupply) {
stage = Stages.Ended;
}
}
function withdrawForeignTokens(address _tokenContract) onlyBeneficiary public returns (bool) {
ForeignToken token = ForeignToken(_tokenContract);
uint256 amount = token.balanceOf(address(this));
return token.transfer(beneficiary, amount);
}
}任何帮助都很感谢,谢谢。
编辑:根据注释中的建议,我成功地收到了Crowdsale合同上的ETH,但它没有发出令牌。下面是代码:
pragma solidity ^0.4.13;
contract ForeignToken {
function balanceOf(address _owner) constant returns (uint256);
function transfer(address _to, uint256 _value) returns (bool);
}
library SafeMath {
function mul(uint256 a, uint256 b) internal constant returns (uint256) {
uint256 c = a * b;
assert(a == 0 || c / a == b);
return c;
}
function div(uint256 a, uint256 b) internal constant returns (uint256) {
uint256 c = a / b;
return c;
}
function sub(uint256 a, uint256 b) internal constant returns (uint256) {
assert(b <= a);
return a - b;
}
function add(uint256 a, uint256 b) internal constant returns (uint256) {
uint256 c = a + b;
assert(c >= a);
return c;
}
}
contract Token {
function issue(address _recipient, uint256 _value) returns (bool success);
function totalSupply() constant returns (uint256 supply);
function unlock() returns (bool success);
}
contract TokenCrowdsale {
using SafeMath for uint256;
// Crowdsale details
address public beneficiary;
address public creator;
address public confirmedBy;
uint256 public maxSupply = 15000000e8;
uint256 public minAcceptedAmount = 10 finney;
bool public purchasingAllowed = false;
uint256 public totalSupply = 0;
// Eth to token rate
uint256 public rate = 2000;
enum Stages {
PreSale,
InProgress,
Ended,
Withdrawn
}
Stages public stage = Stages.PreSale;
// deployed token
Token public deplToken;
// Invested balances
mapping (address => uint256) balances;
/**
* Throw if at stage other than current stage
*
* @param _stage expected stage to test for
*/
modifier atStage(Stages _stage) {
require(stage == _stage);
_;
}
/**
* Throw if sender is not beneficiary
*/
modifier onlyBeneficiary() {
require(beneficiary == msg.sender);
_;
}
/**
* Get balance of `_investor`
*
* @param _investor The address from which the balance will be retrieved
* @return The balance
*/
function balanceOf(address _investor) constant returns (uint256 balance) {
return balances[_investor];
}
function enablePurchasing() onlyBeneficiary atStage(Stages.PreSale) {
purchasingAllowed = true;
stage = Stages.InProgress;
}
function disablePurchasing() onlyBeneficiary atStage(Stages.InProgress) {
purchasingAllowed = false;
stage = Stages.Ended;
}
function enableNewPurchasing() onlyBeneficiary atStage(Stages.Withdrawn) {
purchasingAllowed = true;
stage = Stages.InProgress;
}
/**
* Constructor
*
* @param _tokenAddress The address of the token contact
* @param _beneficiary The address of the wallet for the beneficiary
* @param _creator The address of the wallet for the creator
*/
function TokenCrowdsale(address _tokenAddress, address _beneficiary, address _creator) {
deplToken = Token(_tokenAddress);
beneficiary = _beneficiary;
creator = _creator;
}
/**
* For testing purposes
*
* @return The beneficiary address
*/
function confirmBeneficiary() onlyBeneficiary {
confirmedBy = msg.sender;
}
/**
* Transfer raised amount to the beneficiary address
*/
function withdraw() onlyBeneficiary atStage(Stages.Ended) {
uint256 ethBalance = this.balance;
beneficiary.transfer(ethBalance);
stage = Stages.Withdrawn;
}
/**
* Receives Eth and issue tokens to the sender
*/
function () payable atStage(Stages.InProgress) {
require(purchasingAllowed);
if (msg.value >= 10 finney) {
address investor = msg.sender;
uint256 received = (msg.value).div(10e8);
uint256 tokens = (received).mul(rate);
balances[investor] = balances[investor].add(tokens);
totalSupply = (totalSupply).add(tokens);
}
if (totalSupply >= maxSupply) {
purchasingAllowed = false;
stage = Stages.Ended;
}
}
function withdrawForeignTokens(address _tokenContract) onlyBeneficiary public returns (bool) {
ForeignToken token = ForeignToken(_tokenContract);
uint256 amount = token.balanceOf(address(this));
return token.transfer(beneficiary, amount);
}
}如您所见,我用"if“迭代更改了回退函数中的"require”。
发布于 2017-11-23 22:40:22
遵循这些建议,做更多的研究,我找到了解决办法。首先,我改变了
contract Token {}至
interface Token {}我还添加了一个事件,然后由fallback函数调用该事件来发送令牌:
event sendTokens(address indexed to, uint256 value);最后,我清理了未使用变量的代码,并添加了一些与我的问题无关的其他函数,但是对于管理众包很有用。下面是最后的工作代码:
pragma solidity ^0.4.13;
contract ForeignToken {
function balanceOf(address _owner) constant returns (uint256);
function transfer(address _to, uint256 _value) returns (bool);
}
library SafeMath {
function mul(uint256 a, uint256 b) internal constant returns (uint256) {
uint256 c = a * b;
assert(a == 0 || c / a == b);
return c;
}
function div(uint256 a, uint256 b) internal constant returns (uint256) {
uint256 c = a / b;
return c;
}
function sub(uint256 a, uint256 b) internal constant returns (uint256) {
assert(b <= a);
return a - b;
}
function add(uint256 a, uint256 b) internal constant returns (uint256) {
uint256 c = a + b;
assert(c >= a);
return c;
}
}
interface Token {
function transfer(address _to, uint256 _value) returns (bool);
function totalSupply() constant returns (uint256 supply);
function balanceOf(address _owner) constant returns (uint256 balance);
}
contract TokenCrowdsale {
using SafeMath for uint256;
// Crowdsale details
address public beneficiary;
address public creator;
address public confirmedBy;
uint256 public maxSupply = 15000000e8;
bool public purchasingAllowed = false;
uint256 public totalSupplied = 0;
// Eth to token rate
uint256 public rate = 2000;
enum Stages {
PreSale, //0
InProgress, //1
Ended, //2
Withdrawn //3
}
Stages public stage = Stages.PreSale;
// deployed token
Token public deplToken;
// Invested balances
mapping (address => uint256) balances;
/**
* Throw if at stage other than current stage
*
* @param _stage expected stage to test for
*/
modifier atStage(Stages _stage) {
require(stage == _stage);
_;
}
/**
* Throw if sender is not beneficiary
*/
modifier onlyBeneficiary() {
require(beneficiary == msg.sender);
_;
}
/**
* Get balance of `_investor`
*
* @param _investor The address from which the balance will be retrieved
* @return The balance
*/
function balanceOf(address _investor) constant returns (uint256 balance) {
return balances[_investor];
}
function enablePurchasing() onlyBeneficiary atStage(Stages.PreSale) {
purchasingAllowed = true;
stage = Stages.InProgress;
}
function disablePurchasing() onlyBeneficiary atStage(Stages.InProgress) {
purchasingAllowed = false;
stage = Stages.Ended;
}
function enableNewPurchasing() onlyBeneficiary atStage(Stages.Withdrawn) {
purchasingAllowed = true;
stage = Stages.InProgress;
}
/**
* Constructor
*
* @param _tokenAddress The address of the token contact
* @param _beneficiary The address of the wallet for the beneficiary
* @param _creator The address of the wallet for the creator
*/
function TokenCrowdsale(address _tokenAddress, address _beneficiary, address _creator) {
deplToken = Token(_tokenAddress);
beneficiary = _beneficiary;
creator = _creator;
}
/**
* For testing purposes
*
* @return The beneficiary address
*/
function confirmBeneficiary() onlyBeneficiary {
confirmedBy = msg.sender;
}
event sendTokens(address indexed to, uint256 value);
/**
* Transfer raised amount to the beneficiary address
*/
function withdraw() onlyBeneficiary atStage(Stages.Ended) {
uint256 ethBalance = this.balance;
beneficiary.transfer(ethBalance);
stage = Stages.Withdrawn;
}
/**
* Receives Eth and issue tokens to the sender
*/
function () payable atStage(Stages.InProgress) {
require(purchasingAllowed);
if (msg.value == 0) { return; }
uint256 weiAmount = msg.value;
address investor = msg.sender;
uint256 received = weiAmount.div(10e7);
uint256 tokens = (received).mul(rate);
if (msg.value >= 10 finney) {
uint256 bonusToken = (tokens.div(100)).mul(20);
tokens = tokens.add(bonusToken);
}
sendTokens(msg.sender, tokens);
deplToken.transfer(investor, tokens);
totalSupplied = (totalSupplied).add(tokens);
if (totalSupplied >= maxSupply) {
purchasingAllowed = false;
stage = Stages.Ended;
}
}
function tokensAvailable() constant returns (uint256) {
return deplToken.balanceOf(this);
}
function withdrawForeignTokens(address _tokenContract) onlyBeneficiary public returns (bool) {
ForeignToken token = ForeignToken(_tokenContract);
uint256 amount = token.balanceOf(address(this));
return token.transfer(beneficiary, amount);
}
}我不确定“接口令牌”或“事件sendTokens”是否是解决方案,但它现在正在工作;我可以发送以太并接收已部署的令牌。我已经回答了我自己的问题,所以如果其他人需要这样的东西,它将留在这里作为解决方案。谢谢
https://ethereum.stackexchange.com/questions/31409
复制相似问题