Gas

ERC20幣的使用者需要持有乙太幣嗎?

  • March 22, 2020

假設存在 Fancycoin,一種 ERC20 山寨幣,它具有由 EVM 實現的一些功能。它會做一些消耗氣體的重要事情。

據我了解,如果有人發給我,我可以在錢包裡收到 Fancycoin,而我自己沒有任何乙太幣。

我的問題是:如果我有 Fancycoin 並且我想用它來做某事(也許它會檢查預言機,或者使用塊內部的一些數據進行計算等)但我的錢包裡沒有任何乙太幣,我將無法使用 Fancycoin 的任何功能嗎?正如下面第一條評論中連結的問題的答案中所提到的,我可能無法將 Fancycoin 發送給其他人。)但是,Fancycoin 中的功能是否可以通過某種方式以 Fancycoin 而不是乙太幣支付 gas 費用?

回答上述問題可以回答我的問題,但如果您想擴展:我認為最普遍的情況是,我對建立在乙太坊之上的代幣如何與乙太坊互動感興趣。我不明白這一點。

預設答案是:不,您不能使用沒有乙太幣的帳戶來處理與 Fancycoin 相關的任何事情,因為與標準令牌的任何互動都需要您簽署並廣播到網路的交易,並反過來支付交易費用乙太幣(至少目前你只能用乙太幣支付費用)。

更有趣的答案是:是的,通過稍微改變需求。你確實在鏈下簽署了一筆交易,將其發送給其他人(例如通過鴿子、蝸牛郵件或煙霧信號)。然後其他人可能能夠發送該交易並可能因此獲得一點獎勵。

上述想法並沒有完全解決(表明安全問題仍然存在),但以下草圖有效,我只是在 geth web3 控制台的幫助下在 Remix 中對其進行了測試:

pragma solidity ^0.4.13;

/*
Author: Dr. Sebastian C. Buergel for Validity Labs AG
License: MIT

aim:
allow account without ETH but in possession of tokens to transfer tokens

approach:
sign message off-chain, send to other user, incentivize that user to broadcast message and get token as reward

remaining issues and solutions:
- replay protection (use nonce),
- frontrunning by other nodes (commit-reveal),
- timeout (expiry time)

step 0: choose amount, recipient (to), and reward (in tokens) for broadcaster
step 1: obtain hash from `calcHash` (off-chain, offline)
step 2: sign hash (off-chain, offline), e.g. using geth web3 console:
var signature = web3.eth.sign(web3.eth.accounts[0], hash);
var r = signature.substring(0,66);
var s = '0x' + signature.substring(66,130);
var v = '0x' + signature.substring(130,132); // make sure it is 27 or 28, else add 27

step 3: send transaction to someone else
step 4: that other account broadcasts the message by sending it to `broadcast`, funds get transferred and broadcaster gets reward
*/

contract Fancycoin {

   event Transfer(address indexed _from, address indexed _to, uint256 _value);

   mapping(address => uint) public balanceOf;

   uint public totalSupply;

   constructor(uint supply) {
       totalSupply = supply;
       balanceOf[msg.sender] = supply;
   }

   function transfer(address _to, uint256 _value) returns (bool success) {
       return transferFromTo(msg.sender, _to, _value);
   }

   function transferFromTo(address _from, address _to, uint _value) internal returns (bool success) {
       if (balanceOf[_from] >= _value && _value > 0) {
           balanceOf[_from] -= _value;
           balanceOf[_to] += _value;
           Transfer(_from, _to, _value);
           return true;
       } else { return false; }
   }

   // helper function since web3.sha3 is not (yet) able to concatenate arguments in the same way that solidity does it
   function calcHash(uint amount, address to, uint reward) constant returns (bytes32) {
       return sha3(amount, to, reward);
   }

   function verify(uint amount, address to, uint reward, uint8 v, bytes32 r, bytes32 s) constant returns(address) {
       bytes memory prefix = "\x19Ethereum Signed Message:\n32";
       bytes32 prefixedHash = sha3(prefix, sha3(amount, to, reward));
       return ecrecover(prefixedHash, v, r, s);
   }

   function broadcast(uint amount, address to, uint reward, uint8 v, bytes32 r, bytes32 s) {
       address sender = verify(amount, to, reward, v, r, s);
       assert(transferFromTo(sender, msg.sender, reward));
       assert(transferFromTo(sender, to, amount));
   }

}

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