Ich habe ein Problem, wenn ich die Funktion selectWinner() aufrufe und etwas Ether damit sende, um für Oraclize zu bezahlen. Ich verwende Rinkeby mit Infura und Metamask für die Testkonten. Ich erhalte eine Fehlermeldung in der Metamaske, die besagt:
Transaktionsfehler. Ausnahme im Vertragscode ausgelöst.
Und dann schlägt die Transaktion fehl.
pragma solidity ^0.4.23;
contract Lottery is usingOraclize {
uint lotteryFee = 0.1 ether;
uint8 counter = 0;
address[10] participants;
mapping (address => bool) checkParticipant;
address public owner;
bytes32 public oraclizeID;
uint public winnerNumber;
modifier onlyOnce() {
require(checkParticipant[msg.sender] == false);
_;
}
function participate() external payable onlyOnce returns(address) {
require(msg.value == lotteryFee);
checkParticipant[msg.sender] = true;
counter = counter + 1;
participants[counter] = msg.sender;
return(participants[counter]);
}
function getBalance() public view returns (uint) {
uint contractBalance = address(this).balance;
return(contractBalance);
}
function selectWinner() payable public {
oraclizeID = oraclize_query("WolframAlpha", "random number between 1 and 10");
}
function __callback(bytes32 _oraclizeID, string _result){
if(msg.sender != oraclize_cbAddress()) throw;
testString = _result;
winnerNumber = parseInt(_result);
uint maxRange = counter;
uint randomNumber = uint(sha3(_result)) % maxRange;
}
function payTheReward() external returns(address){
address winnerAddress = participants[winnerNumber];
uint currentBalance = getBalance();
winnerAddress.transfer(currentBalance);
deleteParticipants();
return (winnerAddress);
}
function deleteParticipants() internal {
uint8 a = counter;
for(uint8 i = 0; i < a; i++) {
checkParticipant[participants[i]] = false;
participants[i] = 0;
}
counter = 0;
}
}
Ich verwende Javascript, um es aufzurufen:
selectTheWinner: function(){
App.contractInstance.selectWinner(
{ from: App.account,
value: App.web3.toWei(0.1, "ether")
}
).then(function(addr){ console.log(addr)})
.catch(function(error){ console.log(error); });
Meine Vertragsnummer lautet:0xFD05EE7F1660fcaDF5BB618cA5b09e6C564F99cF
Ihr Vertrag wird nicht einmal kompiliert. Sie müssen zuerst den nicht deklarierten Bezeichner testString
unter der __callback-Funktion entfernen.
Zweitens unterstützt Oraclize nur bis Solc 0.4.20, da es in Versionen, die höher sind, vertragsbrechende Fehler gibt/möglicherweise gibt, ist dies eine weitere Änderung, die Sie vornehmen möchten.
Nachdem Sie die folgenden Änderungen vorgenommen hatten, funktionierte Ihr Vertrag für mich einwandfrei, indem Sie 2 Benutzer teilnehmen ließen und dann selectWinner anriefen, die 1 als Zufallszahl von WA zurückgeben.
Sie werden wahrscheinlich zusätzliche Überprüfungen/Modifikatoren für selectWinner wünschen, da jemand mit dieser Funktion die Gelder des Vertrags abziehen könnte.
Wenn du sagst
Ich habe ein Problem, wenn ich die Funktion aufrufe,
Welche Funktion rufst du auf und sendest Wert an? function selectWinner()
verwendet address(this).balance
, um für die Abfrage zu bezahlen.
function participate()
wird msg.value
ergänzen address(this).balance
.
Versuchen Sie vielleicht, einige Protokolle vor der Abfrage hinzuzufügen, wie in der Oraclize-Dokumentation beschrieben:
if (oraclize_getPrice("URL") > this.balance) {
LogNewOraclizeQuery("Oraclize query was NOT sent, please add
some ETH to cover for the query fee");
} else {
LogNewOraclizeQuery("Oraclize query was sent, standing by for
the answer..");
oraclize_query(60, "URL", "json(http://api.fixer.io/latest?symbols=USD,GBP).rates.GBP");
}
bhalgalix
DenisM
bhalgalix