Chain Link Automation not work! No Execute

This my solidy code:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
interface AutomationCompatibleInterface {
function checkUpkeep(bytes calldata checkData) external returns (bool upkeepNeeded, bytes memory performData);
function performUpkeep(bytes calldata performData) external;
}
// File: AutoCtr.sol
// File: @chainlink/contracts/src/v0.8/interfaces/KeeperCompatibleInterface.sol
pragma solidity 0.8.19;
import {VRFConsumerBaseV2Plus} from "@chainlink/contracts/src/v0.8/vrf/dev/VRFConsumerBaseV2Plus.sol";
import {VRFV2PlusClient} from "@chainlink/contracts/src/v0.8/vrf/dev/libraries/VRFV2PlusClient.sol";
/* Errors */
error Raffle__UpkeepNotNeeded(uint256 currentBalance, uint256 numPlayers, uint256 raffleState);
error Raffle__TransferFailed();
error Raffle__SendMoreToEnterRaffle();
error Raffle__RaffleNotOpen();
/**
* Request testnet LINK and ETH here: https://faucets.chain.link/
* Find information on LINK Token Contracts and get the latest ETH and LINK faucets here: https://docs.chain.link/docs/link-token-contracts/
*/
/**
* THIS IS AN EXAMPLE CONTRACT THAT USES HARDCODED VALUES FOR CLARITY.
* THIS IS AN EXAMPLE CONTRACT THAT USES UN-AUDITED CODE.
* DO NOT USE THIS CODE IN PRODUCTION.
*/
contract Lottery is VRFConsumerBaseV2Plus, AutomationCompatibleInterface {
/* Type declarations */
enum RaffleState {
OPEN,
CALCULATING
}
// Lottery Variables
uint256 private immutable i_entranceFee;
uint256 private s_lastTimeStamp;
address payable[] private s_players;
address private s_recentWinner;
uint256 private immutable i_interval;
RaffleState private s_raffleState;
event RequestSent(uint256 requestId, uint32 numWords);
event RequestFulfilled(uint256 requestId, uint256[] randomWords);
event RaffleEnter(address indexed player);
event WinnerPicked(address indexed player);
event RequestedRaffleWinner(uint256 indexed requestId, bytes performData);
// Your subscription ID.
uint256 public immutable s_subscriptionId =
78560131474220272056099479679342269674716447265552668612386115994028644171414;
// Past request IDs.
uint256[] public requestIds;
uint256 public lastRequestId;
// The gas lane to use, which specifies the maximum gas price to bump to.
// For a list of available gas lanes on each network,
// see https://docs.chain.link/docs/vrf/v2-5/supported-networks
bytes32 public keyHash =
0x787d74caea10b2b357790d5b5247c2f63d1d91572a9846f780606e4d953677ae;
// Depends on the number of requested values that you want sent to the
// fulfillRandomWords() function. Storing each word costs about 20,000 gas,
// so 100,000 is a safe default for this example contract. Test and adjust
// this limit based on the network that you select, the size of the request,
// and the processing of the callback request in the fulfillRandomWords()
// function.
uint32 public callbackGasLimit = 2500000;
// The default is 3, but you can set this higher.
uint16 public requestConfirmations = 3;
// For this example, retrieve 2 random values in one request.
// Cannot exceed VRFCoordinatorV2_5.MAX_NUM_WORDS.
uint32 public numWords = 1;
/**
* HARDCODED FOR SEPOLIA
* COORDINATOR: 0x9DdfaCa8183c41ad55329BdeeD9F6A8d53168B1B
* https://docs.chain.link/vrf/v2-5/supported-networks#sepolia-testnet
*/
constructor(
// uint256 subscriptionId,
uint256 entranceFee,
uint256 interval
) VRFConsumerBaseV2Plus(0x9DdfaCa8183c41ad55329BdeeD9F6A8d53168B1B) {
// s_subscriptionId = subscriptionId;
i_entranceFee = entranceFee;
s_raffleState = RaffleState.OPEN;
s_lastTimeStamp = block.timestamp;
i_interval = interval;
}
// Assumes the subscription is funded sufficiently.
function _requestRandomWords()
private
onlyOwner
returns (uint256 requestId)
{
// Will revert if subscription is not set and funded.
requestId = s_vrfCoordinator.requestRandomWords(
VRFV2PlusClient.RandomWordsRequest({
keyHash: keyHash,
subId: s_subscriptionId,
requestConfirmations: requestConfirmations,
callbackGasLimit: callbackGasLimit,
numWords: numWords,
extraArgs: VRFV2PlusClient._argsToBytes(
VRFV2PlusClient.ExtraArgsV1({nativePayment: false})
)
})
);
requestIds.push(requestId);
lastRequestId = requestId;
emit RequestSent(requestId, numWords);
return requestId;
}
function fulfillRandomWords(
uint256,
uint256[] calldata _randomWords
) internal override {
uint256 indexOfWinner = _randomWords[0] % s_players.length;
address payable recentWinner = s_players[indexOfWinner];
s_recentWinner = recentWinner;
s_players = new address payable[](0);
s_raffleState = RaffleState.OPEN;
s_lastTimeStamp = block.timestamp;
(bool success, ) = recentWinner.call{value: address(this).balance}("");
// require(success, "Transfer failed");
if (!success) {
revert Raffle__TransferFailed();
}
emit WinnerPicked(recentWinner);
}
function enterRaffle() public payable {
// require(msg.value >= i_entranceFee, "Not enough value sent");
// require(s_raffleState == RaffleState.OPEN, "Raffle is not open");
if (msg.value < i_entranceFee) {
revert Raffle__SendMoreToEnterRaffle();
}
if (s_raffleState != RaffleState.OPEN) {
revert Raffle__RaffleNotOpen();
}
s_players.push(payable(msg.sender));
// Emit an event when we update a dynamic array or mapping
// Named events with the function name reversed
emit RaffleEnter(msg.sender);
}
/**
* @dev This is the function that the Chainlink Keeper nodes call
* they look for `upkeepNeeded` to return True.
* the following should be true for this to return true:
* 1. The time interval has passed between raffle runs.
* 2. The lottery is open.
* 3. The contract has ETH.
* 4. Implicity, your subscription is funded with LINK.
*/
function checkUpkeep(
bytes memory checkData
)
public
view
override
returns (bool upkeepNeeded, bytes memory /* performData */)
{
bool isOpen = RaffleState.OPEN == s_raffleState;
bool timePassed = ((block.timestamp - s_lastTimeStamp) > i_interval);
bool hasPlayers = s_players.length > 0;
bool hasBalance = address(this).balance > 0;
if (timePassed && isOpen && hasBalance && hasPlayers) {
return (true, checkData);
} else {
return (false, checkData);
}
}
/**
* @dev Once `checkUpkeep` is returning `true`, this function is called
* and it kicks off a Chainlink VRF call to get a random winner.
*/
function performUpkeep(bytes calldata performData ) external override {
s_raffleState = RaffleState.CALCULATING;
uint256 requestId = _requestRandomWords();
emit RequestedRaffleWinner(requestId, performData);
}
function getRaffleState() public view returns (RaffleState) {
return s_raffleState;
}
function getNumWords() public view returns (uint256) {
return numWords;
}
function getRecentWinner() public view returns (address) {
return s_recentWinner;
}
function getPlayer(uint256 index) public view returns (address) {
return s_players[index];
}
function getLastTimeStamp() public view returns (uint256) {
return s_lastTimeStamp;
}
function getInterval() public view returns (uint256) {
return i_interval;
}
function getEntranceFee() public view returns (uint256) {
return i_entranceFee;
}
function getNumberOfPlayers() public view returns (uint256) {
return s_players.length;
}
}
</code>
<code>// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; interface AutomationCompatibleInterface { function checkUpkeep(bytes calldata checkData) external returns (bool upkeepNeeded, bytes memory performData); function performUpkeep(bytes calldata performData) external; } // File: AutoCtr.sol // File: @chainlink/contracts/src/v0.8/interfaces/KeeperCompatibleInterface.sol pragma solidity 0.8.19; import {VRFConsumerBaseV2Plus} from "@chainlink/contracts/src/v0.8/vrf/dev/VRFConsumerBaseV2Plus.sol"; import {VRFV2PlusClient} from "@chainlink/contracts/src/v0.8/vrf/dev/libraries/VRFV2PlusClient.sol"; /* Errors */ error Raffle__UpkeepNotNeeded(uint256 currentBalance, uint256 numPlayers, uint256 raffleState); error Raffle__TransferFailed(); error Raffle__SendMoreToEnterRaffle(); error Raffle__RaffleNotOpen(); /** * Request testnet LINK and ETH here: https://faucets.chain.link/ * Find information on LINK Token Contracts and get the latest ETH and LINK faucets here: https://docs.chain.link/docs/link-token-contracts/ */ /** * THIS IS AN EXAMPLE CONTRACT THAT USES HARDCODED VALUES FOR CLARITY. * THIS IS AN EXAMPLE CONTRACT THAT USES UN-AUDITED CODE. * DO NOT USE THIS CODE IN PRODUCTION. */ contract Lottery is VRFConsumerBaseV2Plus, AutomationCompatibleInterface { /* Type declarations */ enum RaffleState { OPEN, CALCULATING } // Lottery Variables uint256 private immutable i_entranceFee; uint256 private s_lastTimeStamp; address payable[] private s_players; address private s_recentWinner; uint256 private immutable i_interval; RaffleState private s_raffleState; event RequestSent(uint256 requestId, uint32 numWords); event RequestFulfilled(uint256 requestId, uint256[] randomWords); event RaffleEnter(address indexed player); event WinnerPicked(address indexed player); event RequestedRaffleWinner(uint256 indexed requestId, bytes performData); // Your subscription ID. uint256 public immutable s_subscriptionId = 78560131474220272056099479679342269674716447265552668612386115994028644171414; // Past request IDs. uint256[] public requestIds; uint256 public lastRequestId; // The gas lane to use, which specifies the maximum gas price to bump to. // For a list of available gas lanes on each network, // see https://docs.chain.link/docs/vrf/v2-5/supported-networks bytes32 public keyHash = 0x787d74caea10b2b357790d5b5247c2f63d1d91572a9846f780606e4d953677ae; // Depends on the number of requested values that you want sent to the // fulfillRandomWords() function. Storing each word costs about 20,000 gas, // so 100,000 is a safe default for this example contract. Test and adjust // this limit based on the network that you select, the size of the request, // and the processing of the callback request in the fulfillRandomWords() // function. uint32 public callbackGasLimit = 2500000; // The default is 3, but you can set this higher. uint16 public requestConfirmations = 3; // For this example, retrieve 2 random values in one request. // Cannot exceed VRFCoordinatorV2_5.MAX_NUM_WORDS. uint32 public numWords = 1; /** * HARDCODED FOR SEPOLIA * COORDINATOR: 0x9DdfaCa8183c41ad55329BdeeD9F6A8d53168B1B * https://docs.chain.link/vrf/v2-5/supported-networks#sepolia-testnet */ constructor( // uint256 subscriptionId, uint256 entranceFee, uint256 interval ) VRFConsumerBaseV2Plus(0x9DdfaCa8183c41ad55329BdeeD9F6A8d53168B1B) { // s_subscriptionId = subscriptionId; i_entranceFee = entranceFee; s_raffleState = RaffleState.OPEN; s_lastTimeStamp = block.timestamp; i_interval = interval; } // Assumes the subscription is funded sufficiently. function _requestRandomWords() private onlyOwner returns (uint256 requestId) { // Will revert if subscription is not set and funded. requestId = s_vrfCoordinator.requestRandomWords( VRFV2PlusClient.RandomWordsRequest({ keyHash: keyHash, subId: s_subscriptionId, requestConfirmations: requestConfirmations, callbackGasLimit: callbackGasLimit, numWords: numWords, extraArgs: VRFV2PlusClient._argsToBytes( VRFV2PlusClient.ExtraArgsV1({nativePayment: false}) ) }) ); requestIds.push(requestId); lastRequestId = requestId; emit RequestSent(requestId, numWords); return requestId; } function fulfillRandomWords( uint256, uint256[] calldata _randomWords ) internal override { uint256 indexOfWinner = _randomWords[0] % s_players.length; address payable recentWinner = s_players[indexOfWinner]; s_recentWinner = recentWinner; s_players = new address payable[](0); s_raffleState = RaffleState.OPEN; s_lastTimeStamp = block.timestamp; (bool success, ) = recentWinner.call{value: address(this).balance}(""); // require(success, "Transfer failed"); if (!success) { revert Raffle__TransferFailed(); } emit WinnerPicked(recentWinner); } function enterRaffle() public payable { // require(msg.value >= i_entranceFee, "Not enough value sent"); // require(s_raffleState == RaffleState.OPEN, "Raffle is not open"); if (msg.value < i_entranceFee) { revert Raffle__SendMoreToEnterRaffle(); } if (s_raffleState != RaffleState.OPEN) { revert Raffle__RaffleNotOpen(); } s_players.push(payable(msg.sender)); // Emit an event when we update a dynamic array or mapping // Named events with the function name reversed emit RaffleEnter(msg.sender); } /** * @dev This is the function that the Chainlink Keeper nodes call * they look for `upkeepNeeded` to return True. * the following should be true for this to return true: * 1. The time interval has passed between raffle runs. * 2. The lottery is open. * 3. The contract has ETH. * 4. Implicity, your subscription is funded with LINK. */ function checkUpkeep( bytes memory checkData ) public view override returns (bool upkeepNeeded, bytes memory /* performData */) { bool isOpen = RaffleState.OPEN == s_raffleState; bool timePassed = ((block.timestamp - s_lastTimeStamp) > i_interval); bool hasPlayers = s_players.length > 0; bool hasBalance = address(this).balance > 0; if (timePassed && isOpen && hasBalance && hasPlayers) { return (true, checkData); } else { return (false, checkData); } } /** * @dev Once `checkUpkeep` is returning `true`, this function is called * and it kicks off a Chainlink VRF call to get a random winner. */ function performUpkeep(bytes calldata performData ) external override { s_raffleState = RaffleState.CALCULATING; uint256 requestId = _requestRandomWords(); emit RequestedRaffleWinner(requestId, performData); } function getRaffleState() public view returns (RaffleState) { return s_raffleState; } function getNumWords() public view returns (uint256) { return numWords; } function getRecentWinner() public view returns (address) { return s_recentWinner; } function getPlayer(uint256 index) public view returns (address) { return s_players[index]; } function getLastTimeStamp() public view returns (uint256) { return s_lastTimeStamp; } function getInterval() public view returns (uint256) { return i_interval; } function getEntranceFee() public view returns (uint256) { return i_entranceFee; } function getNumberOfPlayers() public view returns (uint256) { return s_players.length; } } </code>
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

