ETH Price: $2,115.64 (+1.71%)

Contract

0x6531f133e6DeeBe7F2dcE5A0441aA7ef330B4e53
 

More Info

Private Name Tags

TokenTracker

Multichain Info

1 address found via
Transaction Hash
Method
Block
From
To
Approve245832572026-03-04 9:40:2328 hrs ago1772617223IN
Time Token
0 ETH0.000057580.39530376
Transfer239355202025-12-03 21:13:5991 days ago1764796439IN
Time Token
0 ETH0.000298822.03268579
Transfer239260362025-12-02 13:20:1193 days ago1764681611IN
Time Token
0 ETH0.000161071.09571074
Transfer228014312025-06-28 7:25:47250 days ago1751095547IN
Time Token
0 ETH0.000222041.51044157
Commit Upgrade228013242025-06-28 7:04:23250 days ago1751094263IN
Time Token
0 ETH0.00005552.35545794
Transfer228012762025-06-28 6:54:47250 days ago1751093687IN
Time Token
0 ETH0.000230591.5685644
Transfer223596992025-04-27 10:09:11312 days ago1745748551IN
Time Token
0 ETH0.000062090.42244397
Approve220870722025-03-20 9:07:23350 days ago1742461643IN
Time Token
0 ETH0.000206051.41398161
Transfer220796912025-03-19 8:21:47351 days ago1742372507IN
Time Token
0 ETH0.000074690.50818758
Transfer219837062025-03-05 22:35:35364 days ago1741214135IN
Time Token
0 ETH0.000270251.83850887
Transfer218847012025-02-20 2:50:35378 days ago1740019835IN
Time Token
0 ETH0.000266621.81395208
Transfer217051302025-01-26 0:32:47403 days ago1737851567IN
Time Token
0 ETH0.000880385.98912182
Transfer216538502025-01-18 20:46:11410 days ago1737233171IN
Time Token
0 ETH0.001448459.5428276
Transfer213582162024-12-08 13:57:23452 days ago1733666243IN
Time Token
0 ETH0.0017546411.93754929
Transfer213505432024-12-07 12:13:59453 days ago1733573639IN
Time Token
0 ETH0.0010756912.77349371
Transfer211346062024-11-07 8:33:11483 days ago1730968391IN
Time Token
0 ETH0.0016500311.22584541
Transfer209272292024-10-09 9:46:23512 days ago1728467183IN
Time Token
0 ETH0.0018933912.88046798
Transfer208109562024-09-23 4:39:35528 days ago1727066375IN
Time Token
0 ETH0.0022057221.91957688
Transfer207471492024-09-14 6:45:47537 days ago1726296347IN
Time Token
0 ETH0.000322752.12640175
Transfer207470912024-09-14 6:34:11537 days ago1726295651IN
Time Token
0 ETH0.000316022.08205637
Transfer207459162024-09-14 2:37:23537 days ago1726281443IN
Time Token
0 ETH0.000164861.95209963
Approve207251962024-09-11 5:10:59540 days ago1726031459IN
Time Token
0 ETH0.000229521.57507206
Approve207251772024-09-11 5:07:11540 days ago1726031231IN
Time Token
0 ETH0.000248921.7081572
Transfer205541322024-08-18 7:51:23564 days ago1723967483IN
Time Token
0 ETH0.000310932.11527881
Transfer204932812024-08-09 19:57:59572 days ago1723233479IN
Time Token
0 ETH0.000332753.93954581
View all transactions

Latest 7 internal transactions

Advanced mode:
Parent Transaction Hash Method Block
From
To
Transfer57190532018-06-02 10:29:212833 days ago1527935361
Time Token
0.00001 ETH
Transfer54642152018-04-18 19:15:382877 days ago1524078938
Time Token
0.0001 ETH
Transfer44283232017-10-25 18:06:273052 days ago1508954787
Time Token
0.1 ETH
Transfer40479812017-07-20 10:07:093150 days ago1500545229
Time Token
0.53227934 ETH
Transfer35714422017-04-20 23:01:433240 days ago1492729303
Time Token
0.01 ETH
Transfer35362722017-04-14 21:32:463246 days ago1492205566
Time Token
0.01305335 ETH
Transfer35000612017-04-08 16:17:093252 days ago1491668229
Time Token
1 ETH
Loading...
Loading
Loading...
Loading
Cross-Chain Transactions

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
ChronoBankAssetProxy

Compiler Version
v0.4.8+commit.60cc1668

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion
/**
 *Submitted for verification at Etherscan.io on 2018-03-06
*/

pragma solidity ^0.4.4;

contract Owned {
    address public contractOwner;
    address public pendingContractOwner;

    function Owned() {
        contractOwner = msg.sender;
    }

    modifier onlyContractOwner() {
        if (contractOwner == msg.sender) {
            _;
        }
    }

    /**
     * Prepares ownership pass.
     *
     * Can only be called by current owner.
     *
     * @param _to address of the next owner.
     *
     * @return success.
     */
    function changeContractOwnership(address _to) onlyContractOwner() returns(bool) {
        pendingContractOwner = _to;
        return true;
    }

    /**
     * Finalize ownership pass.
     *
     * Can only be called by pending owner.
     *
     * @return success.
     */
    function claimContractOwnership() returns(bool) {
        if (pendingContractOwner != msg.sender) {
            return false;
        }
        contractOwner = pendingContractOwner;
        delete pendingContractOwner;
        return true;
    }
}


contract Emitter {
    function emitTransfer(address _from, address _to, bytes32 _symbol, uint _value, string _reference);
    function emitIssue(bytes32 _symbol, uint _value, address _by);
    function emitRevoke(bytes32 _symbol, uint _value, address _by);
    function emitOwnershipChange(address _from, address _to, bytes32 _symbol);
    function emitApprove(address _from, address _spender, bytes32 _symbol, uint _value);
    function emitRecovery(address _from, address _to, address _by);
    function emitError(bytes32 _message);
}

contract Proxy {
    function emitTransfer(address _from, address _to, uint _value);
    function emitApprove(address _from, address _spender, uint _value);
}

/**
 * @title ChronoBank Platform.
 *
 * The official ChronoBank assets platform powering TIME and LHT tokens, and possibly
 * other unknown tokens needed later.
 * Platform uses EventsHistory contract to keep events, so that in case it needs to be redeployed
 * at some point, all the events keep appearing at the same place.
 *
 * Every asset is meant to be used through a proxy contract. Only one proxy contract have access
 * rights for a particular asset.
 *
 * Features: transfers, allowances, supply adjustments, lost wallet access recovery.
 *
 * Note: all the non constant functions return false instead of throwing in case if state change
 * didn't happen yet.
 */
