ETH Price: $2,149.78 (-2.04%)
Gas: 0.07 Gwei

Transaction Decoder

Block:
5101229 at Feb-16-2018 02:43:04 PM +UTC
Transaction Fee:
0.000587769979831184 ETH $1.26
Gas Used:
532,123 Gas / 1.104575408 Gwei

Emitted Events:

34 0xf5d0a2799d9b97d00646cdedf496d141b7c0a078.0xc27db32e60c045996a132819b9e17465dbe77a5998f2e58a01cfea73c66940bb( 0xc27db32e60c045996a132819b9e17465dbe77a5998f2e58a01cfea73c66940bb, 0x00000000000000000000000000000000000000000000000000000000000006ae, 0x00000000000000000000000000000000000000000000000000000000000009da, 0000000000000000000000000000000000000000000000000000000000001e50, 0000000000000000000000008acd346b9b5173fa48d1dba0009ce09c4ef1e1fe, 0000000000000000000000000000000000000000000000000000000000000000, ee907a4e336c6e0cb6da2e9b06cd7588f9a52ebc87f43df2fd3a1ae958a0f27f )
35 0xf5d0a2799d9b97d00646cdedf496d141b7c0a078.0x8fe37232ddce0f6d02ae0872f23ff840156130db40833067705dcda7a2a52402( 0x8fe37232ddce0f6d02ae0872f23ff840156130db40833067705dcda7a2a52402, 0x00000000000000000000000000000000000000000000000000000000000006ae, 0x0000000000000000000000000000000000000000000000000000000000000000, 0x00000000000000000000000000000000000000000000000000000000000009da, 8f38f3a5cd7a46fc60e72e7c75bfec1857d9f1b71f054cfb00ce00fa47fd2436 )

Account State Difference:

  Address   Before After State Difference Code
337.497783131412925372 Eth337.498370901392756556 Eth0.000587769979831184
0x4a1f1324...4317a60B6
0x814d371E...0331b08D9
0x8aCD346B...C4EF1E1fe
0.00433614 Eth
Nonce: 0
0.003748370020168816 Eth
Nonce: 1
0.000587769979831184
0xc6c0de70...a702914b8
0xE3ffd2C3...b7D8bEf23

Execution Trace

