Solidity

如何測試與 Bittrex 相關的智能合約的功能?

  • June 13, 2019

我已經掌握了與 Bittrex 交易所相關的智能合約。

我想部署這個智能合約來測試功能,但我不知道如何正確呼叫這些功能。我的問題在下面更具體地描述:

我部署了Controller合約,然後呼叫了makeWallet函式,現在我的問題出現了。如何使用合約sweep()上的功能?UserWallet

contract AbstractSweeper {
   function sweep(address token, uint amount) returns (bool);

   function () { throw; }

   Controller controller;

   function AbstractSweeper(address _controller) {
       controller = Controller(_controller);
   }

   modifier canSweep() {
       if (msg.sender != controller.authorizedCaller() && msg.sender != controller.owner()) throw;
       if (controller.halted()) throw;
       _;
   }
}

contract Token {
   function balanceOf(address a) returns (uint) {
       (a);
       return 0;
   }

   function transfer(address a, uint val) returns (bool) {
       (a);
       (val);
       return false;
   }
}

contract DefaultSweeper is AbstractSweeper {
   function DefaultSweeper(address controller)
            AbstractSweeper(controller) {}

   function sweep(address _token, uint _amount)
   canSweep
   returns (bool) {
       bool success = false;
       address destination = controller.destination();

       if (_token != address(0)) {
           Token token = Token(_token);
           uint amount = _amount;
           if (amount > token.balanceOf(this)) {
               return false;
           }

           success = token.transfer(destination, amount);
       }
       else {
           uint amountInWei = _amount;
           if (amountInWei > this.balance) {
               return false;
           }

           success = destination.send(amountInWei);
       }

       if (success) {
           controller.logSweep(this, destination, _token, _amount);
       }
       return success;
   }
}

contract UserWallet {
   AbstractSweeperList sweeperList;
   function UserWallet(address _sweeperlist) {
       sweeperList = AbstractSweeperList(_sweeperlist);
   }

   function () public payable { }

   function tokenFallback(address _from, uint _value, bytes _data) {
       (_from);
       (_value);
       (_data);
    }

   function sweep(address _token, uint _amount)
   returns (bool) {
       (_amount);
       return sweeperList.sweeperOf(_token).delegatecall(msg.data);
   }
}

contract AbstractSweeperList {
   function sweeperOf(address _token) returns (address);
}

contract Controller is AbstractSweeperList {
   address public owner;
   address public authorizedCaller;

   address public destination;

   bool public halted;

   event LogNewWallet(address receiver);
   event LogSweep(address indexed from, address indexed to, address indexed token, uint amount);

   modifier onlyOwner() {
       if (msg.sender != owner) throw; 
       _;
   }

   modifier onlyAuthorizedCaller() {
       if (msg.sender != authorizedCaller) throw; 
       _;
   }

   modifier onlyAdmins() {
       if (msg.sender != authorizedCaller && msg.sender != owner) throw; 
       _;
   }

   function Controller() 
   {
       owner = msg.sender;
       destination = msg.sender;
       authorizedCaller = msg.sender;
   }

   function changeAuthorizedCaller(address _newCaller) onlyOwner {
       authorizedCaller = _newCaller;
   }

   function changeDestination(address _dest) onlyOwner {
       destination = _dest;
   }

   function changeOwner(address _owner) onlyOwner {
       owner = _owner;
   }

   function makeWallet() onlyAdmins returns (address wallet)  {
       wallet = address(new UserWallet(this));
       LogNewWallet(wallet);
   }

   function halt() onlyAdmins {
       halted = true;
   }

   function start() onlyOwner {
       halted = false;
   }

   address public defaultSweeper = address(new DefaultSweeper(this));
   mapping (address => address) sweepers;

   function addSweeper(address _token, address _sweeper) onlyOwner {
       sweepers[_token] = _sweeper;
   }

   function sweeperOf(address _token) returns (address) {
       address sweeper = sweepers[_token];
       if (sweeper == 0) sweeper = defaultSweeper;
       return sweeper;
   }

   function logSweep(address from, address to, address token, uint amount) {
       LogSweep(from, to, token, amount);
   }
}

您必須遵循sweepUserWallet 的操作

function sweep(address _token, uint _amount)
returns (bool) {
   (_amount);
   return sweeperList.sweeperOf(_token).delegatecall(msg.data);
}

它獲得一個地址sweeperList.sweeperOf(_token),然後delegatecall(msg.data)進入該地址。

我們有那msg.data是附加到交易的消息。因此它將sweep(address _token, uint _amount)在目標合約中執行,但不會更改儲存。

現在sweeperOf返回註冊地址或預設地址。

function sweeperOf(address _token) returns (address) {
   address sweeper = sweepers[_token];
   if (sweeper == 0) sweeper = defaultSweeper;
   return sweeper;
}

現在預設清掃器會將令牌(或乙太幣)從 UserWallet(delegatecall 未更改儲存)轉移到目的地。

function sweep(address _token, uint _amount)
canSweep
returns (bool) {
   bool success = false;
   address destination = controller.destination();

   if (_token != address(0)) {
       Token token = Token(_token);
       uint amount = _amount;
       if (amount > token.balanceOf(this)) {
           return false;
       }

       success = token.transfer(destination, amount);
   }
   else {
       uint amountInWei = _amount;
       if (amountInWei > this.balance) {
           return false;
       }

       success = destination.send(amountInWei);
   }

   if (success) {
       controller.logSweep(this, destination, _token, _amount);
   }
   return success;
}

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