interface AutomationCompatibleInterface {
  function checkUpkeep(bytes calldata checkData) external returns (bool upkeepNeeded, bytes memory performData);
  function performUpkeep(bytes calldata performData) external;
}

// File: AutoCtr.sol

// File: @chainlink/contracts/src/v0.8/interfaces/KeeperCompatibleInterface.sol

pragma solidity 0.8.19;

import {VRFConsumerBaseV2Plus} from "@chainlink/contracts/src/v0.8/vrf/dev/VRFConsumerBaseV2Plus.sol";
import {VRFV2PlusClient} from "@chainlink/contracts/src/v0.8/vrf/dev/libraries/VRFV2PlusClient.sol";

/* Errors */
error Raffle__UpkeepNotNeeded(uint256 currentBalance, uint256 numPlayers, uint256 raffleState);
error Raffle__TransferFailed();
error Raffle__SendMoreToEnterRaffle();
error Raffle__RaffleNotOpen();

/**
 * Request testnet LINK and ETH here: https://faucets.chain.link/
 * Find information on LINK Token Contracts and get the latest ETH and LINK faucets here: https://docs.chain.link/docs/link-token-contracts/
 */

/**
 * THIS IS AN EXAMPLE CONTRACT THAT USES HARDCODED VALUES FOR CLARITY.
 * THIS IS AN EXAMPLE CONTRACT THAT USES UN-AUDITED CODE.
 * DO NOT USE THIS CODE IN PRODUCTION.
 */