contract ChronoBankPlatform is Owned {
    // Structure of a particular asset.
    struct Asset {
        uint owner;                       // Asset's owner id.
        uint totalSupply;                 // Asset's total supply.
        string name;                      // Asset's name, for information purposes.
        string description;               // Asset's description, for information purposes.
        bool isReissuable;                // Indicates if asset have dynamic of fixed supply.
        uint8 baseUnit;                   // Proposed number of decimals.
        mapping(uint => Wallet) wallets;  // Holders wallets.
    }

    // Structure of an asset holder wallet for particular asset.
    struct Wallet {
        uint balance;
        mapping(uint => uint) allowance;
    }

    // Structure of an asset holder.
    struct Holder {
        address addr;                    // Current address of the holder.
        mapping(address => bool) trust;  // Addresses that are trusted with recovery proocedure.
    }

    // Iterable mapping pattern is used for holders.
    uint public holdersCount;
    mapping(uint => Holder) public holders;

    // This is an access address mapping. Many addresses may have access to a single holder.
    mapping(address => uint) holderIndex;

    // Asset symbol to asset mapping.
    mapping(bytes32 => Asset) public assets;

    // Asset symbol to asset proxy mapping.
    mapping(bytes32 => address) public proxies;

    // Should use interface of the emitter, but address of events history.
    Emitter public eventsHistory;

    /**
     * Emits Error event with specified error message.
     *
     * Should only be used if no state changes happened.
     *
     * @param _message error message.
     */
    function _error(bytes32 _message) internal {
        eventsHistory.emitError(_message);
    }

    /**
     * Sets EventsHstory contract address.
     *
     * Can be set only once, and only by contract owner.
     *
     * @param _eventsHistory EventsHistory contract address.
     *
     * @return success.
     */
    function setupEventsHistory(address _eventsHistory) onlyContractOwner() returns(bool) {
        if (address(eventsHistory) != 0) {
            return false;
        }
        eventsHistory = Emitter(_eventsHistory);
        return true;
    }

    /**
     * Emits Error if called not by asset owner.
     */
    modifier onlyOwner(bytes32 _symbol) {
        if (isOwner(msg.sender, _symbol)) {
            _;
        } else {
            _error("Only owner: access denied");
        }
    }

    /**
     * Emits Error if called not by asset proxy.
     */
    modifier onlyProxy(bytes32 _symbol) {
        if (proxies[_symbol] == msg.sender) {
            _;
        } else {
            _error("Only proxy: access denied");
        }
    }

    /**
     * Emits Error if _from doesn't trust _to.
     */
    modifier checkTrust(address _from, address _to) {
        if (isTrusted(_from, _to)) {
            _;
        } else {
            _error("Only trusted: access denied");
        }
    }

    /**
     * Check asset existance.
     *
     * @param _symbol asset symbol.
     *
     * @return asset existance.
     */
    function isCreated(bytes32 _symbol) constant returns(bool) {
        return assets[_symbol].owner != 0;
    }

    /**
     * Returns asset decimals.
     *
     * @param _symbol asset symbol.
     *
     * @return asset decimals.
     */
    function baseUnit(bytes32 _symbol) constant returns(uint8) {
        return assets[_symbol].baseUnit;
    }

    /**
     * Returns asset name.
     *
     * @param _symbol asset symbol.
     *
     * @return asset name.
     */
    function name(bytes32 _symbol) constant returns(string) {
        return assets[_symbol].name;
    }

    /**
     * Returns asset description.
     *
     * @param _symbol asset symbol.
     *
     * @return asset description.
     */
    function description(bytes32 _symbol) constant returns(string) {
        return assets[_symbol].description;
    }

    /**
     * Returns asset reissuability.
     *
     * @param _symbol asset symbol.
     *
     * @return asset reissuability.
     */
    function isReissuable(bytes32 _symbol) constant returns(bool) {
        return assets[_symbol].isReissuable;
    }

    /**
     * Returns asset owner address.
     *
     * @param _symbol asset symbol.
     *
     * @return asset owner address.
     */
    function owner(bytes32 _symbol) constant returns(address) {
        return holders[assets[_symbol].owner].addr;
    }

    /**
     * Check if specified address has asset owner rights.
     *
     * @param _owner address to check.
     * @param _symbol asset symbol.
     *
     * @return owner rights availability.
     */
    function isOwner(address _owner, bytes32 _symbol) constant returns(bool) {
        return isCreated(_symbol) && (assets[_symbol].owner == getHolderId(_owner));
    }

    /**
     * Returns asset total supply.
     *
     * @param _symbol asset symbol.
     *
     * @return asset total supply.
     */
    function totalSupply(bytes32 _symbol) constant returns(uint) {
        return assets[_symbol].totalSupply;
    }

    /**
     * Returns asset balance for a particular holder.
     *
     * @param _holder holder address.
     * @param _symbol asset symbol.
     *
     * @return holder balance.
     */
    function balanceOf(address _holder, bytes32 _symbol) constant returns(uint) {
        return _balanceOf(getHolderId(_holder), _symbol);
    }

    /**
     * Returns asset balance for a particular holder id.
     *
     * @param _holderId holder id.
     * @param _symbol asset symbol.
     *
     * @return holder balance.
     */
    function _balanceOf(uint _holderId, bytes32 _symbol) constant returns(uint) {
        return assets[_symbol].wallets[_holderId].balance;
    }

    /**
     * Returns current address for a particular holder id.
     *
     * @param _holderId holder id.
     *
     * @return holder address.
     */
    function _address(uint _holderId) constant returns(address) {
        return holders[_holderId].addr;
    }

    /**
     * Sets Proxy contract address for a particular asset.
     *
     * Can be set only once for each asset, and only by contract owner.
     *
     * @param _address Proxy contract address.
     * @param _symbol asset symbol.
     *
     * @return success.
     */
    function setProxy(address _address, bytes32 _symbol) onlyContractOwner() returns(bool) {
        if (proxies[_symbol] != 0x0) {
            return false;
        }
        proxies[_symbol] = _address;
        return true;
    }

    /**
     * Transfers asset balance between holders wallets.
     *
     * @param _fromId holder id to take from.
     * @param _toId holder id to give to.
     * @param _value amount to transfer.
     * @param _symbol asset symbol.
     */
    function _transferDirect(uint _fromId, uint _toId, uint _value, bytes32 _symbol) internal {
        assets[_symbol].wallets[_fromId].balance -= _value;
        assets[_symbol].wallets[_toId].balance += _value;
    }

    /**
     * Transfers asset balance between holders wallets.
     *
     * Performs sanity checks and takes care of allowances adjustment.
     *
     * @param _fromId holder id to take from.
     * @param _toId holder id to give to.
     * @param _value amount to transfer.
     * @param _symbol asset symbol.
     * @param _reference transfer comment to be included in a Transfer event.
     * @param _senderId transfer initiator holder id.
     *
     * @return success.
     */
    function _transfer(uint _fromId, uint _toId, uint _value, bytes32 _symbol, string _reference, uint _senderId) internal returns(bool) {
        // Should not allow to send to oneself.
        if (_fromId == _toId) {
            _error("Cannot send to oneself");
            return false;
        }
        // Should have positive value.
        if (_value == 0) {
            _error("Cannot send 0 value");
            return false;
        }
        // Should have enough balance.
        if (_balanceOf(_fromId, _symbol) < _value) {
            _error("Insufficient balance");
            return false;
        }
        // Should have enough allowance.
        if (_fromId != _senderId && _allowance(_fromId, _senderId, _symbol) < _value) {
            _error("Not enough allowance");
            return false;
        }
        _transferDirect(_fromId, _toId, _value, _symbol);
        // Adjust allowance.
        if (_fromId != _senderId) {
            assets[_symbol].wallets[_fromId].allowance[_senderId] -= _value;
        }
        // Internal Out Of Gas/Throw: revert this transaction too;
        // Call Stack Depth Limit reached: n/a after HF 4;
        // Recursive Call: safe, all changes already made.
        eventsHistory.emitTransfer(_address(_fromId), _address(_toId), _symbol, _value, _reference);
        _proxyTransferEvent(_fromId, _toId, _value, _symbol);
        return true;
    }

    /**
     * Transfers asset balance between holders wallets.
     *
     * Can only be called by asset proxy.
     *
     * @param _to holder address to give to.
     * @param _value amount to transfer.
     * @param _symbol asset symbol.
     * @param _reference transfer comment to be included in a Transfer event.
     * @param _sender transfer initiator address.
     *
     * @return success.
     */
    function proxyTransferWithReference(address _to, uint _value, bytes32 _symbol, string _reference, address _sender) onlyProxy(_symbol) returns(bool) {
        return _transfer(getHolderId(_sender), _createHolderId(_to), _value, _symbol, _reference, getHolderId(_sender));
    }

    /**
     * Ask asset Proxy contract to emit ERC20 compliant Transfer event.
     *
     * @param _fromId holder id to take from.
     * @param _toId holder id to give to.
     * @param _value amount to transfer.
     * @param _symbol asset symbol.
     */
    function _proxyTransferEvent(uint _fromId, uint _toId, uint _value, bytes32 _symbol) internal {
        if (proxies[_symbol] != 0x0) {
            // Internal Out Of Gas/Throw: revert this transaction too;
            // Call Stack Depth Limit reached: n/a after HF 4;
            // Recursive Call: safe, all changes already made.
            Proxy(proxies[_symbol]).emitTransfer(_address(_fromId), _address(_toId), _value);
        }
    }

    /**
     * Returns holder id for the specified address.
     *
     * @param _holder holder address.
     *
     * @return holder id.
     */
    function getHolderId(address _holder) constant returns(uint) {
        return holderIndex[_holder];
    }

    /**
     * Returns holder id for the specified address, creates it if needed.
     *
     * @param _holder holder address.
     *
     * @return holder id.
     */
    function _createHolderId(address _holder) internal returns(uint) {
        uint holderId = holderIndex[_holder];
        if (holderId == 0) {
            holderId = ++holdersCount;
            holders[holderId].addr = _holder;
            holderIndex[_holder] = holderId;
        }
        return holderId;
    }

    /**
     * Issues new asset token on the platform.
     *
     * Tokens issued with this call go straight to contract owner.
     * Each symbol can be issued only once, and only by contract owner.
     *
     * @param _symbol asset symbol.
     * @param _value amount of tokens to issue immediately.
     * @param _name name of the asset.
     * @param _description description for the asset.
     * @param _baseUnit number of decimals.
     * @param _isReissuable dynamic or fixed supply.
     *
     * @return success.
     */
    function issueAsset(bytes32 _symbol, uint _value, string _name, string _description, uint8 _baseUnit, bool _isReissuable) onlyContractOwner() returns(bool) {
        // Should have positive value if supply is going to be fixed.
        if (_value == 0 && !_isReissuable) {
            _error("Cannot issue 0 value fixed asset");
            return false;
        }
        // Should not be issued yet.
        if (isCreated(_symbol)) {
            _error("Asset already issued");
            return false;
        }
        uint holderId = _createHolderId(msg.sender);

        assets[_symbol] = Asset(holderId, _value, _name, _description, _isReissuable, _baseUnit);
        assets[_symbol].wallets[holderId].balance = _value;
        // Internal Out Of Gas/Throw: revert this transaction too;
        // Call Stack Depth Limit reached: n/a after HF 4;
        // Recursive Call: safe, all changes already made.
        eventsHistory.emitIssue(_symbol, _value, _address(holderId));
        return true;
    }

    /**
     * Issues additional asset tokens if the asset have dynamic supply.
     *
     * Tokens issued with this call go straight to asset owner.
     * Can only be called by asset owner.
     *
     * @param _symbol asset symbol.
     * @param _value amount of additional tokens to issue.
     *
     * @return success.
     */
    function reissueAsset(bytes32 _symbol, uint _value) onlyOwner(_symbol) returns(bool) {
        // Should have positive value.
        if (_value == 0) {
            _error("Cannot reissue 0 value");
            return false;
        }
        Asset asset = assets[_symbol];
        // Should have dynamic supply.
        if (!asset.isReissuable) {
            _error("Cannot reissue fixed asset");
            return false;
        }
        // Resulting total supply should not overflow.
        if (asset.totalSupply + _value < asset.totalSupply) {
            _error("Total supply overflow");
            return false;
        }
        uint holderId = getHolderId(msg.sender);
        asset.wallets[holderId].balance += _value;
        asset.totalSupply += _value;
        // Internal Out Of Gas/Throw: revert this transaction too;
        // Call Stack Depth Limit reached: n/a after HF 4;
        // Recursive Call: safe, all changes already made.
        eventsHistory.emitIssue(_symbol, _value, _address(holderId));
        _proxyTransferEvent(0, holderId, _value, _symbol);
        return true;
    }

    /**
     * Destroys specified amount of senders asset tokens.
     *
     * @param _symbol asset symbol.
     * @param _value amount of tokens to destroy.
     *
     * @return success.
     */
    function revokeAsset(bytes32 _symbol, uint _value) returns(bool) {
        // Should have positive value.
        if (_value == 0) {
            _error("Cannot revoke 0 value");
            return false;
        }
        Asset asset = assets[_symbol];
        uint holderId = getHolderId(msg.sender);
        // Should have enough tokens.
        if (asset.wallets[holderId].balance < _value) {
            _error("Not enough tokens to revoke");
            return false;
        }
        asset.wallets[holderId].balance -= _value;
        asset.totalSupply -= _value;
        // Internal Out Of Gas/Throw: revert this transaction too;
        // Call Stack Depth Limit reached: n/a after HF 4;
        // Recursive Call: safe, all changes already made.
        eventsHistory.emitRevoke(_symbol, _value, _address(holderId));
        _proxyTransferEvent(holderId, 0, _value, _symbol);
        return true;
    }

    /**
     * Passes asset ownership to specified address.
     *
     * Only ownership is changed, balances are not touched.
     * Can only be called by asset owner.
     *
     * @param _symbol asset symbol.
     * @param _newOwner address to become a new owner.
     *
     * @return success.
     */
    function changeOwnership(bytes32 _symbol, address _newOwner) onlyOwner(_symbol) returns(bool) {
        Asset asset = assets[_symbol];
        uint newOwnerId = _createHolderId(_newOwner);
        // Should pass ownership to another holder.
        if (asset.owner == newOwnerId) {
            _error("Cannot pass ownership to oneself");
            return false;
        }
        address oldOwner = _address(asset.owner);
        asset.owner = newOwnerId;
        // Internal Out Of Gas/Throw: revert this transaction too;
        // Call Stack Depth Limit reached: n/a after HF 4;
        // Recursive Call: safe, all changes already made.
        eventsHistory.emitOwnershipChange(oldOwner, _address(newOwnerId), _symbol);
        return true;
    }

    /**
     * Check if specified holder trusts an address with recovery procedure.
     *
     * @param _from truster.
     * @param _to trustee.
     *
     * @return trust existance.
     */
    function isTrusted(address _from, address _to) constant returns(bool) {
        return holders[getHolderId(_from)].trust[_to];
    }

    /**
     * Trust an address to perform recovery procedure for the caller.
     *
     * @param _to trustee.
     *
     * @return success.
     */
    function trust(address _to) returns(bool) {
        uint fromId = _createHolderId(msg.sender);
        // Should trust to another address.
        if (fromId == getHolderId(_to)) {
            _error("Cannot trust to oneself");
            return false;
        }
        // Should trust to yet untrusted.
        if (isTrusted(msg.sender, _to)) {
            _error("Already trusted");
            return false;
        }
        holders[fromId].trust[_to] = true;
        return true;
    }

    /**
     * Revoke trust to perform recovery procedure from an address.
     *
     * @param _to trustee.
     *
     * @return success.
     */
    function distrust(address _to) checkTrust(msg.sender, _to) returns(bool) {
        holders[getHolderId(msg.sender)].trust[_to] = false;
        return true;
    }

    /**
     * Perform recovery procedure.
     *
     * This function logic is actually more of an addAccess(uint _holderId, address _to).
     * It grants another address access to recovery subject wallets.
     * Can only be called by trustee of recovery subject.
     *
     * @param _from holder address to recover from.
     * @param _to address to grant access to.
     *
     * @return success.
     */
    function recover(address _from, address _to) checkTrust(_from, msg.sender) returns(bool) {
        // Should recover to previously unused address.
        if (getHolderId(_to) != 0) {
            _error("Should recover to new address");
            return false;
        }
        // We take current holder address because it might not equal _from.
        // It is possible to recover from any old holder address, but event should have the current one.
        address from = holders[getHolderId(_from)].addr;
        holders[getHolderId(_from)].addr = _to;
        holderIndex[_to] = getHolderId(_from);
        // 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.
        eventsHistory.emitRecovery(from, _to, msg.sender);
        return true;
    }

    /**
     * Sets asset spending allowance for a specified spender.
     *
     * Note: to revoke allowance, one needs to set allowance to 0.
     *
     * @param _spenderId holder id to set allowance for.
     * @param _value amount to allow.
     * @param _symbol asset symbol.
     * @param _senderId approve initiator holder id.
     *
     * @return success.
     */
    function _approve(uint _spenderId, uint _value, bytes32 _symbol, uint _senderId) internal returns(bool) {
        // Asset should exist.
        if (!isCreated(_symbol)) {
            _error("Asset is not issued");
            return false;
        }
        // Should allow to another holder.
        if (_senderId == _spenderId) {
            _error("Cannot approve to oneself");
            return false;
        }
        assets[_symbol].wallets[_senderId].allowance[_spenderId] = _value;
        // 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.
        eventsHistory.emitApprove(_address(_senderId), _address(_spenderId), _symbol, _value);
        if (proxies[_symbol] != 0x0) {
            // Internal Out Of Gas/Throw: revert this transaction too;
            // Call Stack Depth Limit reached: n/a after HF 4;
            // Recursive Call: safe, all changes already made.
            Proxy(proxies[_symbol]).emitApprove(_address(_senderId), _address(_spenderId), _value);
        }
        return true;
    }

    /**
     * Sets asset spending allowance for a specified spender.
     *
     * Can only be called by asset proxy.
     *
     * @param _spender holder address to set allowance to.
     * @param _value amount to allow.
     * @param _symbol asset symbol.
     * @param _sender approve initiator address.
     *
     * @return success.
     */
    function proxyApprove(address _spender, uint _value, bytes32 _symbol, address _sender) onlyProxy(_symbol) returns(bool) {
        return _approve(_createHolderId(_spender), _value, _symbol, _createHolderId(_sender));
    }

    /**
     * Returns asset allowance from one holder to another.
     *
     * @param _from holder that allowed spending.
     * @param _spender holder that is allowed to spend.
     * @param _symbol asset symbol.
     *
     * @return holder to spender allowance.
     */
    function allowance(address _from, address _spender, bytes32 _symbol) constant returns(uint) {
        return _allowance(getHolderId(_from), getHolderId(_spender), _symbol);
    }

    /**
     * Returns asset allowance from one holder to another.
     *
     * @param _fromId holder id that allowed spending.
     * @param _toId holder id that is allowed to spend.
     * @param _symbol asset symbol.
     *
     * @return holder to spender allowance.
     */
    function _allowance(uint _fromId, uint _toId, bytes32 _symbol) constant internal returns(uint) {
        return assets[_symbol].wallets[_fromId].allowance[_toId];
    }

    /**
     * Prforms allowance transfer of asset balance between holders wallets.
     *
     * Can only be called by asset proxy.
     *
     * @param _from holder address to take from.
     * @param _to holder address to give to.
     * @param _value amount to transfer.
     * @param _symbol asset symbol.
     * @param _reference transfer comment to be included in a Transfer event.
     * @param _sender allowance transfer initiator address.
     *
     * @return success.
     */
    function proxyTransferFromWithReference(address _from, address _to, uint _value, bytes32 _symbol, string _reference, address _sender) onlyProxy(_symbol) returns(bool) {
        return _transfer(getHolderId(_from), _createHolderId(_to), _value, _symbol, _reference, getHolderId(_sender));
    }
}

