Solidity

Solidity 智能合約中的退款功能不起作用

  • May 1, 2018

我正在嘗試實現一個 HelloWorld 智能合約,將 1:1 乙太幣更改為令牌(儲存在餘額中),反之亦然 - 我可以呼叫支付功能,一切正常,但退款功能不起作用。儘管從合約中扣除了乙太幣和代幣(儲存在餘額中),但當呼叫退款時,乙太幣不會被發送回呼叫者 - 所以它們會消失。我正在研究 Reopten 測試網:

所以你可以看到合約目前有 0.0088 乙太幣,因為我已經用 0.0011 呼叫了兩次退款,但是你可以看到合約沒有發送乙太幣 - 所以它們消失了

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

您還可以看到,從一個沒有乙太幣轉移到的地址收到了兩次退款電話……

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

我究竟做錯了什麼?

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退款交易:

{“隨機數”:“0x19”,“gasPrice”:“0x098bca5a00”,“gasLimit”:“0x923a”,“為”:“0xAA394f1d64D6193B3189826A7B58e40a56703227”,“值”:“0×00”,“數據”:“0x278ecde10000000000000000000000000000000000000000000000000003e871b540c000”,“鏈ID“:3}

簽署的退款交易:

{“from”:“0x90a700898b596115c03bb9b99b639ad811d792ff”,“nonce”:“0x19”,“gasPrice”:“0x098bca5a00”,“gasLimit”:“0x923a”,“to”:“0xAA394f1d64D6193B31898206A7B5840”,““valuea:“6703A7B5840數據”:“0x278ecde10000000000000000000000000000000000000000000000000003e871b540c000”,“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,“inputs”:[{“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”} $$

剛剛發現您可以在 etherscan 上將交易視為“內部交易”——這意味著一切正常

更多關於“內部交易”的資訊可以在這裡找到

順便說一句,您可以簡化它並添加一些標準一致性,以便在調試情況下使用。

刪除這個

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

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

並添加publicmapping(address => uint) public balances;您將獲得一個名為balances(address). 你不會得到花哨的超載,但你並不真的需要它讓客戶詢問自己。

您可以添加事件日誌

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

(映射後將是“正常”)。

然後你可以稍微更新你的備份(只有足夠的氣體)。

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

還有另一個狀態改變函式:

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;
}

我冒昧地將requireup 分成兩個塊並返回一個 bool。只是一些想法可以幫助您和其他人解決正在發生的事情。

希望能幫助到你。

引用自:https://ethereum.stackexchange.com/questions/47249