0xf5d0a2799d9b97d00646cdedf496d141b7c0a078.e8eb32ef( )
  • 0xef3e1a5d28adc0fe223d297bbbbe8c03b6a852c7.0c90525f( )
    • 0x814d371e4f77bd94079fab6acc91c9c0331b08d9.0c90525f( )
    • 0x22343bafbda91196db9423e9f56572c117f6b5e1.9ae17cea( )
      • 0xf5d0a2799d9b97d00646cdedf496d141b7c0a078.CALL( )
      • 0xf5d0a2799d9b97d00646cdedf496d141b7c0a078.CALL( )
      • 0xf5d0a2799d9b97d00646cdedf496d141b7c0a078.CALL( )
      • 0xf5d0a2799d9b97d00646cdedf496d141b7c0a078.CALL( )
      • 0x368eddb1563ced8d4299f4b0b962ad624fe1e23b.69843940( )
      • 0xc6c0de708d35fa9f21ca969f48901cda702914b8.ef12969b( )
      • 0x368eddb1563ced8d4299f4b0b962ad624fe1e23b.0b0aee69( )
      • 0xef3e1a5d28adc0fe223d297bbbbe8c03b6a852c7.c41a360a( )
        • 0x814d371e4f77bd94079fab6acc91c9c0331b08d9.c41a360a( )
        • 0x368eddb1563ced8d4299f4b0b962ad624fe1e23b.69843940( )
        • 0xc6c0de708d35fa9f21ca969f48901cda702914b8.ab80aa0e( )
        • 0x368eddb1563ced8d4299f4b0b962ad624fe1e23b.69843940( )
        • 0xc6c0de708d35fa9f21ca969f48901cda702914b8.58e52e6e( )
        • 0x368eddb1563ced8d4299f4b0b962ad624fe1e23b.69843940( )
        • LunyrToken.balanceOf( who=0x8aCD346B9B5173fa48D1DbA0009cE09C4EF1E1fe ) => ( 0 )
        • 0x368eddb1563ced8d4299f4b0b962ad624fe1e23b.5d77d8d0( )
        • 0xef3e1a5d28adc0fe223d297bbbbe8c03b6a852c7.399d617a( )
          • 0x814d371e4f77bd94079fab6acc91c9c0331b08d9.399d617a( )
          • 0xb62183f0f3b8d6f11f6da4cf80901f671f2abea5.da19891d( )
            • 0xf5d0a2799d9b97d00646cdedf496d141b7c0a078.CALL( )
            • 0xf5d0a2799d9b97d00646cdedf496d141b7c0a078.CALL( )
            • 0xef3e1a5d28adc0fe223d297bbbbe8c03b6a852c7.24610baf( )
              • 0x814d371e4f77bd94079fab6acc91c9c0331b08d9.24610baf( )
              • 0xe3ffd2c393bf21d062b3eee063bdda2b7d8bef23.859918af( )
              • 0xef3e1a5d28adc0fe223d297bbbbe8c03b6a852c7.9577a2d7( )
                • 0x814d371e4f77bd94079fab6acc91c9c0331b08d9.9577a2d7( )
                • 0x368eddb1563ced8d4299f4b0b962ad624fe1e23b.69843940( )
                • 0xef3e1a5d28adc0fe223d297bbbbe8c03b6a852c7.b6f34aca( )
                  • 0x814d371e4f77bd94079fab6acc91c9c0331b08d9.b6f34aca( )
                  • 0x368eddb1563ced8d4299f4b0b962ad624fe1e23b.69843940( )
                  • 0xef3e1a5d28adc0fe223d297bbbbe8c03b6a852c7.efbef75a( )
                    • 0x814d371e4f77bd94079fab6acc91c9c0331b08d9.efbef75a( )
                    • 0xb62183f0f3b8d6f11f6da4cf80901f671f2abea5.60c5cc3a( )
                      • 0xf5d0a2799d9b97d00646cdedf496d141b7c0a078.CALL( )
                      • 0xf5d0a2799d9b97d00646cdedf496d141b7c0a078.CALL( )
                      • 0xef3e1a5d28adc0fe223d297bbbbe8c03b6a852c7.24610baf( )
                        • 0x814d371e4f77bd94079fab6acc91c9c0331b08d9.24610baf( )
                        • 0xef3e1a5d28adc0fe223d297bbbbe8c03b6a852c7.c41a360a( )
                          • 0x814d371e4f77bd94079fab6acc91c9c0331b08d9.c41a360a( )
                          • 0xef3e1a5d28adc0fe223d297bbbbe8c03b6a852c7.dbdd0aab( )
                            • 0x814d371e4f77bd94079fab6acc91c9c0331b08d9.dbdd0aab( )
                            • 0xef3e1a5d28adc0fe223d297bbbbe8c03b6a852c7.ffbdc8cb( )
                              • 0x814d371e4f77bd94079fab6acc91c9c0331b08d9.ffbdc8cb( )
                              • 0xef3e1a5d28adc0fe223d297bbbbe8c03b6a852c7.60c5cc3a( )
                                • 0x814d371e4f77bd94079fab6acc91c9c0331b08d9.60c5cc3a( )
                                • 0x4a1f1324e9110025222d862fcaa4fa94317a60b6.60c5cc3a( )
                                • 0x641c31e32bc5bb27627437d3b4df19488b6de273.105c63de( )
                                  • 0xf5d0a2799d9b97d00646cdedf496d141b7c0a078.CALL( )
                                  • 0x368eddb1563ced8d4299f4b0b962ad624fe1e23b.69843940( )
                                  • 0x368eddb1563ced8d4299f4b0b962ad624fe1e23b.69843940( )
                                  • 0xf5d0a2799d9b97d00646cdedf496d141b7c0a078.CALL( )
                                  • 0xc6c0de708d35fa9f21ca969f48901cda702914b8.dfcef4e3( )
                                  • 0xf5d0a2799d9b97d00646cdedf496d141b7c0a078.CALL( )
                                  • 0xc6c0de708d35fa9f21ca969f48901cda702914b8.9fe9ac3d( )
                                  • 0xef3e1a5d28adc0fe223d297bbbbe8c03b6a852c7.b6f34aca( )
                                    • 0x814d371e4f77bd94079fab6acc91c9c0331b08d9.b6f34aca( )
                                    • 0xef3e1a5d28adc0fe223d297bbbbe8c03b6a852c7.9909fe5c( )
                                      • 0x814d371e4f77bd94079fab6acc91c9c0331b08d9.9909fe5c( )
                                      • 0xe3ffd2c393bf21d062b3eee063bdda2b7d8bef23.d07bff0c( )
                                      • 0xe3ffd2c393bf21d062b3eee063bdda2b7d8bef23.efbef75a( )
                                      • 0x641c31e32bc5bb27627437d3b4df19488b6de273.105c63de( )
                                        • 0xf5d0a2799d9b97d00646cdedf496d141b7c0a078.CALL( )
                                        • 0x368eddb1563ced8d4299f4b0b962ad624fe1e23b.69843940( )
                                        • 0x368eddb1563ced8d4299f4b0b962ad624fe1e23b.69843940( )
                                        • 0xf5d0a2799d9b97d00646cdedf496d141b7c0a078.CALL( )
                                        • 0xc6c0de708d35fa9f21ca969f48901cda702914b8.dfcef4e3( )
                                        • 0xf5d0a2799d9b97d00646cdedf496d141b7c0a078.CALL( )
                                        • 0xc6c0de708d35fa9f21ca969f48901cda702914b8.9fe9ac3d( )
                                        • 0xef3e1a5d28adc0fe223d297bbbbe8c03b6a852c7.9909fe5c( )
                                          • 0x814d371e4f77bd94079fab6acc91c9c0331b08d9.9909fe5c( )
                                          • 0xe3ffd2c393bf21d062b3eee063bdda2b7d8bef23.d07bff0c( )
                                          • 0xe3ffd2c393bf21d062b3eee063bdda2b7d8bef23.efbef75a( )
                                          • 0x641c31e32bc5bb27627437d3b4df19488b6de273.105c63de( )
                                            • 0xf5d0a2799d9b97d00646cdedf496d141b7c0a078.CALL( )
                                            • 0x368eddb1563ced8d4299f4b0b962ad624fe1e23b.69843940( )
                                            • 0x368eddb1563ced8d4299f4b0b962ad624fe1e23b.69843940( )
                                            • 0xf5d0a2799d9b97d00646cdedf496d141b7c0a078.CALL( )
                                            • 0xc6c0de708d35fa9f21ca969f48901cda702914b8.dfcef4e3( )
                                            • 0xf5d0a2799d9b97d00646cdedf496d141b7c0a078.CALL( )
                                            • 0xc6c0de708d35fa9f21ca969f48901cda702914b8.9fe9ac3d( )
                                            • 0xef3e1a5d28adc0fe223d297bbbbe8c03b6a852c7.9909fe5c( )
                                              • 0x814d371e4f77bd94079fab6acc91c9c0331b08d9.9909fe5c( )
                                              • 0xe3ffd2c393bf21d062b3eee063bdda2b7d8bef23.d07bff0c( )
                                              • 0xe3ffd2c393bf21d062b3eee063bdda2b7d8bef23.efbef75a( )
                                              • 0x641c31e32bc5bb27627437d3b4df19488b6de273.a521d206( )
                                                • 0xf5d0a2799d9b97d00646cdedf496d141b7c0a078.CALL( )
                                                • 0x368eddb1563ced8d4299f4b0b962ad624fe1e23b.69843940( )
                                                • 0x368eddb1563ced8d4299f4b0b962ad624fe1e23b.69843940( )
                                                • 0xf5d0a2799d9b97d00646cdedf496d141b7c0a078.CALL( )
                                                • 0xc6c0de708d35fa9f21ca969f48901cda702914b8.58e52e6e( )
                                                • 0xf5d0a2799d9b97d00646cdedf496d141b7c0a078.CALL( )
                                                • 0xc6c0de708d35fa9f21ca969f48901cda702914b8.32a4b4c7( )
                                                  • 0x5567192aae6f8eab5939a86a890fc0dc4de101d8.f4f3bdc1( )
                                                  • 0x5567192aae6f8eab5939a86a890fc0dc4de101d8.f4f3bdc1( )
                                                  • 0xf5d0a2799d9b97d00646cdedf496d141b7c0a078.CALL( )
                                                  • 0xc6c0de708d35fa9f21ca969f48901cda702914b8.ab80aa0e( )
                                                  • 0xf5d0a2799d9b97d00646cdedf496d141b7c0a078.CALL( )
                                                  • 0xc6c0de708d35fa9f21ca969f48901cda702914b8.36df3186( )
                                                    • 0x5567192aae6f8eab5939a86a890fc0dc4de101d8.f4f3bdc1( )
                                                    • 0x5567192aae6f8eab5939a86a890fc0dc4de101d8.f4f3bdc1( )
                                                      pragma solidity ^0.4.8;
                                                      
                                                      // accepted from zeppelin-solidity https://github.com/OpenZeppelin/zeppelin-solidity
                                                      /*
                                                       * ERC20 interface
                                                       * see https://github.com/ethereum/EIPs/issues/20
                                                       */
                                                      contract ERC20 {
                                                        uint public totalSupply;
                                                        function balanceOf(address who) constant returns (uint);
                                                        function allowance(address owner, address spender) constant returns (uint);
                                                      
                                                        function transfer(address to, uint value) returns (bool ok);
                                                        function transferFrom(address from, address to, uint value) returns (bool ok);
                                                        function approve(address spender, uint value) returns (bool ok);
                                                        event Transfer(address indexed from, address indexed to, uint value);
                                                        event Approval(address indexed owner, address indexed spender, uint value);
                                                      }
                                                      
                                                      
                                                      // accepted from zeppelin-solidity https://github.com/OpenZeppelin/zeppelin-solidity
                                                      
                                                      /**
                                                       * Math operations with safety checks
                                                       */
                                                      contract SafeMath {
                                                        function safeMul(uint a, uint b) internal returns (uint) {
                                                          uint c = a * b;
                                                          assert(a == 0 || c / a == b);
                                                          return c;
                                                        }
                                                      
                                                        function safeDiv(uint a, uint b) internal returns (uint) {
                                                          assert(b > 0);
                                                          uint c = a / b;
                                                          assert(a == b * c + a % b);
                                                          return c;
                                                        }
                                                      
                                                        function safeSub(uint a, uint b) internal returns (uint) {
                                                          assert(b <= a);
                                                          return a - b;
                                                        }
                                                      
                                                        function safeAdd(uint a, uint b) internal returns (uint) {
                                                          uint c = a + b;
                                                          assert(c>=a && c>=b);
                                                          return c;
                                                        }
                                                      
                                                        function max64(uint64 a, uint64 b) internal constant returns (uint64) {
                                                          return a >= b ? a : b;
                                                        }
                                                      
                                                        function min64(uint64 a, uint64 b) internal constant returns (uint64) {
                                                          return a < b ? a : b;
                                                        }
                                                      
                                                        function max256(uint256 a, uint256 b) internal constant returns (uint256) {
                                                          return a >= b ? a : b;
                                                        }
                                                      
                                                        function min256(uint256 a, uint256 b) internal constant returns (uint256) {
                                                          return a < b ? a : b;
                                                        }
                                                      
                                                        function assert(bool assertion) internal {
                                                          if (!assertion) {
                                                            throw;
                                                          }
                                                        }
                                                      }
                                                      
                                                      /// @title Multisignature wallet - Allows multiple parties to agree on transactions before execution.
                                                      /// @author Stefan George - <stefan.george@consensys.net>
                                                      contract MultiSigWallet {
                                                      
                                                          // flag to determine if address is for a real contract or not
                                                          bool public isMultiSigWallet = false;
                                                      
                                                          uint constant public MAX_OWNER_COUNT = 50;
                                                      
                                                          event Confirmation(address indexed sender, uint indexed transactionId);
                                                          event Revocation(address indexed sender, uint indexed transactionId);
                                                          event Submission(uint indexed transactionId);
                                                          event Execution(uint indexed transactionId);
                                                          event ExecutionFailure(uint indexed transactionId);
                                                          event Deposit(address indexed sender, uint value);
                                                          event OwnerAddition(address indexed owner);
                                                          event OwnerRemoval(address indexed owner);
                                                          event RequirementChange(uint required);
                                                      
                                                          mapping (uint => Transaction) public transactions;
                                                          mapping (uint => mapping (address => bool)) public confirmations;
                                                          mapping (address => bool) public isOwner;
                                                          address[] public owners;
                                                          uint public required;
                                                          uint public transactionCount;
                                                      
                                                          struct Transaction {
                                                              address destination;
                                                              uint value;
                                                              bytes data;
                                                              bool executed;
                                                          }
                                                      
                                                          modifier onlyWallet() {
                                                              if (msg.sender != address(this)) throw;
                                                              _;
                                                          }
                                                      
                                                          modifier ownerDoesNotExist(address owner) {
                                                              if (isOwner[owner]) throw;
                                                              _;
                                                          }
                                                      
                                                          modifier ownerExists(address owner) {
                                                              if (!isOwner[owner]) throw;
                                                              _;
                                                          }
                                                      
                                                          modifier transactionExists(uint transactionId) {
                                                              if (transactions[transactionId].destination == 0) throw;
                                                              _;
                                                          }
                                                      
                                                          modifier confirmed(uint transactionId, address owner) {
                                                              if (!confirmations[transactionId][owner]) throw;
                                                              _;
                                                          }
                                                      
                                                          modifier notConfirmed(uint transactionId, address owner) {
                                                              if (confirmations[transactionId][owner]) throw;
                                                              _;
                                                          }
                                                      
                                                          modifier notExecuted(uint transactionId) {
                                                              if (transactions[transactionId].executed) throw;
                                                              _;
                                                          }
                                                      
                                                          modifier notNull(address _address) {
                                                              if (_address == 0) throw;
                                                              _;
                                                          }
                                                      
                                                          modifier validRequirement(uint ownerCount, uint _required) {
                                                              if (ownerCount > MAX_OWNER_COUNT) throw;
                                                              if (_required > ownerCount) throw;
                                                              if (_required == 0) throw;
                                                              if (ownerCount == 0) throw;
                                                              _;
                                                          }
                                                      
                                                          /// @dev Fallback function allows to deposit ether.
                                                          function()
                                                              payable
                                                          {
                                                              if (msg.value > 0)
                                                                  Deposit(msg.sender, msg.value);
                                                          }
                                                      
                                                          /*
                                                           * Public functions
                                                           */
                                                          /// @dev Contract constructor sets initial owners and required number of confirmations.
                                                          /// @param _owners List of initial owners.
                                                          /// @param _required Number of required confirmations.
                                                          function MultiSigWallet(address[] _owners, uint _required)
                                                              public
                                                              validRequirement(_owners.length, _required)
                                                          {
                                                              for (uint i=0; i<_owners.length; i++) {
                                                                  if (isOwner[_owners[i]] || _owners[i] == 0) throw;
                                                                  isOwner[_owners[i]] = true;
                                                              }
                                                              isMultiSigWallet = true;
                                                              owners = _owners;
                                                              required = _required;
                                                          }
                                                      
                                                          /// @dev Allows to add a new owner. Transaction has to be sent by wallet.
                                                          /// @param owner Address of new owner.
                                                          function addOwner(address owner)
                                                              public
                                                              onlyWallet
                                                              ownerDoesNotExist(owner)
                                                              notNull(owner)
                                                              validRequirement(owners.length + 1, required)
                                                          {
                                                              isOwner[owner] = true;
                                                              owners.push(owner);
                                                              OwnerAddition(owner);
                                                          }
                                                      
                                                          /// @dev Allows to remove an owner. Transaction has to be sent by wallet.
                                                          /// @param owner Address of owner.
                                                          function removeOwner(address owner)
                                                              public
                                                              onlyWallet
                                                              ownerExists(owner)
                                                          {
                                                              isOwner[owner] = false;
                                                              for (uint i=0; i<owners.length - 1; i++)
                                                                  if (owners[i] == owner) {
                                                                      owners[i] = owners[owners.length - 1];
                                                                      break;
                                                                  }
                                                              owners.length -= 1;
                                                              if (required > owners.length)
                                                                  changeRequirement(owners.length);
                                                              OwnerRemoval(owner);
                                                          }
                                                      
                                                          /// @dev Allows to replace an owner with a new owner. Transaction has to be sent by wallet.
                                                          /// @param owner Address of owner to be replaced.
                                                          /// @param newOwner Address of new owner.
                                                          /// @param index the indx of the owner to be replaced
                                                          function replaceOwnerIndexed(address owner, address newOwner, uint index)
                                                              public
                                                              onlyWallet
                                                              ownerExists(owner)
                                                              ownerDoesNotExist(newOwner)
                                                          {
                                                              if (owners[index] != owner) throw;
                                                              owners[index] = newOwner;
                                                              isOwner[owner] = false;
                                                              isOwner[newOwner] = true;
                                                              OwnerRemoval(owner);
                                                              OwnerAddition(newOwner);
                                                          }
                                                      
                                                      
                                                          /// @dev Allows to change the number of required confirmations. Transaction has to be sent by wallet.
                                                          /// @param _required Number of required confirmations.
                                                          function changeRequirement(uint _required)
                                                              public
                                                              onlyWallet
                                                              validRequirement(owners.length, _required)
                                                          {
                                                              required = _required;
                                                              RequirementChange(_required);
                                                          }
                                                      
                                                          /// @dev Allows an owner to submit and confirm a transaction.
                                                          /// @param destination Transaction target address.
                                                          /// @param value Transaction ether value.
                                                          /// @param data Transaction data payload.
                                                          /// @return Returns transaction ID.
                                                          function submitTransaction(address destination, uint value, bytes data)
                                                              public
                                                              returns (uint transactionId)
                                                          {
                                                              transactionId = addTransaction(destination, value, data);
                                                              confirmTransaction(transactionId);
                                                          }
                                                      
                                                          /// @dev Allows an owner to confirm a transaction.
                                                          /// @param transactionId Transaction ID.
                                                          function confirmTransaction(uint transactionId)
                                                              public
                                                              ownerExists(msg.sender)
                                                              transactionExists(transactionId)
                                                              notConfirmed(transactionId, msg.sender)
                                                          {
                                                              confirmations[transactionId][msg.sender] = true;
                                                              Confirmation(msg.sender, transactionId);
                                                              executeTransaction(transactionId);
                                                          }
                                                      
                                                          /// @dev Allows an owner to revoke a confirmation for a transaction.
                                                          /// @param transactionId Transaction ID.
                                                          function revokeConfirmation(uint transactionId)
                                                              public
                                                              ownerExists(msg.sender)
                                                              confirmed(transactionId, msg.sender)
                                                              notExecuted(transactionId)
                                                          {
                                                              confirmations[transactionId][msg.sender] = false;
                                                              Revocation(msg.sender, transactionId);
                                                          }
                                                      
                                                          /// @dev Returns the confirmation status of a transaction.
                                                          /// @param transactionId Transaction ID.
                                                          /// @return Confirmation status.
                                                          function isConfirmed(uint transactionId)
                                                              public
                                                              constant
                                                              returns (bool)
                                                          {
                                                              uint count = 0;
                                                              for (uint i=0; i<owners.length; i++) {
                                                                  if (confirmations[transactionId][owners[i]])
                                                                      count += 1;
                                                                  if (count == required)
                                                                      return true;
                                                              }
                                                          }
                                                      
                                                          /*
                                                           * Internal functions
                                                           */
                                                      
                                                          /// @dev Allows anyone to execute a confirmed transaction.
                                                          /// @param transactionId Transaction ID.
                                                          function executeTransaction(uint transactionId)
                                                             internal
                                                             notExecuted(transactionId)
                                                          {
                                                              if (isConfirmed(transactionId)) {
                                                                  Transaction tx = transactions[transactionId];
                                                                  tx.executed = true;
                                                                  if (tx.destination.call.value(tx.value)(tx.data))
                                                                      Execution(transactionId);
                                                                  else {
                                                                      ExecutionFailure(transactionId);
                                                                      tx.executed = false;
                                                                  }
                                                              }
                                                          }
                                                      
                                                          /// @dev Adds a new transaction to the transaction mapping, if transaction does not exist yet.
                                                          /// @param destination Transaction target address.
                                                          /// @param value Transaction ether value.
                                                          /// @param data Transaction data payload.
                                                          /// @return Returns transaction ID.
                                                          function addTransaction(address destination, uint value, bytes data)
                                                              internal
                                                              notNull(destination)
                                                              returns (uint transactionId)
                                                          {
                                                              transactionId = transactionCount;
                                                              transactions[transactionId] = Transaction({
                                                                  destination: destination,
                                                                  value: value,
                                                                  data: data,
                                                                  executed: false
                                                              });
                                                              transactionCount += 1;
                                                              Submission(transactionId);
                                                          }
                                                      
                                                          /*
                                                           * Web3 call functions
                                                           */
                                                          /// @dev Returns number of confirmations of a transaction.
                                                          /// @param transactionId Transaction ID.
                                                          /// @return Number of confirmations.
                                                          function getConfirmationCount(uint transactionId)
                                                              public
                                                              constant
                                                              returns (uint count)
                                                          {
                                                              for (uint i=0; i<owners.length; i++)
                                                                  if (confirmations[transactionId][owners[i]])
                                                                      count += 1;
                                                          }
                                                      
                                                          /// @dev Returns total number of transactions after filers are applied.
                                                          /// @param pending Include pending transactions.
                                                          /// @param executed Include executed transactions.
                                                          /// @return Total number of transactions after filters are applied.
                                                          function getTransactionCount(bool pending, bool executed)
                                                              public
                                                              constant
                                                              returns (uint count)
                                                          {
                                                              for (uint i=0; i<transactionCount; i++)
                                                                  if ((pending && !transactions[i].executed) ||
                                                                      (executed && transactions[i].executed))
                                                                      count += 1;
                                                          }
                                                      
                                                          /// @dev Returns list of owners.
                                                          /// @return List of owner addresses.
                                                          function getOwners()
                                                              public
                                                              constant
                                                              returns (address[])
                                                          {
                                                              return owners;
                                                          }
                                                      
                                                          /// @dev Returns array with owner addresses, which confirmed transaction.
                                                          /// @param transactionId Transaction ID.
                                                          /// @return Returns array of owner addresses.
                                                          function getConfirmations(uint transactionId)
                                                              public
                                                              constant
                                                              returns (address[] _confirmations)
                                                          {
                                                              address[] memory confirmationsTemp = new address[](owners.length);
                                                              uint count = 0;
                                                              uint i;
                                                              for (i=0; i<owners.length; i++)
                                                                  if (confirmations[transactionId][owners[i]]) {
                                                                      confirmationsTemp[count] = owners[i];
                                                                      count += 1;
                                                                  }
                                                              _confirmations = new address[](count);
                                                              for (i=0; i<count; i++)
                                                                  _confirmations[i] = confirmationsTemp[i];
                                                          }
                                                      
                                                          /// @dev Returns list of transaction IDs in defined range.
                                                          /// @param from Index start position of transaction array.
                                                          /// @param to Index end position of transaction array.
                                                          /// @param pending Include pending transactions.
                                                          /// @param executed Include executed transactions.
                                                          /// @return Returns array of transaction IDs.
                                                          function getTransactionIds(uint from, uint to, bool pending, bool executed)
                                                              public
                                                              constant
                                                              returns (uint[] _transactionIds)
                                                          {
                                                              uint[] memory transactionIdsTemp = new uint[](transactionCount);
                                                              uint count = 0;
                                                              uint i;
                                                              for (i=0; i<transactionCount; i++)
                                                                if ((pending && !transactions[i].executed) ||
                                                                    (executed && transactions[i].executed))
                                                                  {
                                                                      transactionIdsTemp[count] = i;
                                                                      count += 1;
                                                                  }
                                                              _transactionIds = new uint[](to - from);
                                                              for (i=from; i<to; i++)
                                                                  _transactionIds[i - from] = transactionIdsTemp[i];
                                                          }
                                                      }
                                                      
                                                      
                                                      
                                                      contract NewToken is ERC20 {}
                                                      
                                                      contract UpgradeAgent is SafeMath {
                                                        address public owner;
                                                        bool public isUpgradeAgent;
                                                        NewToken public newToken;
                                                        uint256 public originalSupply; // the original total supply of old tokens
                                                        bool public upgradeHasBegun;
                                                        function upgradeFrom(address _from, uint256 _value) public;
                                                      }
                                                      
                                                      /// @title Time-locked vault of tokens allocated to Lunyr after 180 days
                                                      contract LUNVault is SafeMath {
                                                      
                                                          // flag to determine if address is for a real contract or not
                                                          bool public isLUNVault = false;
                                                      
                                                          LunyrToken lunyrToken;
                                                          address lunyrMultisig;
                                                          uint256 unlockedAtBlockNumber;
                                                          //uint256 public constant numBlocksLocked = 1110857;
                                                          // smaller lock for testing
                                                          uint256 public constant numBlocksLocked = 1110857;
                                                      
                                                          /// @notice Constructor function sets the Lunyr Multisig address and
                                                          /// total number of locked tokens to transfer
                                                          function LUNVault(address _lunyrMultisig) internal {
                                                              if (_lunyrMultisig == 0x0) throw;
                                                              lunyrToken = LunyrToken(msg.sender);
                                                              lunyrMultisig = _lunyrMultisig;
                                                              isLUNVault = true;
                                                              unlockedAtBlockNumber = safeAdd(block.number, numBlocksLocked); // 180 days of blocks later
                                                          }
                                                      
                                                          /// @notice Transfer locked tokens to Lunyr's multisig wallet
                                                          function unlock() external {
                                                              // Wait your turn!
                                                              if (block.number < unlockedAtBlockNumber) throw;
                                                              // Will fail if allocation (and therefore toTransfer) is 0.
                                                              if (!lunyrToken.transfer(lunyrMultisig, lunyrToken.balanceOf(this))) throw;
                                                          }
                                                      
                                                          // disallow payment this is for LUN not ether
                                                          function () { throw; }
                                                      
                                                      }
                                                      
                                                      /// @title Lunyr crowdsale contract
                                                      contract LunyrToken is SafeMath, ERC20 {
                                                      
                                                          // flag to determine if address is for a real contract or not
                                                          bool public isLunyrToken = false;
                                                      
                                                          // State machine
                                                          enum State{PreFunding, Funding, Success, Failure}
                                                      
                                                          // Token information
                                                          string public constant name = "Lunyr Token";
                                                          string public constant symbol = "LUN";
                                                          uint256 public constant decimals = 18;  // decimal places
                                                          uint256 public constant crowdfundPercentOfTotal = 78;
                                                          uint256 public constant vaultPercentOfTotal = 15;
                                                          uint256 public constant lunyrPercentOfTotal = 7;
                                                          uint256 public constant hundredPercent = 100;
                                                      
                                                          mapping (address => uint256) balances;
                                                          mapping (address => mapping (address => uint256)) allowed;
                                                      
                                                          // Upgrade information
                                                          address public upgradeMaster;
                                                          UpgradeAgent public upgradeAgent;
                                                          uint256 public totalUpgraded;
                                                      
                                                          // Crowdsale information
                                                          bool public finalizedCrowdfunding = false;
                                                          uint256 public fundingStartBlock; // crowdsale start block
                                                          uint256 public fundingEndBlock; // crowdsale end block
                                                          uint256 public constant tokensPerEther = 44; // LUN:ETH exchange rate
                                                          uint256 public constant tokenCreationMax = safeMul(250000 ether, tokensPerEther);
                                                          uint256 public constant tokenCreationMin = safeMul(25000 ether, tokensPerEther);
                                                          // for testing on testnet
                                                          //uint256 public constant tokenCreationMax = safeMul(10 ether, tokensPerEther);
                                                          //uint256 public constant tokenCreationMin = safeMul(3 ether, tokensPerEther);
                                                      
                                                          address public lunyrMultisig;
                                                          LUNVault public timeVault; // Lunyr's time-locked vault
                                                      
                                                          event Upgrade(address indexed _from, address indexed _to, uint256 _value);
                                                          event Refund(address indexed _from, uint256 _value);
                                                          event UpgradeFinalized(address sender, address upgradeAgent);
                                                          event UpgradeAgentSet(address agent);
                                                      
                                                          // For mainnet, startBlock = 3445888, endBlock = 3618688
                                                          function LunyrToken(address _lunyrMultisig,
                                                                              address _upgradeMaster,
                                                                              uint256 _fundingStartBlock,
                                                                              uint256 _fundingEndBlock) {
                                                      
                                                              if (_lunyrMultisig == 0) throw;
                                                              if (_upgradeMaster == 0) throw;
                                                              if (_fundingStartBlock <= block.number) throw;
                                                              if (_fundingEndBlock   <= _fundingStartBlock) throw;
                                                              isLunyrToken = true;
                                                              upgradeMaster = _upgradeMaster;
                                                              fundingStartBlock = _fundingStartBlock;
                                                              fundingEndBlock = _fundingEndBlock;
                                                              timeVault = new LUNVault(_lunyrMultisig);
                                                              if (!timeVault.isLUNVault()) throw;
                                                              lunyrMultisig = _lunyrMultisig;
                                                              if (!MultiSigWallet(lunyrMultisig).isMultiSigWallet()) throw;
                                                          }
                                                      
                                                          function balanceOf(address who) constant returns (uint) {
                                                              return balances[who];
                                                          }
                                                      
                                                          /// @notice Transfer `value` LUN tokens from sender's account
                                                          /// `msg.sender` to provided account address `to`.
                                                          /// @notice This function is disabled during the funding.
                                                          /// @dev Required state: Success
                                                          /// @param to The address of the recipient
                                                          /// @param value The number of LUN to transfer
                                                          /// @return Whether the transfer was successful or not
                                                          function transfer(address to, uint256 value) returns (bool ok) {
                                                              if (getState() != State.Success) throw; // Abort if crowdfunding was not a success.
                                                              if (to == 0x0) throw;
                                                              if (to == address(upgradeAgent)) throw;
                                                              //if (to == address(upgradeAgent.newToken())) throw;
                                                              uint256 senderBalance = balances[msg.sender];
                                                              if (senderBalance >= value && value > 0) {
                                                                  senderBalance = safeSub(senderBalance, value);
                                                                  balances[msg.sender] = senderBalance;
                                                                  balances[to] = safeAdd(balances[to], value);
                                                                  Transfer(msg.sender, to, value);
                                                                  return true;
                                                              }
                                                              return false;
                                                          }
                                                      
                                                          /// @notice Transfer `value` LUN tokens from sender 'from'
                                                          /// to provided account address `to`.
                                                          /// @notice This function is disabled during the funding.
                                                          /// @dev Required state: Success
                                                          /// @param from The address of the sender
                                                          /// @param to The address of the recipient
                                                          /// @param value The number of LUN to transfer
                                                          /// @return Whether the transfer was successful or not
                                                          function transferFrom(address from, address to, uint value) returns (bool ok) {
                                                              if (getState() != State.Success) throw; // Abort if not in Success state.
                                                              if (to == 0x0) throw;
                                                              if (to == address(upgradeAgent)) throw;
                                                              //if (to == address(upgradeAgent.newToken())) throw;
                                                              if (balances[from] >= value &&
                                                                  allowed[from][msg.sender] >= value)
                                                              {
                                                                  balances[to] = safeAdd(balances[to], value);
                                                                  balances[from] = safeSub(balances[from], value);
                                                                  allowed[from][msg.sender] = safeSub(allowed[from][msg.sender], value);
                                                                  Transfer(from, to, value);
                                                                  return true;
                                                              } else { return false; }
                                                          }
                                                      
                                                          /// @notice `msg.sender` approves `spender` to spend `value` tokens
                                                          /// @param spender The address of the account able to transfer the tokens
                                                          /// @param value The amount of wei to be approved for transfer
                                                          /// @return Whether the approval was successful or not
                                                          function approve(address spender, uint256 value) returns (bool ok) {
                                                              if (getState() != State.Success) throw; // Abort if not in Success state.
                                                              allowed[msg.sender][spender] = value;
                                                              Approval(msg.sender, spender, value);
                                                              return true;
                                                          }
                                                      
                                                          /// @param owner The address of the account owning tokens
                                                          /// @param spender The address of the account able to transfer the tokens
                                                          /// @return Amount of remaining tokens allowed to spent
                                                          function allowance(address owner, address spender) constant returns (uint) {
                                                              return allowed[owner][spender];
                                                          }
                                                      
                                                          // Token upgrade functionality
                                                      
                                                          /// @notice Upgrade tokens to the new token contract.
                                                          /// @dev Required state: Success
                                                          /// @param value The number of tokens to upgrade
                                                          function upgrade(uint256 value) external {
                                                              if (getState() != State.Success) throw; // Abort if not in Success state.
                                                              if (upgradeAgent.owner() == 0x0) throw; // need a real upgradeAgent address
                                                      
                                                              // Validate input value.
                                                              if (value == 0) throw;
                                                              if (value > balances[msg.sender]) throw;
                                                      
                                                              // update the balances here first before calling out (reentrancy)
                                                              balances[msg.sender] = safeSub(balances[msg.sender], value);
                                                              totalSupply = safeSub(totalSupply, value);
                                                              totalUpgraded = safeAdd(totalUpgraded, value);
                                                              upgradeAgent.upgradeFrom(msg.sender, value);
                                                              Upgrade(msg.sender, upgradeAgent, value);
                                                          }
                                                      
                                                          /// @notice Set address of upgrade target contract and enable upgrade
                                                          /// process.
                                                          /// @dev Required state: Success
                                                          /// @param agent The address of the UpgradeAgent contract
                                                          function setUpgradeAgent(address agent) external {
                                                              if (getState() != State.Success) throw; // Abort if not in Success state.
                                                              if (agent == 0x0) throw; // don't set agent to nothing
                                                              if (msg.sender != upgradeMaster) throw; // Only a master can designate the next agent
                                                              if (address(upgradeAgent) != 0x0 && upgradeAgent.upgradeHasBegun()) throw; // Don't change the upgrade agent
                                                              upgradeAgent = UpgradeAgent(agent);
                                                              // upgradeAgent must be created and linked to LunyrToken after crowdfunding is over
                                                              if (upgradeAgent.originalSupply() != totalSupply) throw;
                                                              UpgradeAgentSet(upgradeAgent);
                                                          }
                                                      
                                                          /// @notice Set address of upgrade target contract and enable upgrade
                                                          /// process.
                                                          /// @dev Required state: Success
                                                          /// @param master The address that will manage upgrades, not the upgradeAgent contract address
                                                          function setUpgradeMaster(address master) external {
                                                              if (getState() != State.Success) throw; // Abort if not in Success state.
                                                              if (master == 0x0) throw;
                                                              if (msg.sender != upgradeMaster) throw; // Only a master can designate the next master
                                                              upgradeMaster = master;
                                                          }
                                                      
                                                          function setMultiSigWallet(address newWallet) external {
                                                            if (msg.sender != lunyrMultisig) throw;
                                                            MultiSigWallet wallet = MultiSigWallet(newWallet);
                                                            if (!wallet.isMultiSigWallet()) throw;
                                                            lunyrMultisig = newWallet;
                                                          }
                                                      
                                                          // Crowdfunding:
                                                      
                                                          // don't just send ether to the contract expecting to get tokens
                                                          function() { throw; }
                                                      
                                                      
                                                          /// @notice Create tokens when funding is active.
                                                          /// @dev Required state: Funding
                                                          /// @dev State transition: -> Funding Success (only if cap reached)
                                                          function create() payable external {
                                                              // Abort if not in Funding Active state.
                                                              // The checks are split (instead of using or operator) because it is
                                                              // cheaper this way.
                                                              if (getState() != State.Funding) throw;
                                                      
                                                              // Do not allow creating 0 or more than the cap tokens.
                                                              if (msg.value == 0) throw;
                                                      
                                                              // multiply by exchange rate to get newly created token amount
                                                              uint256 createdTokens = safeMul(msg.value, tokensPerEther);
                                                      
                                                              // we are creating tokens, so increase the totalSupply
                                                              totalSupply = safeAdd(totalSupply, createdTokens);
                                                      
                                                              // don't go over the limit!
                                                              if (totalSupply > tokenCreationMax) throw;
                                                      
                                                              // Assign new tokens to the sender
                                                              balances[msg.sender] = safeAdd(balances[msg.sender], createdTokens);
                                                      
                                                              // Log token creation event
                                                              Transfer(0, msg.sender, createdTokens);
                                                          }
                                                      
                                                          /// @notice Finalize crowdfunding
                                                          /// @dev If cap was reached or crowdfunding has ended then:
                                                          /// create LUN for the Lunyr Multisig and developer,
                                                          /// transfer ETH to the Lunyr Multisig address.
                                                          /// @dev Required state: Success
                                                          function finalizeCrowdfunding() external {
                                                              // Abort if not in Funding Success state.
                                                              if (getState() != State.Success) throw; // don't finalize unless we won
                                                              if (finalizedCrowdfunding) throw; // can't finalize twice (so sneaky!)
                                                      
                                                              // prevent more creation of tokens
                                                              finalizedCrowdfunding = true;
                                                      
                                                              // Endowment: 15% of total goes to vault, timelocked for 6 months
                                                              // uint256 vaultTokens = safeDiv(safeMul(totalSupply, vaultPercentOfTotal), hundredPercent);
                                                              uint256 vaultTokens = safeDiv(safeMul(totalSupply, vaultPercentOfTotal), crowdfundPercentOfTotal);
                                                              balances[timeVault] = safeAdd(balances[timeVault], vaultTokens);
                                                              Transfer(0, timeVault, vaultTokens);
                                                      
                                                              // Endowment: 7% of total goes to lunyr for marketing and bug bounty
                                                              uint256 lunyrTokens = safeDiv(safeMul(totalSupply, lunyrPercentOfTotal), crowdfundPercentOfTotal);
                                                              balances[lunyrMultisig] = safeAdd(balances[lunyrMultisig], lunyrTokens);
                                                              Transfer(0, lunyrMultisig, lunyrTokens);
                                                      
                                                              totalSupply = safeAdd(safeAdd(totalSupply, vaultTokens), lunyrTokens);
                                                      
                                                              // Transfer ETH to the Lunyr Multisig address.
                                                              if (!lunyrMultisig.send(this.balance)) throw;
                                                          }
                                                      
                                                          /// @notice Get back the ether sent during the funding in case the funding
                                                          /// has not reached the minimum level.
                                                          /// @dev Required state: Failure
                                                          function refund() external {
                                                              // Abort if not in Funding Failure state.
                                                              if (getState() != State.Failure) throw;
                                                      
                                                              uint256 lunValue = balances[msg.sender];
                                                              if (lunValue == 0) throw;
                                                              balances[msg.sender] = 0;
                                                              totalSupply = safeSub(totalSupply, lunValue);
                                                      
                                                              uint256 ethValue = safeDiv(lunValue, tokensPerEther); // lunValue % tokensPerEther == 0
                                                              Refund(msg.sender, ethValue);
                                                              if (!msg.sender.send(ethValue)) throw;
                                                          }
                                                      
                                                          /// @notice This manages the crowdfunding state machine
                                                          /// We make it a function and do not assign the result to a variable
                                                          /// So there is no chance of the variable being stale
                                                          function getState() public constant returns (State){
                                                            // once we reach success, lock in the state
                                                            if (finalizedCrowdfunding) return State.Success;
                                                            if (block.number < fundingStartBlock) return State.PreFunding;
                                                            else if (block.number <= fundingEndBlock && totalSupply < tokenCreationMax) return State.Funding;
                                                            else if (totalSupply >= tokenCreationMin) return State.Success;
                                                            else return State.Failure;
                                                          }
                                                      }