Warum erhalte ich: Transaktionsfehler. Ausnahme im Vertragscode in Rinkeby geworfen?

Ich erstelle einen Token, der jedes Mal neue Token generiert, wenn ETH an ihn gesendet wird. Es nimmt diese neu generierten Token und sendet sie an die Wallet-Adresse, die die ETH gesendet hat. Die maxTokens beträgt 40 Millionen. Die RATE ist 20mil (ich versuche, die Dinge für meinen Test einfach zu halten). Es ist ziemlich einfach.

Das Problem, auf das ich bei meinem Testvertrag stoße, ist, dass der Versuch, 1 ETH zu senden, in Ordnung ist und die Transaktion durchgeführt wird. Der Versuch, einen größeren Betrag zu senden, z. B. 1,5, erzeugt diese Warnung: „Transaktionsfehler. Ausnahme im Vertragscode ausgelöst. Gaslimit gefährlich hoch eingestellt. Die Genehmigung dieser Transaktion wird wahrscheinlich fehlschlagen.“

Nachdem ich eine Weile herumgespielt hatte, wurde mir klar, dass ich kleinere Mengen an ETH senden könnte, die nach dem Senden der 1ETH durchgehen würden. Je näher ich jedoch den maximalen Token kam, desto mehr wurde der oben erwähnte Fehler angezeigt.

Kann mir jemand erklären, warum ich diesen Fehler bekomme? Ich kann nicht verstehen, warum ein Fehler erzeugt wird, wenn jemand eine ETH-Menge sendet, die relativ nahe an den maxTokens liegt.

Bearbeiten: Ich konnte erfolgreich bis zu 39.999.700 der Token kaufen. Allerdings muss ich jedes Mal kleinere Mengen kaufen, sonst bekomme ich die oben genannten Fehler.

pragma solidity ^0.4.11;

import './IERC20.sol';
import './SafeMath.sol';

contract ChekOutToken is IERC20 {

using SafeMath for uint256;

uint public _totalSupply = 0;

string public constant symbol = "CHEKS";
string public constant name = "ChekOut Token";
uint8 public constant decimals = 18;

// 1 ETH = 1000 CHEKS
uint256 public constant RATE = 20000000;

// Sets Maximum Tokens to be Created
uint256 public constant maxTokens = 40000000000000000000000000;

address public owner;

mapping (address => uint256) public balances;
mapping(address => mapping(address => uint256)) allowed;

function () payable{
    createTokens();
}

function ChekOutToken(){
    owner = msg.sender;
}

function createTokens() payable{
    require(msg.value > 0);
    require(_totalSupply.add(tokens) <= maxTokens);
    uint256 tokens = msg.value.mul(RATE);
    balances[msg.sender] = balances[msg.sender].add(tokens);
    _totalSupply = _totalSupply.add(tokens);
    owner.transfer(msg.value);
    require(_totalSupply.add(tokens) <= maxTokens);
}

function totalSupply() public constant returns (uint256 totalSupply) {
    return _totalSupply;
}

function balanceOf(address _owner) public constant returns (uint256 balance) {
    return balances[_owner];
}

function transfer(address _to, uint256 _value) public returns (bool success) {
    require(balances[msg.sender] >= _value && _value > 0);
    balances[msg.sender] = balances[msg.sender].sub(_value);
    balances[_to] = balances[_to].add(_value);
    Transfer(msg.sender, _to, _value);
    return true;
}

function transferFrom(address _from, address _to, uint256 _value) public returns (bool success) {
    require(allowed[_from][msg.sender] >= _value && balances[_from] >= _value && _value > 0);
    balances[_from] = balances[msg.sender].sub(_value);
    balances[_to] = balances[_to].add(_value);
    allowed[_from][msg.sender] = allowed[_from][msg.sender].sub(_value);
    Transfer(_from, _to, _value);
    return true;
}

function approve(address _spender, uint256 _value) public returns (bool success) {
    allowed[msg.sender][_spender] = _value;
    Approval(msg.sender, _spender, _value);
    return true;
}

function allowance(address _owner, address _spender) public constant returns (uint256 remaining) {
    return allowed[_owner][_spender];
}

event Transfer(address indexed _from, address indexed _to, uint256 _value);

event Approval(address indexed _owner, address indexed _spender, uint256 _value);

}

Antworten (1)

Ich sehe zwei Probleme, und ich denke, das zweite ist die Quelle Ihres Fehlers:

function createTokens() payable{
    require(msg.value > 0);
    require(_totalSupply.add(tokens) <= maxTokens);
    uint256 tokens = msg.value.mul(RATE);
    balances[msg.sender] = balances[msg.sender].add(tokens);
    _totalSupply = _totalSupply.add(tokens);
    owner.transfer(msg.value);
    require(_totalSupply.add(tokens) <= maxTokens);
}

Die Linie require(_totalSupply.add(tokens) <= maxTokens);kommt zweimal vor. Jedes Mal ist problematisch:

  1. Beim ersten Mal tokenswurde noch kein Wert zugewiesen. (Ich war überrascht, dass dies sogar kompiliert wurde, aber anscheinend werden Variablendeklarationen gehisst?) Das überprüft also das Hinzufügen von 0, was nicht das tut, was Sie wollen.
  2. Beim zweiten Mal haben Sie bereits tokenszu hinzugefügt _totalSupply, also überprüfen Sie effektiv "Kann ich tokenszweimal hinzufügen und trotzdem unter bleiben maxTokens?"

requireIch würde die Funktion reparieren, indem ich das frühere nach der Berechnung von verschiebe und das am Ende tokensloswerde :require

function createTokens() payable{
    require(msg.value > 0);
    uint256 tokens = msg.value.mul(RATE);
    require(_totalSupply.add(tokens) <= maxTokens);
    balances[msg.sender] = balances[msg.sender].add(tokens);
    _totalSupply = _totalSupply.add(tokens);
    owner.transfer(msg.value);
}
Du hast es gelöst! Es funktioniert jetzt gut. Vielen Dank für den Hinweis auf die doppelte Verwendung der require-Funktion. Ich fühle mich albern, weil ich dachte, ich hätte den ersten gelöscht, aber offensichtlich nicht ...