嘗試在 erc20 中添加應付功能時出錯
網上大部分的 ERC20 例子都有這個功能:
// ------------------------------------------------------------------------ // Don't accept ETH // ------------------------------------------------------------------------ function () public payable { revert(); }
但是,我想在 Ropsten 上部署一個 ERC20 代幣,使用者可以在其中發送 ETH 並接收我的代幣作為回報所以我嘗試刪除這個函式並將其替換為:
uint public sellPrice =0.5; function setPrices(uint newSellPrice) public onlyOwner { sellPrice = newSellPrice; } function buy(uint256 payload) public payable { uint amount = safeDiv(msg.value, sellPrice); //balances[msg.sender] += amount; //I commented this out cuz im not sure if I need it transferFrom(owner, msg.sender, amount); }
可悲的是,這不起作用..我收到此錯誤:警告!合約執行過程中遇到的錯誤
$$ Reverted $$ 注意:我使用元遮罩發送 Ropsten Ether .. 我沒有放任何十六進制數據(因為我想,因為這是唯一的 paypal 功能,也許我不需要它?)另外,我不知道這個的十六進制數據函式..所以也許是另一個問題,如何獲取未命名函式的十六進制數據?
更新
我已經嘗試了以下建議的解決方案,這是更新後的契約
epragma solidity ^0.4.20; contract SafeMath { function safeAdd(uint a, uint b) public pure returns (uint c) { c = a + b; require(c >= a); } function safeSub(uint a, uint b) public pure returns (uint c) { require(b <= a); c = a - b; } function safeMul(uint a, uint b) public pure returns (uint c) { c = a * b; require(a == 0 || c / a == b); } function safeDiv(uint a, uint b) public pure returns (uint c) { require(b > 0); c = a / b; }
}
contract ERC20Interface { function totalSupply() public view returns (uint); function balanceOf(address tokenOwner) public view returns (uint balance); function allowance(address tokenOwner, address spender) public view returns (uint remaining); function transfer(address to, uint tokens) public returns (bool success); function approve(address spender, uint tokens) public returns (bool success); function transferFrom(address from, address to, uint tokens) public returns (bool success); event Transfer(address indexed from, address indexed to, uint tokens); event Approval(address indexed tokenOwner, address indexed spender, uint tokens);
}
contract ApproveAndCallFallBack { function receiveApproval(address from, uint256 tokens, address token, bytes data) public;
}
contract Owned { address public owner; address public newOwner; event OwnershipTransferred(address indexed _from, address indexed _to); function Owned() public { owner = msg.sender; } modifier onlyOwner { require(msg.sender == owner); _; } function transferOwnership(address _newOwner) public onlyOwner { newOwner = _newOwner; } function acceptOwnership() public { require(msg.sender == newOwner); OwnershipTransferred(owner, newOwner); owner = newOwner; newOwner = address(0); }
}
contract FToken is ERC20Interface, Owned, SafeMath { string public symbol; string public name; uint8 public decimals; uint public _totalSupply; mapping(address => uint) balances; mapping(address => mapping(address => uint)) allowed; function FToken() public { symbol = "fff"; name = "FAdi Token"; decimals = 18; _totalSupply = 1000000000; balances[owner] = _totalSupply; Transfer(address(0), owner, _totalSupply); } function totalSupply() public view returns (uint) { return _totalSupply - balances[address(0)]; } function balanceOf(address tokenOwner) public view returns (uint balance) { return balances[tokenOwner]; } function transfer(address to, uint tokens) public returns (bool success) { balances[msg.sender] = safeSub(balances[msg.sender], tokens); balances[to] = safeAdd(balances[to], tokens); Transfer(msg.sender, to, tokens); return true; } function approve(address spender, uint tokens) public returns (bool success) { allowed[msg.sender][spender] = tokens; Approval(msg.sender, spender, tokens); return true; } function transferFrom(address from, address to, uint tokens) public returns (bool success) { balances[from] = safeSub(balances[from], tokens); allowed[from][msg.sender] = safeSub(allowed[from][msg.sender], tokens); balances[to] = safeAdd(balances[to], tokens); Transfer(from, to, tokens); return true; } function allowance(address tokenOwner, address spender) public constant returns (uint remaining) { return allowed[tokenOwner][spender]; } function approveAndCall(address spender, uint tokens, bytes data) public returns (bool success) { allowed[msg.sender][spender] = tokens; Approval(msg.sender, spender, tokens); ApproveAndCallFallBack(spender).receiveApproval(msg.sender, tokens, this, data); return true; } uint public sellPrice =5; function setPrices(uint newSellPrice) public onlyOwner { sellPrice = newSellPrice; } function buy() public payable returns (bool success) { uint amount = safeMul(msg.value, sellPrice); // calculates the amount //balances[msg.sender] += amount; if (approve(owner, amount)) transferFrom( owner,msg.sender, amount); } function transferAnyERC20Token(address tokenAddress, uint tokens) public onlyOwner returns (bool success) { return ERC20Interface(tokenAddress).transfer(owner, tokens); }
}
可悲的是它沒有用..同樣的錯誤(契約執行期間遇到的錯誤
$$ Reverted $$)
兩件事情。
首先,這是一種錯誤的方法。您應該將代幣的定義和記賬與代幣的報價/銷售分開。這將為您留下一個解決良好的令牌,例如 openzeppelin,沒有任何更改,因此您可以確信很多可能會按預期工作。您還將擁有一份銷售契約。
創建 ERC20 後,所有者/鑄幣者/部署者通常擁有 100% 的供應。他們使用正常
.transfer
方法將部分或全部代幣發送到銷售合約。銷售合約的工作是用手頭的代幣交換收到的 ETH。如果有幫助,可以考慮一個檸檬水攤。檸檬水攤的工作是將美味的檸檬水(它必須首先擁有)換成一定數量的美元。美元和檸檬水(ETH 和代幣)沒有與銷售過程相關的內置屬性。試圖這樣做只會摻雜他們設計的純潔性。
第二件事。這條線會讓你陷入困境。
uint public sellPrice =0.5;
由於賣價是一個無符號整數,
0.5
=0
. 這導致函式中的“除以零”buy()
。考慮乘以 2 (.mul(uint(2)
) 而不是除以0.5
。希望能幫助到你。
更新
Shane 對您使用
transferFrom
. 你沒有正確使用它。但是,由於銷售過程/契約可能已經持有要出售的代幣庫存,transfer(receiver, amount)
因此正常就足夠了。
解決方案正如 Rob Hitchens 所提到的……使用簡單的轉移方法。但是,請確保您使用事件傳輸,而不是他編寫的傳輸函式(帶有小 t)。
Transfer 事件需要 3 個參數,而傳輸函式需要 2 個參數