Solidity

是否可以為 ERC20 代幣進行託管

  • November 9, 2018

我正在開發一個網站,幫助使用者執行 ERC20 代幣的託管。特定平台僅接受上述 ERC20 代幣。我需要我的客戶將 ERC20 代幣存入託管合約,直到他收到服務/產品。我的疑問是,

  1. 是否可以為 ERC20 代幣簽訂託管合約。我不能使用 Metamask(作為 web3 提供者),因為無法使用 metamask 轉移令牌。

如果有人指導我找到帶有樣本契約的解決方案(如果有),那就太好了,非常感謝:)。

我們為 ERC20 代幣的託管功能創建了一個解決方案。希望這可以幫助。

我們使用的程式碼如下。

pragma solidity ^0.4.21;

import "../zeppelin-solidity/contracts/token/ERC20/ERC20.sol";
import "../zeppelin-solidity/contracts/ownership/Ownable.sol";
import "../webshop/Webshop.sol";

contract Escrow is Ownable {
   enum PaymentStatus { Pending, Completed, Refunded }

   event PaymentCreation(uint indexed orderId, address indexed customer, uint value);
   event PaymentCompletion(uint indexed orderId, address indexed customer, uint value, PaymentStatus status);

   struct Payment {
       address customer;
       uint value;
       PaymentStatus status;
       bool refundApproved;
   }

   mapping(uint => Payment) public payments;
   ERC20 public currency;
   address public collectionAddress;
   Webshop public webshop;

   function Escrow(ERC20 _currency, address _collectionAddress) public {
       currency = _currency;
       collectionAddress = _collectionAddress;
       webshop = Webshop(msg.sender);
   }

   function createPayment(uint _orderId, address _customer, uint _value) external onlyOwner {
       payments[_orderId] = Payment(_customer, _value, PaymentStatus.Pending, false);
       emit PaymentCreation(_orderId, _customer, _value);
   }

   function release(uint _orderId) external {
       completePayment(_orderId, collectionAddress, PaymentStatus.Completed);
   }

   function refund(uint _orderId) external {
       completePayment(_orderId, msg.sender, PaymentStatus.Refunded);
   }

   function approveRefund(uint _orderId) external {
       require(msg.sender == collectionAddress);
       Payment storage payment = payments[_orderId];
       payment.refundApproved = true;
   }

   function completePayment(uint _orderId, address _receiver, PaymentStatus _status) private {
       Payment storage payment = payments[_orderId];
       require(payment.customer == msg.sender);
       require(payment.status == PaymentStatus.Pending);
       if (_status == PaymentStatus.Refunded) {
           require(payment.refundApproved);
       }
       currency.transfer(_receiver, payment.value);
       webshop.changeOrderStatus(_orderId, Webshop.OrderStatus.Completed);
       payment.status = _status;
       emit PaymentCompletion(_orderId, payment.customer, payment.value, _status);
   }
}

程式碼的解釋,包括程式碼可以在https://medium.com/@s_van_laar/how-to-build-an-escrow-contract-with-an-ethereum-erc20-token-bfc4825b0dd7找到

  1. 您需要知道令牌的地址,允許使用者儲存它。
  2. 您需要在該地址實例化令牌合約,以便您可以呼叫它的函式
  3. 您需要在客戶端上使用approve(),然後在合約上呼叫transferFrom() 將代幣從使用者發送到合約。transferAndCall() 將不可用,因為您想使用 ERC20。
  4. 條件完成後,您可以通過合約呼叫 .transfer() 將託管轉移給收件人。

這是一個沒有代幣的數字貿易融資範例,但正如我所說,使用帶有代幣的approv/transferFrom 代替乙太幣,而是使用地址。https://github.com/kyriediculous/LetterOfCredit/blob/master/LoCWorkflow.sol

現在您有了設計決定,是否希望每個託管成為兩個使用者之間的單獨契約,就像我在範例中所做的那樣:)。

祝你好運,希望這會有所幫助。

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