Solidity
面對簡單契約中的問題
我正在學習一門課程,並從那裡編寫了相同的程式碼。
在這裡,我在購買代幣時遇到了問題。由於我已將價格設置為 1 乙太幣,因此我應該可以用乙太幣購買,但是當我嘗試用乙太幣購買代幣時,它顯示錯誤,但當我用 wei 購買時,它工作正常。我在這裡想念什麼?
contract owned { address owner; constructor(){ owner = msg.sender; } modifier own () { require(msg.sender == owner , "ONLY OWNER CAN CREATE NEW TOKEN"); _; } } contract TokenGeneration is owned{ mapping(address => uint) public tokenBalance; uint tokenPrice = 1 ether; constructor (){ tokenBalance[msg.sender]= 100; } function createToken() public own { tokenBalance[owner]++; } function burnToken() public own { tokenBalance[owner]--; } function buyToken() public payable { require((tokenBalance[owner] * tokenPrice)/msg.value > 0,"NOT ENOUGH TOKEN"); tokenBalance[owner] -= msg.value; tokenBalance[msg.sender] += msg.value; } function sendToken(address _to, uint amount) public { require(tokenBalance[msg.sender] >= amount , "NOT ENOUGH BALANCE"); tokenBalance[msg.sender] -= amount; tokenBalance[_to] += amount; } }```
問題是您為每個令牌收取 1 wei,而您的 tokenBalance 中只有 100 個令牌。當您嘗試用 1 個乙太幣購買代幣時,您正在嘗試獲取
1000000000000000000
代幣,但您只有100
,因此當您嘗試msg.value
從tokenBalance
該行中減去 時,它必須失敗:tokenBalance[owner] -= msg.value;
因此,為了解決這個問題,您需要在建構子中創建更多標記。
在建構子中,您可以執行以下操作:
tokenBalance[msg.sender] = 1e18 * 100;
這樣你就得到了 100 個單位的 1e18 (1000000000000000000 * 100)。您現在可以以 1 wei 出售每個代幣,以 1e18 wei 出售 1e18 代幣,這將是 1 eth x 1e18 代幣。
msg.value
總是表示為wei,所以要小心。如果您真的想以 1 個乙太幣出售 1 個代幣,那麼您需要檢查 是否
msg.value
等於1 ether
,如果是,則向該發件人出售 1 個代幣。我建議你通過 wei 而不是乙太幣出售代幣,因為 wei 比乙太幣更靈活。這也是因為你有一個
payable
函式並且你正在使用msg.value
,如果你用 1 個乙太幣出售 1 個代幣,如果有人給你 3.5 個乙太幣會發生什麼?你會賣 3.5 個代幣嗎?那些令牌被分割?或者你會出售 3 個代幣並將額外的 0.5 個乙太幣留給自己嗎?重構您的契約,這將按您的預期工作:
contract TokenGeneration is owned{ mapping(address => uint) public tokenBalance; uint public tokenPrice = 1 ether; constructor (){ tokenBalance[msg.sender] = 100; } function createToken() public own { tokenBalance[owner]++; } function burnToken() public own { tokenBalance[owner]--; } function buyToken() public payable { // Let's check how many ethers was sent. The msg.value is in wei, so, // dividing it by 1 ether will give us the count of ethers that was actually sent. uint countOfEthersToBuy = msg.value / tokenPrice; // or msg.value / 1 ether; // Make sure that at least 1 ether was sent, not less. require(countOfEthersToBuy > 0, "Not enough ethers was sent"); // Make sure that whole ethers were sent, not 2.5 ethers, not 5.7 ethers, // since we are selling whole tokens, not fractions of tokens. uint remainingWei = msg.value % tokenPrice; require(remainingWei == 0, "Not whole ethers was sent"); require(tokenBalance[owner] > countOfEthersToBuy,"NOT ENOUGH TOKEN"); tokenBalance[owner] -= countOfEthersToBuy; tokenBalance[msg.sender] += countOfEthersToBuy; } function sendToken(address _to, uint amount) public { require(tokenBalance[msg.sender] >= amount , "NOT ENOUGH BALANCE"); tokenBalance[msg.sender] -= amount; tokenBalance[_to] += amount; } }