Erc-20

ERC20 錢包的通用 Gas 錢包?

  • October 28, 2019

我們有一個錢包結構,使用者將代幣發送到為他們生成的個人使用者錢包地址,然後我們將使用者錢包中的所有資金清掃到一個集中的池中。個人錢包充當使用者資金的接收地址。通常,當發生 ETH 轉賬時,交易費用從資金中扣除,我們承擔費用。

當發生 ERC20 代幣存款時,我們現在必須將 ETH 發送到該地址以支付掃描的交易成本。這遠不是一個好的解決方案(它留下了事務更改並且難以實施)

天真的解決方案:每次我檢測到一個 ERC20 存入該錢包時,只需將 ETH 發送到使用者的錢包中,這樣該錢包就可以支付用於轉移的氣體。

地址工廠契約:受此答案的啟發,創建了一個將為契約生成地址的契約。不足之處是每個地址生成的氣體。

看起來 Meta Transactions 是解決這個問題的一種方式,相關連結

我們的特殊限制:

  • 使用地址作為標識
  • 最小的使用者體驗權衡

解決方案:生成接收者合約的合約

接收方地址生成合約:

contract Factory {

address public owner;
mapping ( uint256 => address ) public receiversMap;
uint256 public receiverCount = 0;

constructor() public {
   /* 
       Deployer's address ( Factory in our case )
       do not pass this as a constructor argument because 
       etherscan will have issues displaying our validated source code
   */
   owner = msg.sender;
}

/*
   @notice Transfer Ownership of this contract to another address
   @param newOwner - Address of the next Owner of the contract
*/
function transferOwner(address newOwner) public {
   require (msg.sender == owner);
   owner = newOwner;
}

/*
   @notice Create a number of receiver contracts
   @param number  - 0-255 
*/
function createReceivers( uint8 number ) public {
   require(msg.sender == owner);

   for(uint8 i = 0; i < number; i++) {
       // Create and index our new receiver
       receiversMap[++receiverCount] = new Receiver();
   }
   // add event here if you need it
}

/*
   @notice Send funds in a receiver to another address
   @param ID       - Receiver indexed ID
   @param tracker  - ERC20 token tracker ( DAI / MKR / etc. )
   @param amount   - Amount of tokens to send
   @param receiver - Address we're sending tokens to
   @return true if transfer succeeded, false otherwise 
*/
function sendFundsFromReceiverTo( uint256 ID, address tracker, uint256 amount, address receiver ) public returns (bool) {
   require(msg.sender == owner);
   return Receiver( receiversMap[ID] ).sendFundsTo( tracker, amount, receiver);
}

/*
   Batch Collection - Should support a few hundred transansfers

   @param tracker           - ERC20 token tracker ( DAI / MKR / etc. )
   @param receiver          - Address we're sending tokens to
   @param contractAddresses - we send an array of addresses instead of ids, so we don't need to read them ( lower gas cost )
   @param amounts           - array of amounts 

*/
function batchCollect( address tracker, address receiver, address[] contractAddresses, uint256[] amounts ) public {
   require(msg.sender == owner);

   for(uint256 i = 0; i < contractAddresses.length; i++) {

       // add exception handling
       Receiver( contractAddresses[i] ).sendFundsTo( tracker, amounts[i], receiver);
   }
}
}

接收方契約:

contract Receiver {

address public owner;

constructor() public {
   /* 
       Deployer's address ( Factory in our case )
       do not pass this as a constructor argument because 
       etherscan will have issues displaying our validated source code
   */
   owner = msg.sender;
}

/*
   @notice Transfer Ownership of this contract to another address
   @param newOwner - Address of the next Owner of the contract
*/
function transferOwner(address newOwner) public {
   require (msg.sender == owner);
   owner = newOwner;
}

/*
   @notice Send funds owned by this contract to another address
   @param tracker  - ERC20 token tracker ( DAI / MKR / etc. )
   @param amount   - Amount of tokens to send
   @param receiver - Address we're sending these tokens to
   @return true if transfer succeeded, false otherwise 
*/
function sendFundsTo( address tracker, uint256 amount, address receiver) public returns ( bool ) {
   // callable only by the owner, not using modifiers to improve readability
   require(msg.sender == owner);

   // Transfer tokens from this address to the receiver
   return ERC20(tracker).transfer(receiver, amount);
}

// depending on your system,  you probably want to suicide this at some
// point in the future, or reuse it for other clients
}

答案基於 Micky Socaci 的解決方案here。整個解決方案,經過必要的修改,託管在My Github上,具有知識共享許可,因此可以放入任何程式碼庫。

如果這對您有幫助,將不勝感激:)。

https://github.com/Meshugah/ERC20-CommonGasWallet

我假設您不能僅根據發送地址來辨識令牌轉移者 - 否則這將是微不足道的(只需遵循 Transfer 事件)。

我個人不太明白為什麼元交易已經不是一件大事了。它們支持各種場景,尤其是在使用者輕鬆入職時。當然,他們有一些問題並且實施起來有點棘手,但是一旦正確實施,它應該可以正常工作。所以我的建議是進行元交易。

讓我們花點時間思考在正常令牌傳輸中,除了發件人地址之外,是否有可能通過其他方式辨識發件人。轉移代幣有兩種方式:直接轉移和批准檢索。

  1. transfer(address recipient, uint256 amount). recipient必須是您控制的一些錢包地址。所以要麼是特製的錢包,要麼是普通的錢包。這幾乎是您幼稚的解決方案。但另一個想法可能是考慮是否可以amount以某種方式使用。如果您只有少數使用者和大量代幣(少量代幣不會產生太大影響),您可以通過代幣數量來辨識使用者。因此,例如,如果三個使用者需要發送 5000 個令牌,您可以指示第一個發送 5003 個令牌,第二個發送 5006,第三個發送 5009。這不是最好的解決方案,但實施起來容易且便宜,因此可能值得考慮。
  2. approve(address spender, uint256 amount)transferFrom(address sender, address recipient, uint256 amount)。與第一個選項中的注意事項相同,因為使用者只啟動approve事務,其餘的由您完成。

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