ETH Price: $2,022.31 (+4.48%)

Transaction Decoder

Block:
4719507 at Dec-12-2017 11:05:05 AM +UTC
Transaction Fee:
0.000480965 ETH $0.97
Gas Used:
96,193 Gas / 5 Gwei

Emitted Events:

70 EventsHistory.0x940c4b3549ef0aaff95807dc27f62d88ca15532d1bf535d7d63800f40395d16c( 0x940c4b3549ef0aaff95807dc27f62d88ca15532d1bf535d7d63800f40395d16c, 0x000000000000000000000000e4e7f6e7d082aeaaa1dd20907ea426a3cc70b0df, 0x00000000000000000000000021630b392896995fafd3edf9e7659126bbd04bee, 0x4343000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000004e20000, 0000000000000000000000000000000000000000000000000000000000000060, 0000000000000000000000000000000000000000000000000000000000000001, 0000000000000000000000000000000000000000000000000000000000000000 )
71 CryptoCarbon.Transfer( from=[Sender] 0xe4e7f6e7d082aeaaa1dd20907ea426a3cc70b0df, to=0x21630b392896995fAfD3eDf9e7659126BBD04bEE, value=81920000 )

Account State Difference:

  Address   Before After State Difference Code
0x68C76947...fE4Fbd6b1
(PandaPool)
437.616063445108471203 Eth437.616544410108471203 Eth0.000480965
0xd6C3FECC...a321E3131
3.1852532464 Eth3.1847504364 Eth0.00050281
0xe4E7f6e7...3cc70b0DF
0.323580989255112063 Eth
Nonce: 13078
0.323602834255112063 Eth
Nonce: 13079
0.000021845

Execution Trace

