Solidity

合約方法僅適用於合約地址,不適用於普通賬戶地址

  • August 21, 2021

為了測試目的,我編寫了一個簡單的代幣合約:

pragma solidity ^0.4.18;

contract TestToken {
   uint public totalSupply;

   mapping(address => uint) public balanceOf;

   function transfer(address to, uint amount) public returns (bool) {
       require(balanceOf[msg.sender] >= amount);
       balanceOf[msg.sender] -= amount;
       balanceOf[to] += amount;
       return true;
   }

   function credit(address to, uint amount) public {
       balanceOf[to] += amount;
       totalSupply += amount;
   }

   function debit(address from, uint amount) public {
       balanceOf[from] -= amount;
       totalSupply -= amount;
   }
}

每當我呼叫credit合約上的方法並將另一個合約的地址作為參數傳遞時,一切都會按預期工作:

token.methods.credit(wallet._address, 500000).send({from: accounts[0], gas: "0xB3E4", gasPrice: "0x4A817C800", value: "0x"})

交易狀態為0x1

餘額更新:

token.methods.balanceOf(wallet._address).call()
'500000'

但是,當我將正常乙太坊帳戶的地址作為參數傳遞時,交易被探勘,但沒有任何反應。

token.methods.credit(accounts[0], 500000).send({from: accounts[0], gas: "0xB3E4", gasPrice: "0x4A817C800", value: "0x"})

交易狀態為0x0

餘額不變:

token.methods.balanceOf(accounts[0]).call()
'0'

比較生成的簽名交易對象,除了欄位之外的唯一區別data是簽名v值始終0是交易失敗和1交易成功的時間。但我不確定那是什麼意思。


更新:

似乎它甚至不是契約與非契約,只是有些地址不起作用。

例如,這有效:

token.methods.credit('0xd2d0aD819B2679FBDD5C75F93fa13242bfd7E2A5', 500000000000000000).send({from: accounts[0], gas: "0xB3E4", gasPrice: "0x4A817C800", value: "0x"})

這不會:

token.methods.credit('0xc4beccd2ebdb32203800dfbc60ff0dd7c2762b48', 500000000000000000).send({from: accounts[0], gas: "0xB3E4", gasPrice: "0x4A817C800", value: "0x"})

問題很可能與氣體限制有關。你是怎麼計算的?

當交易附加了一些數據時,例如合約的方法選擇器和參數,零字節的成本低於非零。因此,發送代幣的0x0011223344556677889900112233445566778899交易將比發送相同數量代幣的交易成本更低0x112233445566778899aa112233445566778899aa。此外,將儲存中的價值從零更改為非零比將其從非零更改為非零成本更高。如果地址已經有一些令牌,那麼balanceOf[to] += amount;成本會更低。to

  1. 您從帳戶發送$$ 0 $$記賬$$ 0 $$,所以餘額保持不變
  2. 如果(帳戶的餘額$$ 0 $$) 為零,正如您在第二次通話中顯示的那樣,轉移通話將因 require(balanceOf$$ msg.sender $$>= 數量)

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