contract ChronoBankAsset {
    function __transferWithReference(address _to, uint _value, string _reference, address _sender) returns(bool);
    function __transferFromWithReference(address _from, address _to, uint _value, string _reference, address _sender) returns(bool);
    function __approve(address _spender, uint _value, address _sender) returns(bool);
    function __process(bytes _data, address _sender) payable {
        throw;
    }
}

contract ERC20 {
    event Transfer(address indexed from, address indexed to, uint256 value);
    event Approval(address indexed from, address indexed spender, uint256 value);

    function totalSupply() constant returns (uint256 supply);
    function balanceOf(address _owner) constant returns (uint256 balance);
    function transfer(address _to, uint256 _value) returns (bool success);
    function transferFrom(address _from, address _to, uint256 _value) returns (bool success);
    function approve(address _spender, uint256 _value) returns (bool success);
    function allowance(address _owner, address _spender) constant returns (uint256 remaining);
}

contract ChronoBankAssetProxy is ERC20 {
    // Assigned platform, immutable.
    ChronoBankPlatform public chronoBankPlatform;

    // Assigned symbol, immutable.
    bytes32 smbl;

    // Assigned name, immutable.
    string public name;

    string public symbol;

    /**
     * Sets platform address, assigns symbol and name.
     *
     * Can be set only once.
     *
     * @param _chronoBankPlatform platform contract address.
     * @param _symbol assigned symbol.
     * @param _name assigned name.
     *
     * @return success.
     */
    function init(ChronoBankPlatform _chronoBankPlatform, string _symbol, string _name) returns(bool) {
        if (address(chronoBankPlatform) != 0x0) {
            return false;
        }
        chronoBankPlatform = _chronoBankPlatform;
        symbol = _symbol;
        smbl = stringToBytes32(_symbol);
        name = _name;
        return true;
    }

function stringToBytes32(string memory source) returns (bytes32 result) {
    assembly {
        result := mload(add(source, 32))
    }
}

    /**
     * Only platform is allowed to call.
     */
    modifier onlyChronoBankPlatform() {
        if (msg.sender == address(chronoBankPlatform)) {
            _;
        }
    }

    /**
     * Only current asset owner is allowed to call.
     */
    modifier onlyAssetOwner() {
        if (chronoBankPlatform.isOwner(msg.sender, smbl)) {
            _;
        }
    }

    /**
     * Returns asset implementation contract for current caller.
     *
     * @return asset implementation contract.
     */
    function _getAsset() internal returns(ChronoBankAsset) {
        return ChronoBankAsset(getVersionFor(msg.sender));
    }

    /**
     * Returns asset total supply.
     *
     * @return asset total supply.
     */
    function totalSupply() constant returns(uint) {
        return chronoBankPlatform.totalSupply(smbl);
    }

    /**
     * Returns asset balance for a particular holder.
     *
     * @param _owner holder address.
     *
     * @return holder balance.
     */
    function balanceOf(address _owner) constant returns(uint) {
        return chronoBankPlatform.balanceOf(_owner, smbl);
    }

    /**
     * Returns asset allowance from one holder to another.
     *
     * @param _from holder that allowed spending.
     * @param _spender holder that is allowed to spend.
     *
     * @return holder to spender allowance.
     */
    function allowance(address _from, address _spender) constant returns(uint) {
        return chronoBankPlatform.allowance(_from, _spender, smbl);
    }

    /**
     * Returns asset decimals.
     *
     * @return asset decimals.
     */
    function decimals() constant returns(uint8) {
        return chronoBankPlatform.baseUnit(smbl);
    }

    /**
     * Transfers asset balance from the caller to specified receiver.
     *
     * @param _to holder address to give to.
     * @param _value amount to transfer.
     *
     * @return success.
     */
    function transfer(address _to, uint _value) returns(bool) {
        return _transferWithReference(_to, _value, "");
    }

    /**
     * Transfers asset balance from the caller to specified receiver adding specified comment.
     *
     * @param _to holder address to give to.
     * @param _value amount to transfer.
     * @param _reference transfer comment to be included in a platform's Transfer event.
     *
     * @return success.
     */
    function transferWithReference(address _to, uint _value, string _reference) returns(bool) {
        return _transferWithReference(_to, _value, _reference);
    }

    /**
     * Resolves asset implementation contract for the caller and forwards there arguments along with
     * the caller address.
     *
     * @return success.
     */
    function _transferWithReference(address _to, uint _value, string _reference) internal returns(bool) {
        return _getAsset().__transferWithReference(_to, _value, _reference, msg.sender);
    }

    /**
     * Performs transfer call on the platform by the name of specified sender.
     *
     * Can only be called by asset implementation contract assigned to sender.
     *
     * @param _to holder address to give to.
     * @param _value amount to transfer.
     * @param _reference transfer comment to be included in a platform's Transfer event.
     * @param _sender initial caller.
     *
     * @return success.
     */
    function __transferWithReference(address _to, uint _value, string _reference, address _sender) onlyAccess(_sender) returns(bool) {
        return chronoBankPlatform.proxyTransferWithReference(_to, _value, smbl, _reference, _sender);
    }

    /**
     * Prforms allowance transfer of asset balance between holders.
     *
     * @param _from holder address to take from.
     * @param _to holder address to give to.
     * @param _value amount to transfer.
     *
     * @return success.
     */
    function transferFrom(address _from, address _to, uint _value) returns(bool) {
        return _transferFromWithReference(_from, _to, _value, "");
    }

    /**
     * Prforms allowance transfer of asset balance between holders adding specified comment.
     *
     * @param _from holder address to take from.
     * @param _to holder address to give to.
     * @param _value amount to transfer.
     * @param _reference transfer comment to be included in a platform's Transfer event.
     *
     * @return success.
     */
    function transferFromWithReference(address _from, address _to, uint _value, string _reference) returns(bool) {
        return _transferFromWithReference(_from, _to, _value, _reference);
    }

    /**
     * Resolves asset implementation contract for the caller and forwards there arguments along with
     * the caller address.
     *
     * @return success.
     */
    function _transferFromWithReference(address _from, address _to, uint _value, string _reference) internal returns(bool) {
        return _getAsset().__transferFromWithReference(_from, _to, _value, _reference, msg.sender);
    }

    /**
     * Performs allowance transfer call on the platform by the name of specified sender.
     *
     * Can only be called by asset implementation contract assigned to sender.
     *
     * @param _from holder address to take from.
     * @param _to holder address to give to.
     * @param _value amount to transfer.
     * @param _reference transfer comment to be included in a platform's Transfer event.
     * @param _sender initial caller.
     *
     * @return success.
     */
    function __transferFromWithReference(address _from, address _to, uint _value, string _reference, address _sender) onlyAccess(_sender) returns(bool) {
        return chronoBankPlatform.proxyTransferFromWithReference(_from, _to, _value, smbl, _reference, _sender);
    }

    /**
     * Sets asset spending allowance for a specified spender.
     *
     * @param _spender holder address to set allowance to.
     * @param _value amount to allow.
     *
     * @return success.
     */
    function approve(address _spender, uint _value) returns(bool) {
        return _approve(_spender, _value);
    }

    /**
     * Resolves asset implementation contract for the caller and forwards there arguments along with
     * the caller address.
     *
     * @return success.
     */
    function _approve(address _spender, uint _value) internal returns(bool) {
        return _getAsset().__approve(_spender, _value, msg.sender);
    }

    /**
     * Performs allowance setting call on the platform by the name of specified sender.
     *
     * Can only be called by asset implementation contract assigned to sender.
     *
     * @param _spender holder address to set allowance to.
     * @param _value amount to allow.
     * @param _sender initial caller.
     *
     * @return success.
     */
    function __approve(address _spender, uint _value, address _sender) onlyAccess(_sender) returns(bool) {
        return chronoBankPlatform.proxyApprove(_spender, _value, smbl, _sender);
    }

    /**
     * Emits ERC20 Transfer event on this contract.
     *
     * Can only be, and, called by assigned platform when asset transfer happens.
     */
    function emitTransfer(address _from, address _to, uint _value) onlyChronoBankPlatform() {
        Transfer(_from, _to, _value);
    }

    /**
     * Emits ERC20 Approval event on this contract.
     *
     * Can only be, and, called by assigned platform when asset allowance set happens.
     */
    function emitApprove(address _from, address _spender, uint _value) onlyChronoBankPlatform() {
        Approval(_from, _spender, _value);
    }

    /**
     * Resolves asset implementation contract for the caller and forwards there transaction data,
     * along with the value. This allows for proxy interface growth.
     */
    function () payable {
        _getAsset().__process.value(msg.value)(msg.data, msg.sender);
    }

    /**
     * Indicates an upgrade freeze-time start, and the next asset implementation contract.
     */
    event UpgradeProposal(address newVersion);

    // Current asset implementation contract address.
    address latestVersion;

    // Proposed next asset implementation contract address.
    address pendingVersion;

    // Upgrade freeze-time start.
    uint pendingVersionTimestamp;

    // Timespan for users to review the new implementation and make decision.
    uint constant UPGRADE_FREEZE_TIME = 3 days;

    // Asset implementation contract address that user decided to stick with.
    // 0x0 means that user uses latest version.
    mapping(address => address) userOptOutVersion;

    /**
     * Only asset implementation contract assigned to sender is allowed to call.
     */
    modifier onlyAccess(address _sender) {
        if (getVersionFor(_sender) == msg.sender) {
            _;
        }
    }

    /**
     * Returns asset implementation contract address assigned to sender.
     *
     * @param _sender sender address.
     *
     * @return asset implementation contract address.
     */
    function getVersionFor(address _sender) constant returns(address) {
        return userOptOutVersion[_sender] == 0 ? latestVersion : userOptOutVersion[_sender];
    }

    /**
     * Returns current asset implementation contract address.
     *
     * @return asset implementation contract address.
     */
    function getLatestVersion() constant returns(address) {
        return latestVersion;
    }

    /**
     * Returns proposed next asset implementation contract address.
     *
     * @return asset implementation contract address.
     */
    function getPendingVersion() constant returns(address) {
        return pendingVersion;
    }

    /**
     * Returns upgrade freeze-time start.
     *
     * @return freeze-time start.
     */
    function getPendingVersionTimestamp() constant returns(uint) {
        return pendingVersionTimestamp;
    }

    /**
     * Propose next asset implementation contract address.
     *
     * Can only be called by current asset owner.
     *
     * Note: freeze-time should not be applied for the initial setup.
     *
     * @param _newVersion asset implementation contract address.
     *
     * @return success.
     */
    function proposeUpgrade(address _newVersion) onlyAssetOwner() returns(bool) {
        // Should not already be in the upgrading process.
        if (pendingVersion != 0x0) {
            return false;
        }
        // New version address should be other than 0x0.
        if (_newVersion == 0x0) {
            return false;
        }
        // Don't apply freeze-time for the initial setup.
        if (latestVersion == 0x0) {
            latestVersion = _newVersion;
            return true;
        }
        pendingVersion = _newVersion;
        pendingVersionTimestamp = now;
        UpgradeProposal(_newVersion);
        return true;
    }

    /**
     * Cancel the pending upgrade process.
     *
     * Can only be called by current asset owner.
     *
     * @return success.
     */
    function purgeUpgrade() onlyAssetOwner() returns(bool) {
        if (pendingVersion == 0x0) {
            return false;
        }
        delete pendingVersion;
        delete pendingVersionTimestamp;
        return true;
    }

    /**
     * Finalize an upgrade process setting new asset implementation contract address.
     *
     * Can only be called after an upgrade freeze-time.
     *
     * @return success.
     */
    function commitUpgrade() returns(bool) {
        if (pendingVersion == 0x0) {
            return false;
        }
        if (pendingVersionTimestamp + UPGRADE_FREEZE_TIME > now) {
            return false;
        }
        latestVersion = pendingVersion;
        delete pendingVersion;
        delete pendingVersionTimestamp;
        return true;
    }

    /**
     * Disagree with proposed upgrade, and stick with current asset implementation
     * until further explicit agreement to upgrade.
     *
     * @return success.
     */
    function optOut() returns(bool) {
        if (userOptOutVersion[msg.sender] != 0x0) {
            return false;
        }
        userOptOutVersion[msg.sender] = latestVersion;
        return true;
    }

    /**
     * Implicitly agree to upgrade to current and future asset implementation upgrades,
     * until further explicit disagreement.
     *
     * @return success.
     */
    function optIn() returns(bool) {
        delete userOptOutVersion[msg.sender];
        return true;
    }
}

