Gas
ERC20幣的使用者需要持有乙太幣嗎?
假設存在 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)); } }