// File: ABIV2.sol



pragma solidity 0.5.2;

import './Ownable.sol';
import './MemberCertificateV2.sol';

contract ABIV2 is Ownable{
    event NewMemberCertificate(address memberAddr, bytes32 name, uint validityDate);
    constructor() public{
    }

    function generateCertificate(bytes32 _name, uint _validityDate) public onlyOwner() returns(address){
        MemberCertificateV2 member = new MemberCertificateV2(_name, _validityDate);
        emit NewMemberCertificate(address(member), _name, _validityDate);
        return address(member);
    }
    
    function setName(address certificateAddr, bytes32 newName) onlyOwner() public {
        MemberCertificateV2 member = MemberCertificateV2(certificateAddr);
        member.setName(newName);
    }

    
    function setValidityDate(address certificateAddr, uint newValidityDate) onlyOwner() public{
        MemberCertificateV2 member = MemberCertificateV2(certificateAddr);
        member.setValidityDate(newValidityDate);
    }
}
/*
1. deploy contract admin

deploy admin 0.050054 * 5,5jt = 275ribu
deploy abi 0.080423 * 5,5jt = 443ribu
add abi to admin 0.004351 * 5,5jt = 25ribu
generate certificate 0.055407 * 5,5jt = 305ribu * 21 member = 6,4jt

7,148,000


V2
Deploy abi 0.018428 * 6jt = 110ribu
bikin member 0.009852 * 6jt = 60ribu
update tiap tahun 0.00074 * 6jt = 4,4ribu
incase mau set name 0.000739 * 6jt = 4,4ribu
*current gas price = 22 wei
*/
// File: MemberCertificateV2.sol



pragma solidity 0.5.2;

import './Ownable.sol';

contract MemberCertificateV2 is Ownable{
    address public creator;
    uint public validityDate;
    bytes32 public name;

    event ChangeName(bytes32 prevName, bytes32 newName);
    event ChangeValidityDate(uint prevValidityDate, uint newValidityDate);

    constructor(bytes32 _name, uint _validityDate) public{
        creator = msg.sender;
        name = _name;
        validityDate = _validityDate;
    }

    function setName(bytes32 newName) onlyOwner() public {
        bytes32 prevName = name;
        name = newName;
        emit ChangeName(prevName, name);
    }

    
    function setValidityDate(uint newValidityDate) onlyOwner() public{
        uint prevValidityDate = validityDate;
        validityDate = newValidityDate;
        emit ChangeValidityDate(prevValidityDate, validityDate);
    }

}
// File: Ownable.sol



pragma solidity ^0.5.0;

/**
 * @title Ownable
 * @dev The Ownable contract has an owner address, and provides basic authorization control
 * functions, this simplifies the implementation of "user permissions".
 */
contract Ownable {
    address private _owner;

    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    /**
     * @dev The Ownable constructor sets the original `owner` of the contract to the sender
     * account.
     */
    constructor () internal {
        _owner = msg.sender;
        emit OwnershipTransferred(address(0), _owner);
    }

    /**
     * @return the address of the owner.
     */
    function owner() public view returns (address) {
        return _owner;
    }

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        require(isOwner());
        _;
    }

    /**
     * @return true if `msg.sender` is the owner of the contract.
     */
    function isOwner() public view returns (bool) {
        return msg.sender == _owner;
    }

    /**
     * @dev Allows the current owner to relinquish control of the contract.
     * @notice Renouncing to ownership will leave the contract without an owner.
     * It will not be possible to call the functions with the `onlyOwner`
     * modifier anymore.
     */
    function renounceOwnership() public onlyOwner {
        emit OwnershipTransferred(_owner, address(0));
        _owner = address(0);
    }

    /**
     * @dev Allows the current owner to transfer control of the contract to a newOwner.
     * @param newOwner The address to transfer ownership to.
     */
    function transferOwnership(address newOwner) public onlyOwner {
        _transferOwnership(newOwner);
    }

    /**
     * @dev Transfers control of the contract to a newOwner.
     * @param newOwner The address to transfer ownership to.
     */
    function _transferOwnership(address newOwner) internal {
        require(newOwner != address(0));
        emit OwnershipTransferred(_owner, newOwner);
        _owner = newOwner;
    }
}