Contract Security Audit

Contract ABI

API
[{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_spender","type":"address"},{"name":"_value","type":"uint256"}],"name":"approve","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":false,"inputs":[],"name":"commitUpgrade","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"getLatestVersion","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_from","type":"address"},{"name":"_spender","type":"address"},{"name":"_value","type":"uint256"}],"name":"emitApprove","outputs":[],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transferFrom","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"emitTransfer","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"name":"","type":"uint8"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"chronoBankPlatform","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"getPendingVersionTimestamp","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[],"name":"purgeUpgrade","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":false,"inputs":[],"name":"optIn","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"},{"name":"_value","type":"uint256"},{"name":"_reference","type":"string"}],"name":"transferFromWithReference","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_value","type":"uint256"},{"name":"_reference","type":"string"},{"name":"_sender","type":"address"}],"name":"__transferWithReference","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"}],"name":"balanceOf","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_spender","type":"address"},{"name":"_value","type":"uint256"},{"name":"_sender","type":"address"}],"name":"__approve","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"string"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"getPendingVersion","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transfer","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_value","type":"uint256"},{"name":"_reference","type":"string"}],"name":"transferWithReference","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_chronoBankPlatform","type":"address"},{"name":"_symbol","type":"string"},{"name":"_name","type":"string"}],"name":"init","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_newVersion","type":"address"}],"name":"proposeUpgrade","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"source","type":"string"}],"name":"stringToBytes32","outputs":[{"name":"result","type":"bytes32"}],"payable":false,"type":"function"},{"constant":false,"inputs":[],"name":"optOut","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"_from","type":"address"},{"name":"_spender","type":"address"}],"name":"allowance","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"},{"name":"_value","type":"uint256"},{"name":"_reference","type":"string"},{"name":"_sender","type":"address"}],"name":"__transferFromWithReference","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"_sender","type":"address"}],"name":"getVersionFor","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"},{"payable":true,"type":"fallback"},{"anonymous":false,"inputs":[{"indexed":false,"name":"newVersion","type":"address"}],"name":"UpgradeProposal","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"from","type":"address"},{"indexed":true,"name":"to","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"from","type":"address"},{"indexed":true,"name":"spender","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Approval","type":"event"}]

606060405234610000575b61198d806100196000396000f3006060604052361561014e5763ffffffff60e060020a60003504166306fdde0381146101ed578063095ea7b31461027a5780630ba12c83146102aa5780630e6d1de9146102cb57806318160ddd146102f4578063233850891461031357806323b872dd1461033757806323de66511461036d578063313ce5671461039157806349752baf146103b45780634bfaf2e8146103dd5780634dfe950d146103fc5780635b48684e1461041d5780636461fe391461043e5780636a630ee7146104ba57806370a08231146105395780637b7054c81461056457806395d89b411461059b578063a883fb9014610628578063a9059cbb14610651578063ac35caee14610681578063b2b45df5146106f5578063c915fc93146107a3578063cfb51928146107d0578063d4eec5a614610835578063dd62ed3e14610856578063ec698a2814610887578063fe8beb711461090e575b6101eb5b61015a610943565b604080517ff2d6e0ab00000000000000000000000000000000000000000000000000000000815233600160a060020a03818116602484015260048301938452366044840181905294169363f2d6e0ab9334936000939190819060640185858082843782019150509450505050506000604051808303818588803b156100005761235a5a03f11561000057505050505b565b005b34610000576101fa610954565b604080516020808252835181830152835191928392908301918501908083838215610240575b80518252602083111561024057601f199092019160209182019101610220565b505050905090810190601f16801561026c5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3461000057610296600160a060020a03600435166024356109df565b604080519115158252519081900360200190f35b34610000576102966109f4565b604080519115158252519081900360200190f35b34610000576102d8610a59565b60408051600160a060020a039092168252519081900360200190f35b3461000057610301610a69565b60408051918252519081900360200190f35b34610000576101eb600160a060020a0360043581169060243516604435610aea565b005b3461000057610296600160a060020a0360043581169060243516604435610b54565b604080519115158252519081900360200190f35b34610000576101eb600160a060020a0360043581169060243516604435610b7c565b005b346100005761039e610be6565b6040805160ff9092168252519081900360200190f35b34610000576102d8610c67565b60408051600160a060020a039092168252519081900360200190f35b3461000057610301610c76565b60408051918252519081900360200190f35b3461000057610296610c7d565b604080519115158252519081900360200190f35b3461000057610296610d27565b604080519115158252519081900360200190f35b3461000057604080516020600460643581810135601f8101849004840285018401909552848452610296948235600160a060020a03908116956024803590921695604435959460849492930191908190840183828082843750949650610d5395505050505050565b604080519115158252519081900360200190f35b3461000057604080516020600460443581810135601f8101849004840285018401909552848452610296948235600160a060020a031694602480359560649492939190920191819084018382808284375094965050509235600160a060020a03169250610d6c915050565b604080519115158252519081900360200190f35b3461000057610301600160a060020a0360043516610eb4565b60408051918252519081900360200190f35b3461000057610296600160a060020a036004358116906024359060443516610f3e565b604080519115158252519081900360200190f35b34610000576101fa611007565b604080516020808252835181830152835191928392908301918501908083838215610240575b80518252602083111561024057601f199092019160209182019101610220565b505050905090810190601f16801561026c5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34610000576102d8611095565b60408051600160a060020a039092168252519081900360200190f35b3461000057610296600160a060020a03600435166024356110a5565b604080519115158252519081900360200190f35b3461000057604080516020600460443581810135601f8101849004840285018401909552848452610296948235600160a060020a03169460248035956064949293919092019181908401838280828437509496506110cb95505050505050565b604080519115158252519081900360200190f35b346100005760408051602060046024803582810135601f8101859004850286018501909652858552610296958335600160a060020a0316959394604494939290920191819084018382808284375050604080516020601f89358b018035918201839004830284018301909452808352979998810197919650918201945092508291508401838280828437509496506110e295505050505050565b604080519115158252519081900360200190f35b3461000057610296600160a060020a036004351661128d565b604080519115158252519081900360200190f35b3461000057610301600480803590602001908201803590602001908080601f016020809104026020016040519081016040528093929190818152602001838380828437509496506113c595505050505050565b60408051918252519081900360200190f35b34610000576102966113d0565b604080519115158252519081900360200190f35b3461000057610301600160a060020a0360043581169060243516611431565b60408051918252519081900360200190f35b3461000057604080516020600460643581810135601f8101849004840285018401909552848452610296948235600160a060020a0390811695602480359092169560443595946084949293019190819084018382808284375094965050509235600160a060020a031692506114c4915050565b604080519115158252519081900360200190f35b34610000576102d8600160a060020a0360043516611619565b60408051600160a060020a039092168252519081900360200190f35b600061094e33611619565b90505b90565b6002805460408051602060018416156101000260001901909316849004601f810184900484028201840190925281815292918301828280156109d75780601f106109ac576101008083540402835291602001916109d7565b820191906000526020600020905b8154815290600101906020018083116109ba57829003601f168201915b505050505081565b60006109eb8383611670565b90505b92915050565b600554600090600160a060020a03161515610a1157506000610951565b426203f480600654011115610a2857506000610951565b506005805460048054600160a060020a0319908116600160a060020a03841617909155169055600060065560015b90565b600454600160a060020a03165b90565b6000805460015460408051602090810185905281517fb524abcf00000000000000000000000000000000000000000000000000000000815260048101939093529051600160a060020a039093169263b524abcf92602480820193929182900301818787803b156100005760325a03f115610000575050604051519150505b90565b60005433600160a060020a0390811691161415610b4d5781600160a060020a031683600160a060020a03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925836040518082815260200191505060405180910390a35b5b5b505050565b6000610b728484846020604051908101604052806000815250611712565b90505b9392505050565b60005433600160a060020a0390811691161415610b4d5781600160a060020a031683600160a060020a03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040518082815260200191505060405180910390a35b5b5b505050565b6000805460015460408051602090810185905281517fdc86e6f000000000000000000000000000000000000000000000000000000000815260048101939093529051600160a060020a039093169263dc86e6f092602480820193929182900301818787803b156100005760325a03f115610000575050604051519150505b90565b600054600160a060020a031681565b6006545b90565b60008054600154604080516020908101859052815160e160020a6374b5a315028152600160a060020a03338116600483015260248201949094529151929093169263e96b462a9260448084019382900301818787803b156100005760325a03f1156100005750506040515115905061095157600554600160a060020a03161515610d0957506000610951565b5060058054600160a060020a0319169055600060065560015b5b5b90565b600160a060020a03331660009081526007602052604090208054600160a060020a031916905560015b90565b6000610d6185858585611712565b90505b949350505050565b60008133600160a060020a0316610d8282611619565b600160a060020a03161415610ea9576000805460015460408051602090810194909452517f57a96dd0000000000000000000000000000000000000000000000000000000008152600160a060020a038a811660048301908152602483018b905260448301849052888216608484015260a0606484019081528a5160a48501528a5192909516956357a96dd0958d958d9590948d948d9490939260c40191908601908083838215610e4d575b805182526020831115610e4d57601f199092019160209182019101610e2d565b505050905090810190601f168015610e795780820380516001836020036101000a031916815260200191505b509650505050505050602060405180830381600087803b156100005760325a03f115610000575050604051519250505b5b5b50949350505050565b6000805460015460408051602090810185905281517f4d30b6be000000000000000000000000000000000000000000000000000000008152600160a060020a038781166004830152602482019490945291519290931692634d30b6be9260448084019382900301818787803b156100005760325a03f115610000575050604051519150505b919050565b60008133600160a060020a0316610f5482611619565b600160a060020a03161415610ffd576000805460015460408051602090810185905281517f14712e2f000000000000000000000000000000000000000000000000000000008152600160a060020a038b81166004830152602482018b905260448201949094528884166064820152915192909316936314712e2f9360848084019491939192918390030190829087803b156100005760325a03f115610000575050604051519250505b5b5b509392505050565b6003805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815292918301828280156109d75780601f106109ac576101008083540402835291602001916109d7565b820191906000526020600020905b8154815290600101906020018083116109ba57829003601f168201915b505050505081565b600554600160a060020a03165b90565b60006109eb83836020604051908101604052806000815250611847565b90505b92915050565b6000610b72848484611847565b90505b9392505050565b60008054600160a060020a0316156110fc57506000610b75565b60008054600160a060020a031916600160a060020a03861617815583516003805492819052917fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b602060026101006001851615026000190190931692909204601f9081018390048201939288019083901061118257805160ff19168380011785556111af565b828001600101855582156111af579182015b828111156111af578251825591602001919060010190611194565b5b506111d09291505b808211156111cc57600081556001016111b8565b5090565b50506111db836113c5565b600181600019169055508160029080519060200190828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061123157805160ff191683800117855561125e565b8280016001018555821561125e579182015b8281111561125e578251825591602001919060010190611243565b5b5061127f9291505b808211156111cc57600081556001016111b8565b5090565b5050600190505b9392505050565b60008054600154604080516020908101859052815160e160020a6374b5a315028152600160a060020a03338116600483015260248201949094529151929093169263e96b462a9260448084019382900301818787803b156100005760325a03f11561000057505060405151159050610f3957600554600160a060020a03161561131857506000610f39565b600160a060020a038216151561133057506000610f39565b600454600160a060020a03161515611365575060048054600160a060020a031916600160a060020a0383161790556001610f39565b60058054600160a060020a038416600160a060020a031990911681179091554260065560408051918252517faf574319215a31df9b528258f1bdeef2b12b169dc85ff443a49373248c77493a9181900360200190a15060015b5b5b919050565b60208101515b919050565b600160a060020a03338116600090815260076020526040812054909116156113fa57506000610951565b5060045433600160a060020a0390811660009081526007602052604090208054600160a060020a0319169190921617905560015b90565b6000805460015460408051602090810185905281517f1c8d5d38000000000000000000000000000000000000000000000000000000008152600160a060020a0388811660048301528781166024830152604482019490945291519290931692631c8d5d389260648084019382900301818787803b156100005760325a03f115610000575050604051519150505b92915050565b60008133600160a060020a03166114da82611619565b600160a060020a0316141561160d576000805460015460408051602090810194909452517f161ff662000000000000000000000000000000000000000000000000000000008152600160a060020a038b8116600483019081528b82166024840152604483018b90526064830184905288821660a484015260c0608484019081528a5160c48501528a51929095169563161ff662958e958e958e9591948e948e949193919260e401919086019080838382156115b0575b8051825260208311156115b057601f199092019160209182019101611590565b505050905090810190601f1680156115dc5780820380516001836020036101000a031916815260200191505b50975050505050505050602060405180830381600087803b156100005760325a03f115610000575050604051519250505b5b5b5095945050505050565b600160a060020a038082166000908152600760205260408120549091161561165b57600160a060020a0380831660009081526007602052604090205416611668565b600454600160a060020a03165b90505b919050565b600061167a610943565b600160a060020a0316637b7054c88484336000604051602001526040518463ffffffff1660e060020a0281526004018084600160a060020a0316600160a060020a0316815260200183815260200182600160a060020a0316600160a060020a031681526020019350505050602060405180830381600087803b156100005760325a03f115610000575050604051519150505b92915050565b600061171c610943565b600160a060020a031663ec698a2886868686336000604051602001526040518663ffffffff1660e060020a0281526004018086600160a060020a0316600160a060020a0316815260200185600160a060020a0316600160a060020a031681526020018481526020018060200183600160a060020a0316600160a060020a031681526020018281038252848181518152602001915080519060200190808383600083146117e3575b8051825260208311156117e357601f1990920191602091820191016117c3565b505050905090810190601f16801561180f5780820380516001836020036101000a031916815260200191505b509650505050505050602060405180830381600087803b156100005760325a03f115610000575050604051519150505b949350505050565b6000611851610943565b600160a060020a0316636a630ee7858585336000604051602001526040518563ffffffff1660e060020a0281526004018085600160a060020a0316600160a060020a031681526020018481526020018060200183600160a060020a0316600160a060020a031681526020018281038252848181518152602001915080519060200190808383600083146118ff575b8051825260208311156118ff57601f1990920191602091820191016118df565b505050905090810190601f16801561192b5780820380516001836020036101000a031916815260200191505b5095505050505050602060405180830381600087803b156100005760325a03f115610000575050604051519150505b93925050505600a165627a7a7230582014a2415442d222c840a9f97e881c3a1a8b3b9e45ca90ea33df3ca27a39dd6a500029

Deployed Bytecode

0x6060604052361561014e5763ffffffff60e060020a60003504166306fdde0381146101ed578063095ea7b31461027a5780630ba12c83146102aa5780630e6d1de9146102cb57806318160ddd146102f4578063233850891461031357806323b872dd1461033757806323de66511461036d578063313ce5671461039157806349752baf146103b45780634bfaf2e8146103dd5780634dfe950d146103fc5780635b48684e1461041d5780636461fe391461043e5780636a630ee7146104ba57806370a08231146105395780637b7054c81461056457806395d89b411461059b578063a883fb9014610628578063a9059cbb14610651578063ac35caee14610681578063b2b45df5146106f5578063c915fc93146107a3578063cfb51928146107d0578063d4eec5a614610835578063dd62ed3e14610856578063ec698a2814610887578063fe8beb711461090e575b6101eb5b61015a610943565b604080517ff2d6e0ab00000000000000000000000000000000000000000000000000000000815233600160a060020a03818116602484015260048301938452366044840181905294169363f2d6e0ab9334936000939190819060640185858082843782019150509450505050506000604051808303818588803b156100005761235a5a03f11561000057505050505b565b005b34610000576101fa610954565b604080516020808252835181830152835191928392908301918501908083838215610240575b80518252602083111561024057601f199092019160209182019101610220565b505050905090810190601f16801561026c5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3461000057610296600160a060020a03600435166024356109df565b604080519115158252519081900360200190f35b34610000576102966109f4565b604080519115158252519081900360200190f35b34610000576102d8610a59565b60408051600160a060020a039092168252519081900360200190f35b3461000057610301610a69565b60408051918252519081900360200190f35b34610000576101eb600160a060020a0360043581169060243516604435610aea565b005b3461000057610296600160a060020a0360043581169060243516604435610b54565b604080519115158252519081900360200190f35b34610000576101eb600160a060020a0360043581169060243516604435610b7c565b005b346100005761039e610be6565b6040805160ff9092168252519081900360200190f35b34610000576102d8610c67565b60408051600160a060020a039092168252519081900360200190f35b3461000057610301610c76565b60408051918252519081900360200190f35b3461000057610296610c7d565b604080519115158252519081900360200190f35b3461000057610296610d27565b604080519115158252519081900360200190f35b3461000057604080516020600460643581810135601f8101849004840285018401909552848452610296948235600160a060020a03908116956024803590921695604435959460849492930191908190840183828082843750949650610d5395505050505050565b604080519115158252519081900360200190f35b3461000057604080516020600460443581810135601f8101849004840285018401909552848452610296948235600160a060020a031694602480359560649492939190920191819084018382808284375094965050509235600160a060020a03169250610d6c915050565b604080519115158252519081900360200190f35b3461000057610301600160a060020a0360043516610eb4565b60408051918252519081900360200190f35b3461000057610296600160a060020a036004358116906024359060443516610f3e565b604080519115158252519081900360200190f35b34610000576101fa611007565b604080516020808252835181830152835191928392908301918501908083838215610240575b80518252602083111561024057601f199092019160209182019101610220565b505050905090810190601f16801561026c5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34610000576102d8611095565b60408051600160a060020a039092168252519081900360200190f35b3461000057610296600160a060020a03600435166024356110a5565b604080519115158252519081900360200190f35b3461000057604080516020600460443581810135601f8101849004840285018401909552848452610296948235600160a060020a03169460248035956064949293919092019181908401838280828437509496506110cb95505050505050565b604080519115158252519081900360200190f35b346100005760408051602060046024803582810135601f8101859004850286018501909652858552610296958335600160a060020a0316959394604494939290920191819084018382808284375050604080516020601f89358b018035918201839004830284018301909452808352979998810197919650918201945092508291508401838280828437509496506110e295505050505050565b604080519115158252519081900360200190f35b3461000057610296600160a060020a036004351661128d565b604080519115158252519081900360200190f35b3461000057610301600480803590602001908201803590602001908080601f016020809104026020016040519081016040528093929190818152602001838380828437509496506113c595505050505050565b60408051918252519081900360200190f35b34610000576102966113d0565b604080519115158252519081900360200190f35b3461000057610301600160a060020a0360043581169060243516611431565b60408051918252519081900360200190f35b3461000057604080516020600460643581810135601f8101849004840285018401909552848452610296948235600160a060020a0390811695602480359092169560443595946084949293019190819084018382808284375094965050509235600160a060020a031692506114c4915050565b604080519115158252519081900360200190f35b34610000576102d8600160a060020a0360043516611619565b60408051600160a060020a039092168252519081900360200190f35b600061094e33611619565b90505b90565b6002805460408051602060018416156101000260001901909316849004601f810184900484028201840190925281815292918301828280156109d75780601f106109ac576101008083540402835291602001916109d7565b820191906000526020600020905b8154815290600101906020018083116109ba57829003601f168201915b505050505081565b60006109eb8383611670565b90505b92915050565b600554600090600160a060020a03161515610a1157506000610951565b426203f480600654011115610a2857506000610951565b506005805460048054600160a060020a0319908116600160a060020a03841617909155169055600060065560015b90565b600454600160a060020a03165b90565b6000805460015460408051602090810185905281517fb524abcf00000000000000000000000000000000000000000000000000000000815260048101939093529051600160a060020a039093169263b524abcf92602480820193929182900301818787803b156100005760325a03f115610000575050604051519150505b90565b60005433600160a060020a0390811691161415610b4d5781600160a060020a031683600160a060020a03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925836040518082815260200191505060405180910390a35b5b5b505050565b6000610b728484846020604051908101604052806000815250611712565b90505b9392505050565b60005433600160a060020a0390811691161415610b4d5781600160a060020a031683600160a060020a03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040518082815260200191505060405180910390a35b5b5b505050565b6000805460015460408051602090810185905281517fdc86e6f000000000000000000000000000000000000000000000000000000000815260048101939093529051600160a060020a039093169263dc86e6f092602480820193929182900301818787803b156100005760325a03f115610000575050604051519150505b90565b600054600160a060020a031681565b6006545b90565b60008054600154604080516020908101859052815160e160020a6374b5a315028152600160a060020a03338116600483015260248201949094529151929093169263e96b462a9260448084019382900301818787803b156100005760325a03f1156100005750506040515115905061095157600554600160a060020a03161515610d0957506000610951565b5060058054600160a060020a0319169055600060065560015b5b5b90565b600160a060020a03331660009081526007602052604090208054600160a060020a031916905560015b90565b6000610d6185858585611712565b90505b949350505050565b60008133600160a060020a0316610d8282611619565b600160a060020a03161415610ea9576000805460015460408051602090810194909452517f57a96dd0000000000000000000000000000000000000000000000000000000008152600160a060020a038a811660048301908152602483018b905260448301849052888216608484015260a0606484019081528a5160a48501528a5192909516956357a96dd0958d958d9590948d948d9490939260c40191908601908083838215610e4d575b805182526020831115610e4d57601f199092019160209182019101610e2d565b505050905090810190601f168015610e795780820380516001836020036101000a031916815260200191505b509650505050505050602060405180830381600087803b156100005760325a03f115610000575050604051519250505b5b5b50949350505050565b6000805460015460408051602090810185905281517f4d30b6be000000000000000000000000000000000000000000000000000000008152600160a060020a038781166004830152602482019490945291519290931692634d30b6be9260448084019382900301818787803b156100005760325a03f115610000575050604051519150505b919050565b60008133600160a060020a0316610f5482611619565b600160a060020a03161415610ffd576000805460015460408051602090810185905281517f14712e2f000000000000000000000000000000000000000000000000000000008152600160a060020a038b81166004830152602482018b905260448201949094528884166064820152915192909316936314712e2f9360848084019491939192918390030190829087803b156100005760325a03f115610000575050604051519250505b5b5b509392505050565b6003805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815292918301828280156109d75780601f106109ac576101008083540402835291602001916109d7565b820191906000526020600020905b8154815290600101906020018083116109ba57829003601f168201915b505050505081565b600554600160a060020a03165b90565b60006109eb83836020604051908101604052806000815250611847565b90505b92915050565b6000610b72848484611847565b90505b9392505050565b60008054600160a060020a0316156110fc57506000610b75565b60008054600160a060020a031916600160a060020a03861617815583516003805492819052917fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b602060026101006001851615026000190190931692909204601f9081018390048201939288019083901061118257805160ff19168380011785556111af565b828001600101855582156111af579182015b828111156111af578251825591602001919060010190611194565b5b506111d09291505b808211156111cc57600081556001016111b8565b5090565b50506111db836113c5565b600181600019169055508160029080519060200190828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061123157805160ff191683800117855561125e565b8280016001018555821561125e579182015b8281111561125e578251825591602001919060010190611243565b5b5061127f9291505b808211156111cc57600081556001016111b8565b5090565b5050600190505b9392505050565b60008054600154604080516020908101859052815160e160020a6374b5a315028152600160a060020a03338116600483015260248201949094529151929093169263e96b462a9260448084019382900301818787803b156100005760325a03f11561000057505060405151159050610f3957600554600160a060020a03161561131857506000610f39565b600160a060020a038216151561133057506000610f39565b600454600160a060020a03161515611365575060048054600160a060020a031916600160a060020a0383161790556001610f39565b60058054600160a060020a038416600160a060020a031990911681179091554260065560408051918252517faf574319215a31df9b528258f1bdeef2b12b169dc85ff443a49373248c77493a9181900360200190a15060015b5b5b919050565b60208101515b919050565b600160a060020a03338116600090815260076020526040812054909116156113fa57506000610951565b5060045433600160a060020a0390811660009081526007602052604090208054600160a060020a0319169190921617905560015b90565b6000805460015460408051602090810185905281517f1c8d5d38000000000000000000000000000000000000000000000000000000008152600160a060020a0388811660048301528781166024830152604482019490945291519290931692631c8d5d389260648084019382900301818787803b156100005760325a03f115610000575050604051519150505b92915050565b60008133600160a060020a03166114da82611619565b600160a060020a0316141561160d576000805460015460408051602090810194909452517f161ff662000000000000000000000000000000000000000000000000000000008152600160a060020a038b8116600483019081528b82166024840152604483018b90526064830184905288821660a484015260c0608484019081528a5160c48501528a51929095169563161ff662958e958e958e9591948e948e949193919260e401919086019080838382156115b0575b8051825260208311156115b057601f199092019160209182019101611590565b505050905090810190601f1680156115dc5780820380516001836020036101000a031916815260200191505b50975050505050505050602060405180830381600087803b156100005760325a03f115610000575050604051519250505b5b5b5095945050505050565b600160a060020a038082166000908152600760205260408120549091161561165b57600160a060020a0380831660009081526007602052604090205416611668565b600454600160a060020a03165b90505b919050565b600061167a610943565b600160a060020a0316637b7054c88484336000604051602001526040518463ffffffff1660e060020a0281526004018084600160a060020a0316600160a060020a0316815260200183815260200182600160a060020a0316600160a060020a031681526020019350505050602060405180830381600087803b156100005760325a03f115610000575050604051519150505b92915050565b600061171c610943565b600160a060020a031663ec698a2886868686336000604051602001526040518663ffffffff1660e060020a0281526004018086600160a060020a0316600160a060020a0316815260200185600160a060020a0316600160a060020a031681526020018481526020018060200183600160a060020a0316600160a060020a031681526020018281038252848181518152602001915080519060200190808383600083146117e3575b8051825260208311156117e357601f1990920191602091820191016117c3565b505050905090810190601f16801561180f5780820380516001836020036101000a031916815260200191505b509650505050505050602060405180830381600087803b156100005760325a03f115610000575050604051519150505b949350505050565b6000611851610943565b600160a060020a0316636a630ee7858585336000604051602001526040518563ffffffff1660e060020a0281526004018085600160a060020a0316600160a060020a031681526020018481526020018060200183600160a060020a0316600160a060020a031681526020018281038252848181518152602001915080519060200190808383600083146118ff575b8051825260208311156118ff57601f1990920191602091820191016118df565b505050905090810190601f16801561192b5780820380516001836020036101000a031916815260200191505b5095505050505050602060405180830381600087803b156100005760325a03f115610000575050604051519150505b93925050505600a165627a7a7230582014a2415442d222c840a9f97e881c3a1a8b3b9e45ca90ea33df3ca27a39dd6a500029

Swarm Source

bzzr://14a2415442d222c840a9f97e881c3a1a8b3b9e45ca90ea33df3ca27a39dd6a50

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.