abstract contract NestMapping is NestBase, INestMapping {

    // constructor() { }

    /// @dev Address of nest token contract
    address _nestTokenAddress;

    /// @dev Address of nest node contract
    address _nestNodeAddress;

    /// @dev INestLedger implementation contract address
    address _nestLedgerAddress;

    /// @dev INestMining implementation contract address for nest
    address _nestMiningAddress;

    /// @dev INestMining implementation contract address for ntoken
    address _ntokenMiningAddress;

    /// @dev INestPriceFacade implementation contract address
    address _nestPriceFacadeAddress;

    /// @dev INestVote implementation contract address
    address _nestVoteAddress;

    /// @dev INestQuery implementation contract address
    address _nestQueryAddress;

    /// @dev NNIncome contract address
    address _nnIncomeAddress;

    /// @dev INTokenController implementation contract address
    address _nTokenControllerAddress;
    
    /// @dev Address registered in the system
    mapping(string=>address) _registeredAddress;

    /// @dev Set the built-in contract address of the system
    /// @param nestTokenAddress Address of nest token contract
    /// @param nestNodeAddress Address of nest node contract
    /// @param nestLedgerAddress INestLedger implementation contract address
    /// @param nestMiningAddress INestMining implementation contract address for nest
    /// @param ntokenMiningAddress INestMining implementation contract address for ntoken
    /// @param nestPriceFacadeAddress INestPriceFacade implementation contract address
    /// @param nestVoteAddress INestVote implementation contract address
    /// @param nestQueryAddress INestQuery implementation contract address
    /// @param nnIncomeAddress NNIncome contract address
    /// @param nTokenControllerAddress INTokenController implementation contract address
    function setBuiltinAddress(
        address nestTokenAddress,
        address nestNodeAddress,
        address nestLedgerAddress,
        address nestMiningAddress,
        address ntokenMiningAddress,
        address nestPriceFacadeAddress,
        address nestVoteAddress,
        address nestQueryAddress,
        address nnIncomeAddress,
        address nTokenControllerAddress
    ) override external onlyGovernance {
        
        if (nestTokenAddress != address(0)) {
            _nestTokenAddress = nestTokenAddress;
        }
        if (nestNodeAddress != address(0)) {
            _nestNodeAddress = nestNodeAddress;
        }
        if (nestLedgerAddress != address(0)) {
            _nestLedgerAddress = nestLedgerAddress;
        }
        if (nestMiningAddress != address(0)) {
            _nestMiningAddress = nestMiningAddress;
        }
        if (ntokenMiningAddress != address(0)) {
            _ntokenMiningAddress = ntokenMiningAddress;
        }
        if (nestPriceFacadeAddress != address(0)) {
            _nestPriceFacadeAddress = nestPriceFacadeAddress;
        }
        if (nestVoteAddress != address(0)) {
            _nestVoteAddress = nestVoteAddress;
        }
        if (nestQueryAddress != address(0)) {
            _nestQueryAddress = nestQueryAddress;
        }
        if (nnIncomeAddress != address(0)) {
            _nnIncomeAddress = nnIncomeAddress;
        }
        if (nTokenControllerAddress != address(0)) {
            _nTokenControllerAddress = nTokenControllerAddress;
        }
    }

    /// @dev Get the built-in contract address of the system
    /// @return nestTokenAddress Address of nest token contract
    /// @return nestNodeAddress Address of nest node contract
    /// @return nestLedgerAddress INestLedger implementation contract address
    /// @return nestMiningAddress INestMining implementation contract address for nest
    /// @return ntokenMiningAddress INestMining implementation contract address for ntoken
    /// @return nestPriceFacadeAddress INestPriceFacade implementation contract address
    /// @return nestVoteAddress INestVote implementation contract address
    /// @return nestQueryAddress INestQuery implementation contract address
    /// @return nnIncomeAddress NNIncome contract address
    /// @return nTokenControllerAddress INTokenController implementation contract address
    function getBuiltinAddress() override external view returns (
        address nestTokenAddress,
        address nestNodeAddress,
        address nestLedgerAddress,
        address nestMiningAddress,
        address ntokenMiningAddress,
        address nestPriceFacadeAddress,
        address nestVoteAddress,
        address nestQueryAddress,
        address nnIncomeAddress,
        address nTokenControllerAddress
    ) {
        return (
            _nestTokenAddress,
            _nestNodeAddress,
            _nestLedgerAddress,
            _nestMiningAddress,
            _ntokenMiningAddress,
            _nestPriceFacadeAddress,
            _nestVoteAddress,
            _nestQueryAddress,
            _nnIncomeAddress,
            _nTokenControllerAddress
        );
    }

    /// @dev Get address of nest token contract
    /// @return Address of nest token contract
    function getNestTokenAddress() override external view returns (address) { return _nestTokenAddress; }

    /// @dev Get address of nest node contract
    /// @return Address of nest node contract
    function getNestNodeAddress() override external view returns (address) { return _nestNodeAddress; }

    /// @dev Get INestLedger implementation contract address
    /// @return INestLedger implementation contract address
    function getNestLedgerAddress() override external view returns (address) { return _nestLedgerAddress; }

    /// @dev Get INestMining implementation contract address for nest
    /// @return INestMining implementation contract address for nest
    function getNestMiningAddress() override external view returns (address) { return _nestMiningAddress; }

    /// @dev Get INestMining implementation contract address for ntoken
    /// @return INestMining implementation contract address for ntoken
    function getNTokenMiningAddress() override external view returns (address) { return _ntokenMiningAddress; }

    /// @dev Get INestPriceFacade implementation contract address
    /// @return INestPriceFacade implementation contract address
    function getNestPriceFacadeAddress() override external view returns (address) { return _nestPriceFacadeAddress; }

    /// @dev Get INestVote implementation contract address
    /// @return INestVote implementation contract address
    function getNestVoteAddress() override external view returns (address) { return _nestVoteAddress; }

    /// @dev Get INestQuery implementation contract address
    /// @return INestQuery implementation contract address
    function getNestQueryAddress() override external view returns (address) { return _nestQueryAddress; }

    /// @dev Get NNIncome contract address
    /// @return NNIncome contract address
    function getNnIncomeAddress() override external view returns (address) { return _nnIncomeAddress; }

    /// @dev Get INTokenController implementation contract address
    /// @return INTokenController implementation contract address
    function getNTokenControllerAddress() override external view returns (address) { return _nTokenControllerAddress; }

    /// @dev Registered address. The address registered here is the address accepted by nest system
    /// @param key The key
    /// @param addr Destination address. 0 means to delete the registration information
    function registerAddress(string memory key, address addr) override external onlyGovernance {
        _registeredAddress[key] = addr;
    }

    /// @dev Get registered address
    /// @param key The key
    /// @return Destination address. 0 means empty
    function checkAddress(string memory key) override external view returns (address) {
        return _registeredAddress[key];
    }
}
/// @dev The contract is for nest builtin contract address mapping
function setBuiltinAddress(
    address nestTokenAddress,
    address nestNodeAddress,
    address nestLedgerAddress,
    address nestMiningAddress,
    address ntokenMiningAddress,
    address nestPriceFacadeAddress,
    address nestVoteAddress,
    address nestQueryAddress,
    address nnIncomeAddress,
    address nTokenControllerAddress
) override external onlyGovernance {
        
    if (nestTokenAddress != address(0)) {
        _nestTokenAddress = nestTokenAddress;
    }
    if (nestNodeAddress != address(0)) {
        _nestNodeAddress = nestNodeAddress;
    }
    if (nestLedgerAddress != address(0)) {
        _nestLedgerAddress = nestLedgerAddress;
    }
    if (nestMiningAddress != address(0)) {
        _nestMiningAddress = nestMiningAddress;
    }
    if (ntokenMiningAddress != address(0)) {
        _ntokenMiningAddress = ntokenMiningAddress;
    }
    if (nestPriceFacadeAddress != address(0)) {
        _nestPriceFacadeAddress = nestPriceFacadeAddress;
    }
    if (nestVoteAddress != address(0)) {
        _nestVoteAddress = nestVoteAddress;
    }
    if (nestQueryAddress != address(0)) {
        _nestQueryAddress = nestQueryAddress;
    }
    if (nnIncomeAddress != address(0)) {
        _nnIncomeAddress = nnIncomeAddress;
    }
    if (nTokenControllerAddress != address(0)) {
        _nTokenControllerAddress = nTokenControllerAddress;
    }
}

/// @dev Set the built-in contract address of the system
/// @param nestTokenAddress Address of nest token contract
/// @param nestNodeAddress Address of nest node contract
/// @param nestLedgerAddress INestLedger implementation contract address
/// @param nestMiningAddress INestMining implementation contract address for nest
/// @param ntokenMiningAddress INestMining implementation contract address for ntoken
/// @param nestPriceFacadeAddress INestPriceFacade implementation contract address
/// @param nestVoteAddress INestVote implementation contract address
/// @param nestQueryAddress INestQuery implementation contract address
/// @param nnIncomeAddress NNIncome contract address
/// @param nTokenControllerAddress INTokenController implementation contract address