Rückerstattungsfunktion in Solidity Smart Contract funktioniert nicht

Ich versuche, einen HelloWorld-Smart-Vertrag zu implementieren, um 1:1 Ether in einen Token (in Guthaben gespeichert) und umgekehrt umzuwandeln - ich kann die Bezahlfunktion aufrufen und alles funktioniert gut, aber die Rückerstattungsfunktion funktioniert nicht. Obwohl Ether und Token (in Guthaben gespeichert) vom Vertrag abgezogen werden, werden Ether nicht an den Anrufer zurückgeschickt, wenn die Rückerstattung aufgerufen wird – sie verschwinden also. Ich arbeite am Reopten-Testnetz:

Wie Sie sehen können, hat der Vertrag derzeit 0,0088 Ether, weil ich die Rückerstattung zweimal mit 0,0011 angerufen habe, aber wie Sie sehen können, sendet der Vertrag keine Ether - also verschwinden sie

https://ropsten.etherscan.io/address/0xaa394f1d64d6193b3189826a7b58e40a56703227

Sie können auch sehen, dass es zwei Anrufe zur Rückerstattung von einer Adresse gab, an die keine Ether überwiesen wurden ...

https://ropsten.etherscan.io/address/0x90a700898b596115c03bb9b99b639ad811d792ff

Was mache ich falsch?

pragma solidity ^0.4.23;

contract EtherSwap {
mapping(address => uint) balances;

/* Define variable owner of the type address */
address owner;

/* This function is executed at initialization and sets the owner of the contract */
constructor() public { 
    owner = msg.sender; 
}

function() public payable {
    balances[msg.sender] += msg.value;
}   

function query() public constant returns (uint balance) {
    return balances[msg.sender];
}

function query(address id) public constant returns (uint balance) {
    return balances[id];
}

function refund(uint amountRequested) public {
    require(amountRequested > 0 && amountRequested <= balances[msg.sender]);

    balances[msg.sender] -= amountRequested;

    msg.sender.transfer(amountRequested);
}

/* Function to recover the funds on the contract */
function kill() public { if (msg.sender == owner) selfdestruct(owner); }

}

RAW-Rückerstattungstransaktion:

{"nonce":"0x19","gasPrice":"0x098bca5a00","gasLimit":"0x923a","to":"0xAA394f1d64D6193B3189826A7B58e40a56703227","value":"0x00","data":"0x278ecde10000000000000000000000000000000000000000000000000003e871b540c000"," Ketten-ID":3}

Unterzeichnete Rückerstattungstransaktion:

{"from":"0x90a700898b596115c03bb9b99b639ad811d792ff","nonce":"0x19","gasPrice":"0x098bca5a00","gasLimit":"0x923a","to":"0xAA394f1d64D6193B3189826A7B58e40a567032270","value":" data":"0x278ecde10000000000000000000000000000000000000000000000003e871b540c000","chainId":3}

ABI:

[{"constant":false,"inputs":[{"name":"amountRequested","type":"uint256"}],"name":"refund","outputs":[],"payable" :false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"query","outputs":[{"name ":"balance","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs": [],"name":"kill","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"input":[{"name":"id","type":"address"}],"name":"query","outputs":[{"name":"balance","type":" uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"inputs":[],"payable":false,"stateMutability":"nonpayable", "type":"constructor"},{"payable":true,"stateMutability":"payable","type":"fallback"}]view","type":"function"},{"inputs":[],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"payable":true, "stateMutability":"payable","type":"fallback"}]view","type":"function"},{"inputs":[],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"payable":true, "stateMutability":"payable","type":"fallback"}]

Antworten (2)

Nebenbei können Sie das vereinfachen und ein wenig Standardkonformität hinzufügen, was in Debugging-Situationen nützlich sein kann.

Entferne das

function query() public constant returns (uint balance) {
    return balances[msg.sender];
}

function query(address id) public constant returns (uint balance) {
    return balances[id];
}

und fügen Sie publichinzu mapping(address => uint) public balances;Sie erhalten eine "kostenlose" Getter-Funktion namens balances(address). Sie erhalten nicht die ausgefallene Überlastung, aber Sie brauchen sie nicht wirklich, damit ein Client nach sich selbst fragt.

Sie können Ereignisprotokolle hinzufügen

event LogDeposit(address sender, uint amount);
event LogRefund(address receiver, uint amount);

(nachdem das Mapping "normal" wäre).

Dann könnten Sie Ihr Fallback ein wenig aktualisieren (es gibt gerade genug Gas).

function() public payable {
    balances[msg.sender] += msg.value;
    LogDeposit(msg.sender, msg.value);
} 

Und die andere zustandsändernde Funktion:

function refund(uint amountRequested) public returns(bool success) {
    require(amountRequested > 0);
    require(amountRequested <= balances[msg.sender]);
    balances[msg.sender] -= amountRequested;
    LogRefund(msg.sender, amountRequested);
    msg.sender.transfer(amountRequested);
    return true;
}

Ich habe mir die Freiheit genommen, das requireup in zwei Blöcke aufzuteilen und einen bool zurückzugeben. Nur ein paar Ideen, die Ihnen und anderen bei der Fehlerbehebung helfen können.

Ich hoffe es hilft.

Ich habe gerade herausgefunden, dass Sie die Transaktion als "interne Transaktionen" auf Etherscan sehen können - das bedeutet, dass alles so funktioniert, wie es sollte

Mehr zu "internen Transaktionen" finden Sie hier