contract MultiSigWalletWithLock is
    MultiSigWallet
{
    /* default lock time is 2 weeks, can be modified later */
    uint256 public lockSeconds = 1209600;

    /* events */
    event UnlockTimeSet(uint256 indexed transactionId, uint256 confirmationTime);
    event LockSecondsChange(uint256 lockSeconds);

    /* unlock time of transactions */
    mapping (uint256 => uint256) public unlockTimes;


    /** @dev Contract constructor sets initial owners and required number of confirmations.
      * @param _owners List of initial owners.
      * @param _required Number of required confirmations.
      */
    constructor (
        address[] _owners,
        uint256 _required
    )
        public
        MultiSigWallet(_owners, _required)
    {}

    /** @dev Changes the duration of the time lock for transactions.
      * @param _lockSeconds Duration needed after a transaction is confirmed and before it becomes executable, in seconds.
      */
    function changeLockSeconds(uint256 _lockSeconds)
        public
        onlyWallet
    {
        lockSeconds = _lockSeconds;
        emit LockSecondsChange(_lockSeconds);
    }

    /** @dev Allows an owner to confirm a transaction.
      * @param transactionId Transaction ID.
      */
    function confirmTransaction(uint256 transactionId)
        public
        ownerExists(msg.sender)
        transactionExists(transactionId)
        notConfirmed(transactionId, msg.sender)
    {
        confirmations[transactionId][msg.sender] = true;
        emit Confirmation(msg.sender, transactionId);
        if (isConfirmed(transactionId) && unlockTimes[transactionId] == 0) {
            uint256 unlockTime = block.timestamp + lockSeconds;
            unlockTimes[transactionId] = unlockTime;
            emit UnlockTimeSet(transactionId, unlockTime);
        }
    }

    /** @dev Allows anyone to execute a confirmed transaction.
      * @param transactionId Transaction ID.
      */
    function executeTransaction(uint256 transactionId)
        public
        ownerExists(msg.sender)
        notExecuted(transactionId)
    {
        require(
            block.timestamp >= unlockTimes[transactionId],
            "TRANSACTION_NEED_TO_UNLOCK"
        );
        super.executeTransaction(transactionId);
    }
}
function confirmTransaction(uint256 transactionId)
    public
    ownerExists(msg.sender)
    transactionExists(transactionId)
    notConfirmed(transactionId, msg.sender)
{
    confirmations[transactionId][msg.sender] = true;
    emit Confirmation(msg.sender, transactionId);
    if (isConfirmed(transactionId) && unlockTimes[transactionId] == 0) {
        uint256 unlockTime = block.timestamp + lockSeconds;
        unlockTimes[transactionId] = unlockTime;
        emit UnlockTimeSet(transactionId, unlockTime);
    }
}

/** @dev Allows an owner to confirm a transaction.
 * @param transactionId Transaction ID.
 */