CryptoCarbon.transfer( _to=0x21630b392896995fAfD3eDf9e7659126BBD04bEE, _value=81920000 ) => ( True )
  • Null: 0x000...004.CALL( )
  • 0x68c769478002b2e2db64fe3be55c943fe4fbd6b1.64ef212e( )
    • Null: 0x000...004.CALL( )
    • EventsHistory.515c1457( )
      • MultiAssetEmitter.emitTransfer( _from=0xe4E7f6e7d082aeaAa1Dd20907Ea426A3cc70b0DF, _to=0x21630b392896995fAfD3eDf9e7659126BBD04bEE, _symbol=4343000000000000000000000000000000000000000000000000000000000000, _value=81920000, _reference= )
        • EventsHistory.versions( 0x68C769478002B2E2Db64fE3Be55C943fE4Fbd6b1 ) => ( 1 )
        • Null: 0x000...004.CALL( )
        • StackDepthLib.checkDepth( self=0x606dDac6F2928369e8515340f8dE97Fe2d166777, n=1 ) => ( True )
          • StackDepthLib.__dig( n=0 )
          • CryptoCarbon.emitTransfer( _from=0xe4E7f6e7d082aeaAa1Dd20907Ea426A3cc70b0DF, _to=0x21630b392896995fAfD3eDf9e7659126BBD04bEE, _value=81920000 )
          • 0xd6c3fecce74e5fb3a9bcc6bbaaebf80a321e3131.f3fef3a3( )
            • ETH 0.00050281 0xe4e7f6e7d082aeaaa1dd20907ea426a3cc70b0df.CALL( )
              File 1 of 4: CryptoCarbon
              contract MultiAsset {
                  function isCreated(bytes32 _symbol) constant returns(bool);
                  function owner(bytes32 _symbol) constant returns(address);
                  function totalSupply(bytes32 _symbol) constant returns(uint);
                  function balanceOf(address _holder, bytes32 _symbol) constant returns(uint);
                  function transfer(address _to, uint _value, bytes32 _symbol) returns(bool);
                  function proxyTransferWithReference(address _to, uint _value, bytes32 _symbol, string _reference) returns(bool);
                  function proxyTransferToICAPWithReference(bytes32 _icap, uint _value, string _reference) returns(bool);
                  function proxyApprove(address _spender, uint _value, bytes32 _symbol) returns(bool);
                  function allowance(address _from, address _spender, bytes32 _symbol) constant returns(uint);
                  function transferFromWithReference(address _from, address _to, uint _value, bytes32 _symbol, string _reference) returns(bool);
                  function transferFromToICAPWithReference(address _from, bytes32 _icap, uint _value, string _reference) returns(bool);
                  function proxyTransferFromWithReference(address _from, address _to, uint _value, bytes32 _symbol, string _reference) returns(bool);
                  function proxyTransferFromToICAPWithReference(address _from, bytes32 _icap, uint _value, string _reference) returns(bool);
                  function proxySetCosignerAddress(address _address, bytes32 _symbol) returns(bool);
              }
              
              contract Ambi {
                  function getNodeAddress(bytes32 _name) constant returns (address);
                  function addNode(bytes32 _name, address _addr) external returns (bool);
                  function hasRelation(bytes32 _from, bytes32 _role, address _to) constant returns (bool);
              }
              
              contract EtherTreasuryInterface {
                  function withdraw(address _to, uint _value) returns(bool);
              }
              
              contract Safe {
                  // Should always be placed as first modifier!
                  modifier noValue {
                      if (msg.value > 0) {
                          // Internal Out Of Gas/Throw: revert this transaction too;
                          // Call Stack Depth Limit reached: revert this transaction too;
                          // Recursive Call: safe, no any changes applied yet, we are inside of modifier.
                          _safeSend(msg.sender, msg.value);
                      }
                      _
                  }
              
                  modifier onlyHuman {
                      if (_isHuman()) {
                          _
                      }
                  }
              
                  modifier noCallback {
                      if (!isCall) {
                          _
                      }
                  }
              
                  modifier immutable(address _address) {
                      if (_address == 0) {
                          _
                      }
                  }
              
                  address stackDepthLib;
                  function setupStackDepthLib(address _stackDepthLib) immutable(address(stackDepthLib)) returns(bool) {
                      stackDepthLib = _stackDepthLib;
                      return true;
                  }
              
                  modifier requireStackDepth(uint16 _depth) {
                      if (stackDepthLib == 0x0) {
                          throw;
                      }
                      if (_depth > 1023) {
                          throw;
                      }
                      if (!stackDepthLib.delegatecall(0x32921690, stackDepthLib, _depth)) {
                          throw;
                      }
                      _
                  }
              
                  // Must not be used inside the functions that have noValue() modifier!
                  function _safeFalse() internal noValue() returns(bool) {
                      return false;
                  }
              
                  function _safeSend(address _to, uint _value) internal {
                      if (!_unsafeSend(_to, _value)) {
                          throw;
                      }
                  }
              
                  function _unsafeSend(address _to, uint _value) internal returns(bool) {
                      return _to.call.value(_value)();
                  }
              
                  function _isContract() constant internal returns(bool) {
                      return msg.sender != tx.origin;
                  }
              
                  function _isHuman() constant internal returns(bool) {
                      return !_isContract();
                  }
              
                  bool private isCall = false;
                  function _setupNoCallback() internal {
                      isCall = true;
                  }
              
                  function _finishNoCallback() internal {
                      isCall = false;
                  }
              }
              
              contract Asset is Safe {
                  event Transfer(address indexed from, address indexed to, uint value);
                  event Approve(address indexed from, address indexed spender, uint value);
              
                  MultiAsset public multiAsset;
                  bytes32 public symbol;
              
                  function init(address _multiAsset, bytes32 _symbol) noValue() immutable(address(multiAsset)) returns(bool) {
                      MultiAsset ma = MultiAsset(_multiAsset);
                      if (!ma.isCreated(_symbol)) {
                          return false;
                      }
                      multiAsset = ma;
                      symbol = _symbol;
                      return true;
                  }
              
                  modifier onlyMultiAsset() {
                      if (msg.sender == address(multiAsset)) {
                          _
                      }
                  }
              
                  function totalSupply() constant returns(uint) {
                      return multiAsset.totalSupply(symbol);
                  }
              
                  function balanceOf(address _owner) constant returns(uint) {
                      return multiAsset.balanceOf(_owner, symbol);
                  }
              
                  function allowance(address _from, address _spender) constant returns(uint) {
                      return multiAsset.allowance(_from, _spender, symbol);
                  }
              
                  function transfer(address _to, uint _value) returns(bool) {
                      return __transferWithReference(_to, _value, "");
                  }
              
                  function transferWithReference(address _to, uint _value, string _reference) returns(bool) {
                      return __transferWithReference(_to, _value, _reference);
                  }
              
                  function __transferWithReference(address _to, uint _value, string _reference) private noValue() returns(bool) {
                      return _isHuman() ?
                          multiAsset.proxyTransferWithReference(_to, _value, symbol, _reference) :
                          multiAsset.transferFromWithReference(msg.sender, _to, _value, symbol, _reference);
                  }
              
                  function transferToICAP(bytes32 _icap, uint _value) returns(bool) {
                      return __transferToICAPWithReference(_icap, _value, "");
                  }
              
                  function transferToICAPWithReference(bytes32 _icap, uint _value, string _reference) returns(bool) {
                      return __transferToICAPWithReference(_icap, _value, _reference);
                  }
              
                  function __transferToICAPWithReference(bytes32 _icap, uint _value, string _reference) private noValue() returns(bool) {
                      return _isHuman() ?
                          multiAsset.proxyTransferToICAPWithReference(_icap, _value, _reference) :
                          multiAsset.transferFromToICAPWithReference(msg.sender, _icap, _value, _reference);
                  }
                  
                  function transferFrom(address _from, address _to, uint _value) returns(bool) {
                      return __transferFromWithReference(_from, _to, _value, "");
                  }
              
                  function transferFromWithReference(address _from, address _to, uint _value, string _reference) returns(bool) {
                      return __transferFromWithReference(_from, _to, _value, _reference);
                  }
              
                  function __transferFromWithReference(address _from, address _to, uint _value, string _reference) private noValue() onlyHuman() returns(bool) {
                      return multiAsset.proxyTransferFromWithReference(_from, _to, _value, symbol, _reference);
                  }
              
                  function transferFromToICAP(address _from, bytes32 _icap, uint _value) returns(bool) {
                      return __transferFromToICAPWithReference(_from, _icap, _value, "");
                  }
              
                  function transferFromToICAPWithReference(address _from, bytes32 _icap, uint _value, string _reference) returns(bool) {
                      return __transferFromToICAPWithReference(_from, _icap, _value, _reference);
                  }
              
                  function __transferFromToICAPWithReference(address _from, bytes32 _icap, uint _value, string _reference) private noValue() onlyHuman() returns(bool) {
                      return multiAsset.proxyTransferFromToICAPWithReference(_from, _icap, _value, _reference);
                  }
              
                  function approve(address _spender, uint _value) noValue() onlyHuman() returns(bool) {
                      return multiAsset.proxyApprove(_spender, _value, symbol);
                  }
              
                  function setCosignerAddress(address _cosigner) noValue() onlyHuman() returns(bool) {
                      return multiAsset.proxySetCosignerAddress(_cosigner, symbol);
                  }
              
                  function emitTransfer(address _from, address _to, uint _value) onlyMultiAsset() {
                      Transfer(_from, _to, _value);
                  }
              
                  function emitApprove(address _from, address _spender, uint _value) onlyMultiAsset() {
                      Approve(_from, _spender, _value);
                  }
              
                  function sendToOwner() noValue() returns(bool) {
                      address owner = multiAsset.owner(symbol);
                      uint balance = this.balance;
                      bool success = true;
                      if (balance > 0) {
                          success = _unsafeSend(owner, balance);
                      }
                      return multiAsset.transfer(owner, balanceOf(owner), symbol) && success;
                  }
              }
              
              contract AmbiEnabled {
                  Ambi public ambiC;
                  bool public isImmortal;
                  bytes32 public name;
              
                  modifier checkAccess(bytes32 _role) {
                      if(address(ambiC) != 0x0 && ambiC.hasRelation(name, _role, msg.sender)){
                          _
                      }
                  }
                  
                  function getAddress(bytes32 _name) constant returns (address) {
                      return ambiC.getNodeAddress(_name);
                  }
              
                  function setAmbiAddress(address _ambi, bytes32 _name) returns (bool){
                      if(address(ambiC) != 0x0){
                          return false;
                      }
                      Ambi ambiContract = Ambi(_ambi);
                      if(ambiContract.getNodeAddress(_name)!=address(this)) {
                          if (!ambiContract.addNode(_name, address(this))){
                              return false;
                          }
                      }
                      name = _name;
                      ambiC = ambiContract;
                      return true;
                  }
              
                  function immortality() checkAccess("owner") returns(bool) {
                      isImmortal = true;
                      return true;
                  }
              
                  function remove() checkAccess("owner") returns(bool) {
                      if (isImmortal) {
                          return false;
                      }
                      selfdestruct(msg.sender);
                      return true;
                  }
              }
              
              contract CryptoCarbon is Asset, AmbiEnabled {
                  uint public txGasPriceLimit = 21000000000;
                  uint public refundGas = 40000;
                  uint public transferCallGas = 21000;
                  uint public transferWithReferenceCallGas = 21000;
                  uint public transferFromCallGas = 21000;
                  uint public transferFromWithReferenceCallGas = 21000;
                  uint public transferToICAPCallGas = 21000;
                  uint public transferToICAPWithReferenceCallGas = 21000;
                  uint public transferFromToICAPCallGas = 21000;
                  uint public transferFromToICAPWithReferenceCallGas = 21000;
                  uint public approveCallGas = 21000;
                  uint public forwardCallGas = 21000;
                  uint public setCosignerCallGas = 21000;
                  uint public absMinFee;
                  uint public feePercent; // set up in 1/100 of percent, 10 is 0.1%
                  uint public absMaxFee;
                  EtherTreasuryInterface public treasury;
                  address public feeAddress;
                  bool private __isAllowed;
                  mapping(bytes32 => address) public allowedForwards;
              
                  function setFeeStructure(uint _absMinFee, uint _feePercent, uint _absMaxFee) noValue() checkAccess("cron") returns (bool) {
                      if(_feePercent > 10000 || _absMaxFee < _absMinFee) {
                          return false;
                      }
                      absMinFee = _absMinFee;
                      feePercent = _feePercent;
                      absMaxFee = _absMaxFee;
                      return true;
                  }
              
                  function setupFee(address _feeAddress) noValue() checkAccess("admin") returns(bool) {
                      feeAddress = _feeAddress;
                      return true;
                  }
              
                  function updateRefundGas() noValue() checkAccess("setup") returns(uint) {
                      uint startGas = msg.gas;
                      // just to simulate calculations
                      uint refund = (startGas - msg.gas + refundGas) * tx.gasprice;
                      if (tx.gasprice > txGasPriceLimit) {
                          return 0;
                      }
                      // end
                      if (!_refund(5000000000000000)) {
                          return 0;
                      }
                      refundGas = startGas - msg.gas;
                      return refundGas;
                  }
              
                  function setOperationsCallGas(
                      uint _transfer,
                      uint _transferFrom,
                      uint _transferToICAP,
                      uint _transferFromToICAP,
                      uint _transferWithReference,
                      uint _transferFromWithReference,
                      uint _transferToICAPWithReference,
                      uint _transferFromToICAPWithReference,
                      uint _approve,
                      uint _forward,
                      uint _setCosigner
                  )
                      noValue()
                      checkAccess("setup")
                      returns(bool)
                  {
                      transferCallGas = _transfer;
                      transferFromCallGas = _transferFrom;
                      transferToICAPCallGas = _transferToICAP;
                      transferFromToICAPCallGas = _transferFromToICAP;
                      transferWithReferenceCallGas = _transferWithReference;
                      transferFromWithReferenceCallGas = _transferFromWithReference;
                      transferToICAPWithReferenceCallGas = _transferToICAPWithReference;
                      transferFromToICAPWithReferenceCallGas = _transferFromToICAPWithReference;
                      approveCallGas = _approve;
                      forwardCallGas = _forward;
                      setCosignerCallGas = _setCosigner;
                      return true;
                  }
              
                  function setupTreasury(address _treasury, uint _txGasPriceLimit) checkAccess("admin") returns(bool) {
                      if (_txGasPriceLimit == 0) {
                          return _safeFalse();
                      }
                      treasury = EtherTreasuryInterface(_treasury);
                      txGasPriceLimit = _txGasPriceLimit;
                      if (msg.value > 0) {
                          _safeSend(_treasury, msg.value);
                      }
                      return true;
                  }
              
                  function setForward(bytes4 _msgSig, address _forward) noValue() checkAccess("admin") returns(bool) {
                      allowedForwards[sha3(_msgSig)] = _forward;
                      return true;
                  }
              
                  function _stringGas(string _string) constant internal returns(uint) {
                      return bytes(_string).length * 75; // ~75 gas per byte, empirical shown 68-72.
                  }
              
                  function _transferFee(address _feeFrom, uint _value, string _reference) internal returns(bool) {
                      if (feeAddress == 0x0 || feeAddress == _feeFrom || _value == 0) {
                          return true;
                      }
                      return multiAsset.transferFromWithReference(_feeFrom, feeAddress, _value, symbol, _reference);
                  }
              
                  function _returnFee(address _to, uint _value) internal returns(bool, bool) {
                      if (feeAddress == 0x0 || feeAddress == _to || _value == 0) {
                          return (false, true);
                      }
                      if (!multiAsset.transferFromWithReference(feeAddress, _to, _value, symbol, "Fee return")) {
                          throw;
                      }
                      return (false, true);
                  }
              
                  function _applyRefund(uint _startGas) internal returns(bool) {
                      uint refund = (_startGas - msg.gas + refundGas) * tx.gasprice;
                      return _refund(refund);
                  }
              
                  function _refund(uint _value) internal returns(bool) {
                      if (tx.gasprice > txGasPriceLimit) {
                          return false;
                      }
                      return treasury.withdraw(tx.origin, _value);
                  }
              
                  function _allow() internal {
                      __isAllowed = true;
                  }
              
                  function _disallow() internal {
                      __isAllowed = false;
                  }
              
                  function calculateFee(uint _value) constant returns(uint) {
                      uint fee = (_value * feePercent) / 10000;
                      if (fee < absMinFee) {
                          return absMinFee;
                      }
                      if (fee > absMaxFee) {
                          return absMaxFee;
                      }
                      return fee;
                  }
              
                  function calculateFeeDynamic(uint _value, uint _additionalGas) constant returns(uint) {
                      uint fee = calculateFee(_value);
                      if (_additionalGas <= 7500) {
                          return fee;
                      }
                      // Assuming that absMinFee covers at least 100000 gas refund, let's add another absMinFee
                      // for every other 100000 additional gas.
                      uint additionalFee = ((_additionalGas / 100000) + 1) * absMinFee;
                      return fee + additionalFee;
                  }
              
                  function takeFee(address _feeFrom, uint _value, string _reference) noValue() checkAccess("fee") returns(bool) {
                      return _transferFee(_feeFrom, _value, _reference);
                  }
              
                  function _transfer(address _to, uint _value) internal returns(bool, bool) {
                      uint startGas = msg.gas + transferCallGas;
                      uint fee = calculateFee(_value);
                      if (!_transferFee(msg.sender, fee, "Transfer fee")) {
                          return (false, false);
                      }
                      _allow();
                      bool success = super.transfer(_to, _value);
                      _disallow();
                      if (!success) {
                          return _returnFee(msg.sender, fee);
                      }
                      return (true, _applyRefund(startGas));
                  }
              
                  function _transferFrom(address _from, address _to, uint _value) internal returns(bool, bool) {
                      uint startGas = msg.gas + transferFromCallGas;
                      _allow();
                      uint fee = calculateFee(_value);
                      if (!_transferFee(_from, fee, "Transfer fee")) {
                          return (false, false);
                      }
                      _allow();
                      bool success = super.transferFrom(_from, _to, _value);
                      _disallow();
                      if (!success) {
                          return _returnFee(_from, fee);
                      }
                      return (true, _applyRefund(startGas));
                  }
              
                  function _transferToICAP(bytes32 _icap, uint _value) internal returns(bool, bool) {
                      uint startGas = msg.gas + transferToICAPCallGas;
                      uint fee = calculateFee(_value);
                      if (!_transferFee(msg.sender, fee, "Transfer fee")) {
                          return (false, false);
                      }
                      _allow();
                      bool success = super.transferToICAP(_icap, _value);
                      _disallow();
                      if (!success) {
                          return _returnFee(msg.sender, fee);
                      }
                      return (true, _applyRefund(startGas));
                  }
              
                  function _transferFromToICAP(address _from, bytes32 _icap, uint _value) internal returns(bool, bool) {
                      uint startGas = msg.gas + transferFromToICAPCallGas;
                      uint fee = calculateFee(_value);
                      if (!_transferFee(_from, fee, "Transfer fee")) {
                          return (false, false);
                      }
                      _allow();
                      bool success = super.transferFromToICAP(_from, _icap, _value);
                      _disallow();
                      if (!success) {
                          return _returnFee(_from, fee);
                      }
                      return (true, _applyRefund(startGas));
                  }
              
                  function _transferWithReference(address _to, uint _value, string _reference) internal returns(bool, bool) {
                      uint startGas = msg.gas + transferWithReferenceCallGas;
                      uint additionalGas = _stringGas(_reference);
                      uint fee = calculateFeeDynamic(_value, additionalGas);
                      if (!_transferFee(msg.sender, fee, "Transfer fee")) {
                          return (false, false);
                      }
                      _allow();
                      bool success = super.transferWithReference(_to, _value, _reference);
                      _disallow();
                      if (!success) {
                          return _returnFee(msg.sender, fee);
                      }
                      return (true, _applyRefund(startGas + additionalGas));
                  }
              
                  function _transferFromWithReference(address _from, address _to, uint _value, string _reference) internal returns(bool, bool) {
                      uint startGas = msg.gas + transferFromWithReferenceCallGas;
                      uint additionalGas = _stringGas(_reference);
                      uint fee = calculateFeeDynamic(_value, additionalGas);
                      if (!_transferFee(_from, fee, "Transfer fee")) {
                          return (false, false);
                      }
                      _allow();
                      bool success = super.transferFromWithReference(_from, _to, _value, _reference);
                      _disallow();
                      if (!success) {
                          return _returnFee(_from, fee);
                      }
                      return (true, _applyRefund(startGas + additionalGas));
                  }
              
                  function _transferToICAPWithReference(bytes32 _icap, uint _value, string _reference) internal returns(bool, bool) {
                      uint startGas = msg.gas + transferToICAPWithReferenceCallGas;
                      uint additionalGas = _stringGas(_reference);
                      uint fee = calculateFeeDynamic(_value, additionalGas);
                      if (!_transferFee(msg.sender, fee, "Transfer fee")) {
                          return (false, false);
                      }
                      _allow();
                      bool success = super.transferToICAPWithReference(_icap, _value, _reference);
                      _disallow();
                      if (!success) {
                          return _returnFee(msg.sender, fee);
                      }
                      return (true, _applyRefund(startGas + additionalGas));
                  }
              
                  function _transferFromToICAPWithReference(address _from, bytes32 _icap, uint _value, string _reference) internal returns(bool, bool) {
                      uint startGas = msg.gas + transferFromToICAPWithReferenceCallGas;
                      uint additionalGas = _stringGas(_reference);
                      uint fee = calculateFeeDynamic(_value, additionalGas);
                      if (!_transferFee(_from, fee, "Transfer fee")) {
                          return (false, false);
                      }
                      _allow();
                      bool success = super.transferFromToICAPWithReference(_from, _icap, _value, _reference);
                      _disallow();
                      if (!success) {
                          return _returnFee(_from, fee);
                      }
                      return (true, _applyRefund(startGas + additionalGas));
                  }
              
                  function _approve(address _spender, uint _value) internal returns(bool, bool) {
                      uint startGas = msg.gas + approveCallGas;
                      // Don't take fee when enabling fee taking.
                      // Don't refund either.
                      if (_spender == address(this)) {
                          return (super.approve(_spender, _value), false);
                      }
                      uint fee = calculateFee(0);
                      if (!_transferFee(msg.sender, fee, "Approve fee")) {
                          return (false, false);
                      }
                      _allow();
                      bool success = super.approve(_spender, _value);
                      _disallow();
                      if (!success) {
                          return _returnFee(msg.sender, fee);
                      }
                      return (true, _applyRefund(startGas));
                  }
              
                  function _setCosignerAddress(address _cosigner) internal returns(bool, bool) {
                      uint startGas = msg.gas + setCosignerCallGas;
                      uint fee = calculateFee(0);
                      if (!_transferFee(msg.sender, fee, "Cosigner fee")) {
                          return (false, false);
                      }
                      if (!super.setCosignerAddress(_cosigner)) {
                          return _returnFee(msg.sender, fee);
                      }
                      return (true, _applyRefund(startGas));
                  }
              
                  function transfer(address _to, uint _value) returns(bool) {
                      bool success;
                      (success,) = _transfer(_to, _value);
                      return success;
                  }
              
                  function transferFrom(address _from, address _to, uint _value) returns(bool) {
                      bool success;
                      (success,) = _transferFrom(_from, _to, _value);
                      return success;
                  }
              
                  function transferToICAP(bytes32 _icap, uint _value) returns(bool) {
                      bool success;
                      (success,) = _transferToICAP(_icap, _value);
                      return success;
                  }
              
                  function transferFromToICAP(address _from, bytes32 _icap, uint _value) returns(bool) {
                      bool success;
                      (success,) = _transferFromToICAP(_from, _icap, _value);
                      return success;
                  }
              
                  function transferWithReference(address _to, uint _value, string _reference) returns(bool) {
                      bool success;
                      (success,) = _transferWithReference(_to, _value, _reference);
                      return success;
                  }
              
                  function transferFromWithReference(address _from, address _to, uint _value, string _reference) returns(bool) {
                      bool success;
                      (success,) = _transferFromWithReference(_from, _to, _value, _reference);
                      return success;
                  }
              
                  function transferToICAPWithReference(bytes32 _icap, uint _value, string _reference) returns(bool) {
                      bool success;
                      (success,) = _transferToICAPWithReference(_icap, _value, _reference);
                      return success;
                  }
              
                  function transferFromToICAPWithReference(address _from, bytes32 _icap, uint _value, string _reference) returns(bool) {
                      bool success;
                      (success,) = _transferFromToICAPWithReference(_from, _icap, _value, _reference);
                      return success;
                  }
              
                  function approve(address _spender, uint _value) returns(bool) {
                      bool success;
                      (success,) = _approve(_spender, _value);
                      return success;
                  }
              
                  function setCosignerAddress(address _cosigner) returns(bool) {
                      bool success;
                      (success,) = _setCosignerAddress(_cosigner);
                      return success;
                  }
              
                  function checkTransfer(address _to, uint _value) constant returns(bool, bool) {
                      return _transfer(_to, _value);
                  }
              
                  function checkTransferFrom(address _from, address _to, uint _value) constant returns(bool, bool) {
                      return _transferFrom(_from, _to, _value);
                  }
              
                  function checkTransferToICAP(bytes32 _icap, uint _value) constant returns(bool, bool) {
                      return _transferToICAP(_icap, _value);
                  }
              
                  function checkTransferFromToICAP(address _from, bytes32 _icap, uint _value) constant returns(bool, bool) {
                      return _transferFromToICAP(_from, _icap, _value);
                  }
              
                  function checkTransferWithReference(address _to, uint _value, string _reference) constant returns(bool, bool) {
                      return _transferWithReference(_to, _value, _reference);
                  }
              
                  function checkTransferFromWithReference(address _from, address _to, uint _value, string _reference) constant returns(bool, bool) {
                      return _transferFromWithReference(_from, _to, _value, _reference);
                  }
              
                  function checkTransferToICAPWithReference(bytes32 _icap, uint _value, string _reference) constant returns(bool, bool) {
                      return _transferToICAPWithReference(_icap, _value, _reference);
                  }
              
                  function checkTransferFromToICAPWithReference(address _from, bytes32 _icap, uint _value, string _reference) constant returns(bool, bool) {
                      return _transferFromToICAPWithReference(_from, _icap, _value, _reference);
                  }
              
                  function checkApprove(address _spender, uint _value) constant returns(bool, bool) {
                      return _approve(_spender, _value);
                  }
              
                  function checkSetCosignerAddress(address _cosigner) constant returns(bool, bool) {
                      return _setCosignerAddress(_cosigner);
                  }
              
                  function checkForward(bytes _data) constant returns(bool, bool) {
                      return _forward(allowedForwards[sha3(_data[0], _data[1], _data[2], _data[3])], _data);
                  }
              
                  function _forward(address _to, bytes _data) internal returns(bool, bool) {
                      uint startGas = msg.gas + forwardCallGas;
                      uint additionalGas = (_data.length * 50);  // 50 gas per byte;
                      if (_to == 0x0) {
                          return (false, _safeFalse());
                      }
                      uint fee = calculateFeeDynamic(0, additionalGas);
                      if (!_transferFee(msg.sender, fee, "Forward fee")) {
                          return (false, false);
                      }
                      if (!_to.call.value(msg.value)(_data)) {
                          _returnFee(msg.sender, fee);
                          return (false, _safeFalse());
                      }
                      return (true, _applyRefund(startGas + additionalGas));
                  }
              
                  function () returns(bool) {
                      bool success;
                      (success,) = _forward(allowedForwards[sha3(msg.sig)], msg.data);
                      return success;
                  }
              
                  function emitTransfer(address _from, address _to, uint _value) onlyMultiAsset() {
                      Transfer(_from, _to, _value);
                      if (__isAllowed) {
                          return;
                      }
                      if (feeAddress == 0x0 || _to == feeAddress || _from == feeAddress) {
                          return;
                      }
                      if (_transferFee(_from, calculateFee(_value), "Transfer fee")) {
                          return;
                      }
                      throw;
                  }
              
                  function emitApprove(address _from, address _spender, uint _value) onlyMultiAsset() {
                      Approve(_from, _spender, _value);
                      if (__isAllowed) {
                          return;
                      }
                      if (feeAddress == 0x0 || _spender == address(this)) {
                          return;
                      }
                      if (_transferFee(_from, calculateFee(0), "Approve fee")) {
                          return;
                      }
                      throw;
                  }
              }

              File 2 of 4: EventsHistory
              // This software is a subject to Ambisafe License Agreement.
              // No use or distribution is allowed without written permission from Ambisafe.
              // https://ambisafe.com/terms.pdf
              
              contract Ambi {
                  function getNodeAddress(bytes32 _nodeName) constant returns(address);
                  function hasRelation(bytes32 _nodeName, bytes32 _relation, address _to) constant returns(bool);
                  function addNode(bytes32 _nodeName, address _nodeAddress) constant returns(bool);
              }
              
              contract AmbiEnabled {
                  Ambi public ambiC;
                  bool public isImmortal;
                  bytes32 public name;
              
                  modifier checkAccess(bytes32 _role) {
                      if(address(ambiC) != 0x0 && ambiC.hasRelation(name, _role, msg.sender)){
                          _
                      }
                  }
                  
                  function getAddress(bytes32 _name) constant returns (address) {
                      return ambiC.getNodeAddress(_name);
                  }
              
                  function setAmbiAddress(address _ambi, bytes32 _name) returns (bool){
                      if(address(ambiC) != 0x0){
                          return false;
                      }
                      Ambi ambiContract = Ambi(_ambi);
                      if(ambiContract.getNodeAddress(_name)!=address(this)) {
                          if (!ambiContract.addNode(_name, address(this))){
                              return false;
                          }
                      }
                      name = _name;
                      ambiC = ambiContract;
                      return true;
                  }
              
                  function immortality() checkAccess("owner") returns(bool) {
                      isImmortal = true;
                      return true;
                  }
              
                  function remove() checkAccess("owner") returns(bool) {
                      if (isImmortal) {
                          return false;
                      }
                      selfdestruct(msg.sender);
                      return true;
                  }
              }
              
              library StackDepthLib {
                  // This will probably work with a value of 390 but no need to cut it
                  // that close in the case that the optimizer changes slightly or
                  // something causing that number to rise slightly.
                  uint constant GAS_PER_DEPTH = 400;
              
                  function checkDepth(address self, uint n) constant returns(bool) {
                      if (n == 0) return true;
                      return self.call.gas(GAS_PER_DEPTH * n)(0x21835af6, n - 1);
                  }
              
                  function __dig(uint n) constant {
                      if (n == 0) return;
                      if (!address(this).delegatecall(0x21835af6, n - 1)) throw;
                  }
              }
              
              contract Safe {
                  // Should always be placed as first modifier!
                  modifier noValue {
                      if (msg.value > 0) {
                          // Internal Out Of Gas/Throw: revert this transaction too;
                          // Call Stack Depth Limit reached: revert this transaction too;
                          // Recursive Call: safe, no any changes applied yet, we are inside of modifier.
                          _safeSend(msg.sender, msg.value);
                      }
                      _
                  }
              
                  modifier onlyHuman {
                      if (_isHuman()) {
                          _
                      }
                  }
              
                  modifier noCallback {
                      if (!isCall) {
                          _
                      }
                  }
              
                  modifier immutable(address _address) {
                      if (_address == 0) {
                          _
                      }
                  }
              
                  address stackDepthLib;
                  function setupStackDepthLib(address _stackDepthLib) immutable(address(stackDepthLib)) returns(bool) {
                      stackDepthLib = _stackDepthLib;
                      return true;
                  }
              
                  modifier requireStackDepth(uint16 _depth) {
                      if (stackDepthLib == 0x0) {
                          throw;
                      }
                      if (_depth > 1023) {
                          throw;
                      }
                      if (!stackDepthLib.delegatecall(0x32921690, stackDepthLib, _depth)) {
                          throw;
                      }
                      _
                  }
              
                  // Must not be used inside the functions that have noValue() modifier!
                  function _safeFalse() internal noValue() returns(bool) {
                      return false;
                  }
              
                  function _safeSend(address _to, uint _value) internal {
                      if (!_unsafeSend(_to, _value)) {
                          throw;
                      }
                  }
              
                  function _unsafeSend(address _to, uint _value) internal returns(bool) {
                      return _to.call.value(_value)();
                  }
              
                  function _isContract() constant internal returns(bool) {
                      return msg.sender != tx.origin;
                  }
              
                  function _isHuman() constant internal returns(bool) {
                      return !_isContract();
                  }
              
                  bool private isCall = false;
                  function _setupNoCallback() internal {
                      isCall = true;
                  }
              
                  function _finishNoCallback() internal {
                      isCall = false;
                  }
              }
              
              /**
               * @title Events History universal contract.
               *
               * Contract serves as an Events storage and version history for a particular contract type.
               * Events appear on this contract address but their definitions provided by other contracts/libraries.
               * Version info is provided for historical and informational purposes.
               *
               * Note: all the non constant functions return false instead of throwing in case if state change
               * didn't happen yet.
               */
              contract EventsHistory is AmbiEnabled, Safe {
                  // Event emitter signature to address with Event definiton mapping.
                  mapping(bytes4 => address) public emitters;
              
                  // Calling contract address to version mapping.
                  mapping(address => uint) public versions;
              
                  // Version to info mapping.
                  mapping(uint => VersionInfo) public versionInfo;
              
                  // Latest verion number.
                  uint public latestVersion;
              
                  struct VersionInfo {
                      uint block;        // Block number in which version has been introduced.
                      address by;        // Contract owner address who added version.
                      address caller;    // Address of this version calling contract.
                      string name;       // Version name, informative.
                      string changelog;  // Version changelog, informative.
                  }
              
                  /**
                   * Assign emitter address to a specified emit function signature.
                   *
                   * Can be set only once for each signature, and only by contract owner.
                   * Caller contract should be sure that emitter for a particular signature will never change.
                   *
                   * @param _eventSignature signature of the event emitting function.
                   * @param _emitter address with Event definition.
                   *
                   * @return success.
                   */
                  function addEmitter(bytes4 _eventSignature, address _emitter) noValue() checkAccess("admin") returns(bool) {
                      if (emitters[_eventSignature] != 0x0) {
                          return false;
                      }
                      emitters[_eventSignature] = _emitter;
                      return true;
                  }
              
                  /**
                   * Introduce new caller contract version specifing version information.
                   *
                   * Can be set only once for each caller, and only by contract owner.
                   * Name and changelog should not be empty.
                   *
                   * @param _caller address of the new caller.
                   * @param _name version name.
                   * @param _changelog version changelog.
                   *
                   * @return success.
                   */
                  function addVersion(address _caller, string _name, string _changelog) noValue() checkAccess("admin") returns(bool) {
                      if (versions[_caller] != 0) {
                          return false;
                      }
                      if (bytes(_name).length == 0) {
                          return false;
                      }
                      if (bytes(_changelog).length == 0) {
                          return false;
                      }
                      uint version = ++latestVersion;
                      versions[_caller] = version;
                      versionInfo[version] = VersionInfo(block.number, msg.sender, _caller, _name, _changelog);
                      return true;
                  }
              
                  /**
                   * Event emitting fallback.
                   *
                   * Can be and only called caller with assigned version.
                   * Resolves msg.sig to an emitter address, and calls it to emit an event.
                   *
                   * Throws if emit function signature is not registered, or call failed.
                   */
                  function () noValue() {
                      if (versions[msg.sender] == 0) {
                          return;
                      }
                      // Internal Out Of Gas/Throw: revert this transaction too;
                      // Call Stack Depth Limit reached: revert this transaction too;
                      // Recursive Call: safe, all changes already made.
                      if (!emitters[msg.sig].delegatecall(msg.data)) {
                          throw;
                      }
                  }
              }

              File 3 of 4: MultiAssetEmitter
              // This software is a subject to Ambisafe License Agreement.
              // No use or distribution is allowed without written permission from Ambisafe.
              // https://ambisafe.com/terms.pdf
              
              contract EventsHistory {
                  function versions(address) constant returns(uint);
              }
              
              /**
               * @title MultiAsset Emitter.
               *
               * Contains all the original event emitting function definitions and events.
               * In case of new events needed later, additional emitters can be developed.
               * All the functions is meant to be called using delegatecall.
               */
              library MultiAssetEmitter {
                  event Transfer(address indexed from, address indexed to, bytes32 indexed symbol, uint value, string reference, uint version);
                  event Issue(bytes32 indexed symbol, uint value, address by, uint version);
                  event Revoke(bytes32 indexed symbol, uint value, address by, uint version);
                  event OwnershipChange(address indexed from, address indexed to, bytes32 indexed symbol, uint version);
                  event Approve(address indexed from, address indexed spender, bytes32 indexed symbol, uint value, uint version);
                  event Recovery(address indexed from, address indexed to, address by, uint version);
                  event TransferToICAP(address indexed from, address indexed to, bytes32 indexed icap, uint value, string reference, uint version);
                  event Error(bytes32 message, uint version);
                  
                  function emitTransfer(address _from, address _to, bytes32 _symbol, uint _value, string _reference) {
                      Transfer(_from, _to, _symbol, _value, _reference, _getVersion());
                  }
              
                  function emitIssue(bytes32 _symbol, uint _value, address _by) {
                      Issue(_symbol, _value, _by, _getVersion());
                  }
              
                  function emitRevoke(bytes32 _symbol, uint _value, address _by) {
                      Revoke(_symbol, _value, _by, _getVersion());
                  }
              
                  function emitOwnershipChange(address _from, address _to, bytes32 _symbol) {
                      OwnershipChange(_from, _to, _symbol, _getVersion());
                  }
              
                  function emitApprove(address _from, address _spender, bytes32 _symbol, uint _value) {
                      Approve(_from, _spender, _symbol, _value, _getVersion());
                  }
              
                  function emitRecovery(address _from, address _to, address _by) {
                      Recovery(_from, _to, _by, _getVersion());
                  }
              
                  function emitTransferToICAP(address _from, address _to, bytes32 _icap, uint _value, string _reference) {
                      TransferToICAP(_from, _to, _icap, _value, _reference, _getVersion());
                  }
              
                  function emitError(bytes32 _message) {
                      Error(_message, _getVersion());
                  }
              
                  /**
                   * Get version number of the caller.
                   *
                   * Assuming that the call is made by EventsHistory using delegate call,
                   * context was not changed, so the caller is the address that called
                   * EventsHistory.
                   *
                   * @return current context caller version number.
                   */
                  function _getVersion() constant internal returns(uint) {
                      return EventsHistory(address(this)).versions(msg.sender);
                  }
              }

              File 4 of 4: StackDepthLib
              // https://github.com/pipermerriam/ethereum-stack-depth-lib
              
              library StackDepthLib {
                  // This will probably work with a value of 390 but no need to cut it
                  // that close in the case that the optimizer changes slightly or
                  // something causing that number to rise slightly.
                  uint constant GAS_PER_DEPTH = 400;
              
                  function checkDepth(address self, uint n) constant returns(bool) {
                      if (n == 0) return true;
                      return self.call.gas(GAS_PER_DEPTH * n)(0x21835af6, n - 1);
                  }
              
                  function __dig(uint n) constant {
                      if (n == 0) return;
                      if (!address(this).delegatecall(0x21835af6, n - 1)) throw;
                  }
              }