Ich sende ETH im Rinkeby-Netzwerk von meiner Brieftasche in Metamask zu einem Vertrag, der auf Rinkeby bereitgestellt wurde. Dies ist ein Crowdsale-Vertrag , der auf Open Zeppelin basiert .
Wenn ich jedoch die Transaktionsdetails auf Etherscan überprüfe, erhalte ich die folgende Fehlermeldung:
TxReceipt-Status: Fehlgeschlagen
Wie finde ich das Problem heraus?
Die vorgeschlagene Gasmenge von Metamask ist immer ungewöhnlich hoch, wenn die Transaktion fehlschlagen soll ...
ETH wurde zum TestTokenSale.sol
Vertrag geschickt.
Rinkeby-Transaktion: 0xbbcff212c72e201412a3c4f4304d13e517212b793f04ae597399d2f375052b36
geth debug.traceTransaction: [Gist]
Der TestToken.sol
wird zuerst bereitgestellt, gefolgt vonTestTokenSale.sol
TestToken.sol
Konstruktorargumente:'qwe', 'qwe, 'qwe', 123
pragma solidity ^0.4.15;
import "./libs/zeppelin/token/MintableToken.sol";
contract TestToken is MintableToken {
string public name;
string public symbol;
uint8 public constant decimals = 18;
string public constant version = "1.0";
string public location;
uint8 public power;
uint256 public constant tokenUnit = 10 ** 18;
function TestToken(string _name, string _symbol, string _location, uint8 _power) {
name = _name;
symbol = _symbol;
location = _location;
power = _power;
}
}
TestTokenSale.sol
Konstruktorargumente:1520889758, 1530889758, 500, 10000000, 0xcede48d8ac162d1b08ed9419010de3c99f2cfdd6, 0x37b925b6c72cc313bea41b95629b74478d9d442b
pragma solidity ^0.4.15;
import "./libs/zeppelin/crowdsale/CappedCrowdsale.sol";
import "./libs/zeppelin/crowdsale/FinalizableCrowdsale.sol";
import './TestToken.sol';
contract TestTokenSale is CappedCrowdsale, FinalizableCrowdsale {
address public tokenContractAddress;
function TestTokenSale(uint256 _startTime, uint256 _endTime, uint256 _rate, uint256 _cap, address _wallet, address _tokenContractAddress)
CappedCrowdsale(_cap)
FinalizableCrowdsale()
Crowdsale(_startTime, _endTime, _rate, _wallet)
{
tokenContractAddress = _tokenContractAddress;
}
function createTokenContract(address tokenContractAddress) internal returns (MintableToken) {
return TestToken(tokenContractAddress);
}
function finalization() internal {
}
}
ETH senden an TestTokenSale.sol
schlägt immer noch fehl ...
Tx: 0x640771750ded31c0ef817d1e0df3a1ec16c186fd353a6034dd1799af26e486ed
TestTokenSale.sol
Konstruktorargumente:1511235849, 1530889758, 500, 10000000, 0xcede48d8ac162d1b08ed9419010de3c99f2cfdd6, 0x47a27fb4722f293b7ab499ef910d1f2ca78b94b6
pragma solidity ^0.4.15;
import "./libs/zeppelin/crowdsale/CappedCrowdsale.sol";
import "./libs/zeppelin/crowdsale/FinalizableCrowdsale.sol";
import './TestToken.sol';
contract TestTokenSale is CappedCrowdsale, FinalizableCrowdsale {
address public tokenContractAddress;
function TestTokenSale(uint256 _startTime, uint256 _endTime, uint256 _rate, uint256 _cap, address _wallet, address _tokenContractAddress)
CappedCrowdsale(_cap)
FinalizableCrowdsale()
Crowdsale(_startTime, _endTime, _rate, _wallet)
{
token = TestToken(_tokenContractAddress);
}
function finalization() internal {
}
}
Tx: 0x561f9cb4630905c2bb1391db3d3d1afd3b29cc454b238b25dbc3372f19c4a274
ETH sendet nur dann erfolgreich an den TestTokenSale.sol
Vertrag, wenn Crowdsale.sol
bearbeitet wurde, um auszukommentieren require(validPurchase())
:
Code funktioniert
function buyTokens(address beneficiary) public payable {
require(beneficiary != address(0));
// require(validPurchase());
...
Code schlägt fehl
Das Senden von ETH schlägt fehl, wenn ich diese Zeile nicht auskommentiere, sondern validPurchase()
auf setze return true
:
function buyTokens(address beneficiary) public payable {
require(beneficiary != address(0));
require(validPurchase());
...
function validPurchase() internal constant returns (bool) {
return true;
// bool withinPeriod = now >= startTime && now <= endTime;
// bool nonZeroPurchase = msg.value != 0;
// return withinPeriod && nonZeroPurchase;
}
Code funktioniert!!!
// low level token purchase function
function buyTokens(address beneficiary) public payable {
require(beneficiary != address(0));
require(now >= startTime);
require(now <= endTime);
require(msg.value != 0);
// require(validPurchase());
Sollten require(validPurchase())
keine Fehler ausgegeben werden, wenn validPurchase()
zurückgegeben wird true
?
Warum funktioniert es, wenn die 3 Bedingungen von validPurchase()
out nach verschoben werden buyTokens
, aber nicht funktionieren, wenn sie in `validPurchase()~ stehen?
Was passiert hier?
Wir hatten einige der gleichen Probleme wie du. Was wir herausgefunden haben, war Folgendes:
startTime
und endTime
muss so eingestellt sein, dass Sie beim Aufrufen des Kontrakts tatsächlich Token kaufen, wenn der Verkauf offen ist. Wir haben eine hasStarted()
Methode hinzugefügt und sowohl diese als auch die hasEnded()
Methode aufgerufen, um sicherzustellen, dass wir uns tatsächlich innerhalb des Verkaufszeitraums befinden.startTime
muss in der Zukunft liegen. Ist dies nicht der Fall, wird nichts funktionieren. Aus diesem Grund addieren wir 90 Sekunden zum aktuellen Zeitstempel hinzu.accounts[0]
im Konstruktor senden – die Adresse muss eine Zeichenfolge sein, wenn sie aus der Migrationsdatei aufgerufen wird.25
) einsenden, da rate
- es eine sein muss web3.BigNumber(25)
.Als Referenz finden Sie hier unsere Migrationsdatei: 2_deploy_contracts.js
var MyTokenCrowdsale = artifacts.require("MyTokenCrowdsale");
module.exports = function(deployer, network, accounts) {
const start = web3.eth.getBlock(web3.eth.blockNumber).timestamp + 90;
const end = start + (86400 * 30); // 30 days
const rate = new web3.BigNumber(25);
wallet = accounts[1].toString();
deployer.deploy(MyTokenCrowdsale, start, end, rate, wallet);
};
web3.BigNumber
statt einer regulären int
für die bestanden?rate
web3.BigNumber
und nicht eine ist int
.Wenn man sich den Vertragscode ansieht, kann man sehen, dass der Vertrag Ether nur während des Zeitraums akzeptiert, in dem der Token-Verkauf stattfindet. Wenn Sie Ether außerhalb dieses Zeitraums senden, wird der Vertrag die Ausführung unterbrechen und Ihren Ether zurückgeben (dh was nach der Zahlung des Gases übrig ist, das für die Ausführung des Vertrags bis zu diesem Zeitpunkt erforderlich ist).
Der Zeitraum des Token-Verkaufs wird bei der Vertragserstellung durch Parameter _starttime
und _endtime
vom Konstruktor festgelegt. Ich habe mir den Vertragsspeicher nicht angesehen, um zu überprüfen, welche Werte für _starttime
und festgelegt wurden _endtime
. Sie könnten jedoch an dieser Stelle mit der Fehlersuche beginnen und überprüfen, ob angemessene Werte für _starttime
und _endtime
bei der Vertragserstellung festgelegt wurden.
_startTime
und liegt _endTime
. Aber die Transaktion ist trotzdem fehlgeschlagen..._startTime=1511127652
, _endTime=1530889758
und die Zeit, zu der ich die ETH an den Vertrag gesendet habe, war 1511127656
nach unixtimestamp.com/index.phpbuyTokens
Funktion, und token.mint(beneficiary, tokens);
es scheint die Zeile zu sein, die dazu führt, dass der ETH-Sendevorgang fehlschlägt!MintableToken
wurde getrennt vom Crowdsale
Vertrag bereitgestellt, ich frage mich, ob dies ein Problem mit der mint
Funktion mit den Modifikatoren verursacht onlyOwner canMint
, vielleicht ist der Crowdsale-Vertrag nicht der Eigentümer des MintableToken
?transferOwnership
, um das Eigentum an dem MintableToken
auf den Crowdsale
Vertrag zu übertragen, und überprüfte, ob das owner
Eigentum an MintableToken
der Adresse des Crowdsale
Vertrags ist. Das token.mint(beneficiary, tokens);
Senden von ETH an den Crowdsale
Vertrag scheitert jedoch immer noch ...
Ismael
Athene Weisheit
0xbbcff212c72e201412a3c4f4304d13e517212b793f04ae597399d2f375052b36
. Sehen Sie etwas falsch mit dem Vertragscode?Ismael
Ismael
Crowdsale()
die wiederum aufrufencreateTokenContract()
, was zurückgeben wirdTestToken(tokenContractAddress)
, aber es wird 0x0 zurückgeben, datokenContractAddress
es noch nicht initialisiert ist. Variable löschentokenContractAddress
und direkt in Ihrem Konstruktor zuweisentoken = MintableToken(_tokenContractAddress);
Athene Weisheit
createTokenContract
?Athene Weisheit
Ismael
mint()
aufgerufen wird,buyTokens()
aber es istonlyOwner
so, dass Sie den Crowdsale als Besitzer des Tokens festlegen müssen, aber ich denke nicht, dass das hier der Fehler ist.Athene Weisheit
require(validPurchase());
in der FunktionbuyTokens
vonCrowdsale.sol
... auskommentieren. Das BearbeitenvalidPurchase
von führte dazu,return true
dass der ETH-Versand auch fehlschlug ... Das ist so seltsam?Athene Weisheit