contract Lottery is VRFConsumerBaseV2Plus, AutomationCompatibleInterface {
    /* Type declarations */
    enum RaffleState {
        OPEN,
        CALCULATING
    }
    // Lottery Variables
    uint256 private immutable i_entranceFee;
    uint256 private s_lastTimeStamp;
    address payable[] private s_players;
    address private s_recentWinner;
    uint256 private immutable i_interval;
    RaffleState private s_raffleState;

    event RequestSent(uint256 requestId, uint32 numWords);
    event RequestFulfilled(uint256 requestId, uint256[] randomWords);
    event RaffleEnter(address indexed player);
    event WinnerPicked(address indexed player);
    event RequestedRaffleWinner(uint256 indexed requestId, bytes performData);

    // Your subscription ID.
    uint256 public immutable s_subscriptionId =
        78560131474220272056099479679342269674716447265552668612386115994028644171414;

    // Past request IDs.
    uint256[] public requestIds;
    uint256 public lastRequestId;

    // The gas lane to use, which specifies the maximum gas price to bump to.
    // For a list of available gas lanes on each network,
    // see https://docs.chain.link/docs/vrf/v2-5/supported-networks
    bytes32 public keyHash =
        0x787d74caea10b2b357790d5b5247c2f63d1d91572a9846f780606e4d953677ae;

    // Depends on the number of requested values that you want sent to the
    // fulfillRandomWords() function. Storing each word costs about 20,000 gas,
    // so 100,000 is a safe default for this example contract. Test and adjust
    // this limit based on the network that you select, the size of the request,
    // and the processing of the callback request in the fulfillRandomWords()
    // function.
    uint32 public callbackGasLimit = 2500000;

    // The default is 3, but you can set this higher.
    uint16 public requestConfirmations = 3;

    // For this example, retrieve 2 random values in one request.
    // Cannot exceed VRFCoordinatorV2_5.MAX_NUM_WORDS.
    uint32 public numWords = 1;

    /**
     * HARDCODED FOR SEPOLIA
     * COORDINATOR: 0x9DdfaCa8183c41ad55329BdeeD9F6A8d53168B1B
     * https://docs.chain.link/vrf/v2-5/supported-networks#sepolia-testnet
     */
    constructor(
        // uint256 subscriptionId,
        uint256 entranceFee,
        uint256 interval
    ) VRFConsumerBaseV2Plus(0x9DdfaCa8183c41ad55329BdeeD9F6A8d53168B1B) {
        // s_subscriptionId = subscriptionId;
        i_entranceFee = entranceFee;
        s_raffleState = RaffleState.OPEN;
        s_lastTimeStamp = block.timestamp;
        i_interval = interval;
    }

    // Assumes the subscription is funded sufficiently.
    function _requestRandomWords()
        private
        onlyOwner
        returns (uint256 requestId)
    {
        // Will revert if subscription is not set and funded.
        requestId = s_vrfCoordinator.requestRandomWords(
            VRFV2PlusClient.RandomWordsRequest({
                keyHash: keyHash,
                subId: s_subscriptionId,
                requestConfirmations: requestConfirmations,
                callbackGasLimit: callbackGasLimit,
                numWords: numWords,
                extraArgs: VRFV2PlusClient._argsToBytes(
                    VRFV2PlusClient.ExtraArgsV1({nativePayment: false})
                )
            })
        );
        requestIds.push(requestId);
        lastRequestId = requestId;
        emit RequestSent(requestId, numWords);
        return requestId;
    }

    function fulfillRandomWords(
        uint256,
        uint256[] calldata _randomWords
    ) internal override {
        uint256 indexOfWinner = _randomWords[0] % s_players.length;
        address payable recentWinner = s_players[indexOfWinner];
        s_recentWinner = recentWinner;
        s_players = new address payable[](0);
        s_raffleState = RaffleState.OPEN;
        s_lastTimeStamp = block.timestamp;
        (bool success, ) = recentWinner.call{value: address(this).balance}("");
        // require(success, "Transfer failed");
        if (!success) {
            revert Raffle__TransferFailed();
        }
        emit WinnerPicked(recentWinner);
    }

    function enterRaffle() public payable {
        // require(msg.value >= i_entranceFee, "Not enough value sent");
        // require(s_raffleState == RaffleState.OPEN, "Raffle is not open");
        if (msg.value < i_entranceFee) {
            revert Raffle__SendMoreToEnterRaffle();
        }
        if (s_raffleState != RaffleState.OPEN) {
            revert Raffle__RaffleNotOpen();
        }
        s_players.push(payable(msg.sender));
        // Emit an event when we update a dynamic array or mapping
        // Named events with the function name reversed
        emit RaffleEnter(msg.sender);
    }

    /**
     * @dev This is the function that the Chainlink Keeper nodes call
     * they look for `upkeepNeeded` to return True.
     * the following should be true for this to return true:
     * 1. The time interval has passed between raffle runs.
     * 2. The lottery is open.
     * 3. The contract has ETH.
     * 4. Implicity, your subscription is funded with LINK.
     */
    function checkUpkeep(
        bytes memory checkData
    )
        public
        view
        override
        returns (bool upkeepNeeded, bytes memory /* performData */)
    {
        bool isOpen = RaffleState.OPEN == s_raffleState;
        bool timePassed = ((block.timestamp - s_lastTimeStamp) > i_interval);
        bool hasPlayers = s_players.length > 0;
        bool hasBalance = address(this).balance > 0;
        if (timePassed && isOpen && hasBalance && hasPlayers) {
            return (true, checkData);
        } else {
            return (false, checkData);
        }
    }

     /**
     * @dev Once `checkUpkeep` is returning `true`, this function is called
     * and it kicks off a Chainlink VRF call to get a random winner.
     */
    function performUpkeep(bytes calldata performData ) external override {
        s_raffleState = RaffleState.CALCULATING;
        uint256 requestId = _requestRandomWords();
        emit RequestedRaffleWinner(requestId, performData);
    }

    function getRaffleState() public view returns (RaffleState) {
        return s_raffleState;
    }

    function getNumWords() public view returns (uint256) {
        return numWords;
    }

    function getRecentWinner() public view returns (address) {
        return s_recentWinner;
    }

    function getPlayer(uint256 index) public view returns (address) {
        return s_players[index];
    }

    function getLastTimeStamp() public view returns (uint256) {
        return s_lastTimeStamp;
    }

    function getInterval() public view returns (uint256) {
        return i_interval;
    }

    function getEntranceFee() public view returns (uint256) {
        return i_entranceFee;
    }

    function getNumberOfPlayers() public view returns (uint256) {
        return s_players.length;
    }
}

Contract address: https://sepolia.etherscan.io/address/0xfd2eA75f66493eCF7F45072E01254c6d8C403a35#readContract
Automation detail:
https://automation.chain.link/sepolia/3269845219509365492688127324933702012403758002781625898657947000998001276879

When reading contract, the method of checkData returns true, but performUpkeep did not execute.

Expect it to run automatically。

New contributor

贰东之声 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật