# Analog.Оплачиваемый тестнет, который накормит!

By [Alex Bakugan ](https://paragraph.com/@alex-bakugan) · 2024-07-09

---

\*\*Всем привет работяги, На связи [CryptoGalaxy](https://t.me/crypto_galaxyyy)! \*\*Пока очередной тир-1 проект заставляет лить слезы многих криптанов, предлагаю рассмотреть реальный андерадар проект, который может щедро накормить, и при чем, уже очень скоро!А говорю я про децентрализованную платформу нулевого уровня, под названием **ANALOG**, которая позволяет передавать данные о событиях и данных в разных экосистемных проектах.  
  
  
**Немного о проекте:**  
**ANALOG -** это децентрализованная платформа уровня 0, предназначенная для проверки и передачи данных о событиях в различных экосистемах блокчейнов. Он использует механизм консенсуса **Proof-of-Time (PoT)** для обеспечения точности и надежности проверки данных. **Analog** стремится произвести революцию в том, как приложения взаимодействуют между собой в блокчейнах, предоставляя не требующую доверия структуру для проверки данных о событиях, что делает его важным инструментом для разработчиков, стремящихся создавать децентрализованные приложения следующего поколения.  
**Рейз:** **16 000 000**  
**Оценка**: **120 000 000**  
**Инвесторы:** **Wintermute, Orange Dao, Quantstamp, Tribe Capital, NGC Ventures**  
**Команда:**

![](https://storage.googleapis.com/papyrus_images/3961e1f455961edacb20cf5dbab1c705c9e775b52fca4d281596ad2217b9fce9.png)

**В апреле** у проекта запустился тестнет только для разработчиков, а в мае стартовал награждаемый  публичный тестнет, на который выделено 2% от общего суплая. **Всего на комьюнити выделено 27% процентов!**  
  
**ТГЕ у проекта запланирован на Q3,** а тестнет закончиться уже в конце этого месяца. Несмотря на неплохой рейз и  подтвержденный аирдроп, делают проект небольшое количество людей, в гелакси компании насчитаывается около 300к участников, а чтобы  выбиться в топ 20к лидерборда среди всей толпы, нужно всего 300 ATP(поинты), **которые можно нафармить от 5-7 дней**.  
**Для сравнения,  нашумевший проект ОМНИ**, который раздал от 500 до 1000 долларов, выделил на комьюнити меньшую сумму, при сравнительно схожей токеномикой! При том что количество участников было в разы больше.  
  
**Исходя из всех представленных данных**, вывод один, отрабатывать проект определённо стоит! Тем более осталось **меньше месяца** до окончания тестнета!**Далее** я представляю **ПОДРОБНЕЙШИЙ** гад по выполнению тестнета.**LFG** !!!

  
`1`.**Переходим по** [**ССЫЛКЕ**](https://testnet.analog.one/#/?signup&referral=PLV2PD) **и создаем аккаунт.** Почту лучше юзать gmail или mail.ru. Аккануты зареганые на почту рамблер, банят на следущий день

![](https://storage.googleapis.com/papyrus_images/1c8aae3095c8e64ac888a2c640874c2f62fbaa59dc7a6c723a1f85d5436844d2.png)

`2`.**Далее авторизовываемся на гелакси и апруваем все задания**. Искренее рекомендую сделать гелакси на 100 процентов, так как многие проекты сбривали по этому пункту!!! \*_\*\*Для того чтобы верфинуть задание «Аналог спэйс юзер, нужно подписаться на них в гелакси»\*\*\*_

![](https://storage.googleapis.com/papyrus_images/b1a641fa3d3751952e0d0c6eac6c2c97fe2ccc20dc7eb0c9d0e623f7ddf20637.png)

![](https://storage.googleapis.com/papyrus_images/bea513afddd5a88d6a7f97255f62af61e879d1e5f55d656452e0d641d5a1e23c.png)

`4.`**Простое задание с DMAIL**, где нужно просто подключить кошелек, перейдя по ссылке с их сайта. Бывает не засчитывает сразу, нужно подождать какое-то время или попробовать снова.

![](https://storage.googleapis.com/papyrus_images/ea939a765be01e24e6785dbf911d7e9ce58aebb85f52c3fea2dcc0058d96b188.png)

`5`. **Задание с квестами от кошелька TALISMAN**. Я скипнул это задание, так как для его выполнения нужно импортировать сид фразу от со своего мм в кош ТАЛИСМАН. И дает он нам только доп ХP от самого талисмана, а не ATP

![](https://storage.googleapis.com/papyrus_images/e8dc658edb7fd169fee8a7b62d674b01aca96698a3c5ca1ccd06b1fc2bd244b3.png)

`6`.**VOTING SESSION**. Это голосования, за смарт контракты, которые проходят каждые 7 день (бывают перерывы). За ваш голос дают 10ATP, а если смарт контракт, за который вы голосовали победит, вам сыпанут ещё от 30 до 50 ATP.Для этого переходим в раздел **WATCH GAME** и голосуем!

![](https://storage.googleapis.com/papyrus_images/7c4b882bd98f6aa9ecf95032615f943006ee723bbba9ced3fbc66f8e4b9a3ab5.png)

![](https://storage.googleapis.com/papyrus_images/940c6cd2c07882c5ace3698e8a493603e061ab0bc513937f5de1c4565f66f692.png)

`7`.**Переходим к основной части тестнета под названием** **DEVELOPER**

`8`.**Для начала   вам нужно установить кошелек** [**TALISMAN**](https://chromewebstore.google.com/detail/talisman-ethereum-and-pol/fijngjgcjhjmmpcmkeiomlglpeiijkld?hl=en) **авторизовать кош и выбросить сид фразу**))))

![](https://storage.googleapis.com/papyrus_images/4002a36f10a2421026824e1cddada12dc9d8e87bcd5a1777e5b5d94b74951ff7.png)

  
`9`.**После активации кошелька,** заходим в его **SETTINGS** далее >>> **Networks and Tokens**, далее>>>**Manage networks**  выбираем сеть **POLKADOT** и добавляем сеть **ANALOG TESTNET** как показано на скрине, после Нажимаем **Copy Adress** и из списка копируем адресс кошелька **ANALOG TESTNET**

![](https://storage.googleapis.com/papyrus_images/89c8fbaae2f6c5cd4f21caa9020d642bcb1c3fa7d66c375297e5a15de1842502.png)

![](https://storage.googleapis.com/papyrus_images/15892513ed36d3ea90eb28a56e37c39d21065dff779caf4ed0e8d8ec60491837.png)

![](https://storage.googleapis.com/papyrus_images/27eb41a7e2bdffa3dde97e08b4cb252a39e285d44cfc78ad89601f56ab27ba4c.png)

![](https://storage.googleapis.com/papyrus_images/97d8eff7cc1e6157cd3381d54eba6ca1f738c1906f3ef5e4f8c54bafd4e8cb44.png)

![](https://storage.googleapis.com/papyrus_images/56df263bd70f3ad3b07f08be5d491242404bc64c4f177b7afc4eff7ff6bf8032.png)

`10.`**После, чего отправляемся в** [**дискорд**](https://discord.gg/analog) **проекта** и в ветке faucet вставляем свой кош в формате **!faucet ewbfebt3gth53hg35h3r3ef3**. **Ура!** **Вы получили тестовые токены**

![](https://storage.googleapis.com/papyrus_images/9b8c1cefc484b42a58035b6b18ccc307c516a6cdf6d65424c649ec508b4eea5a.png)

`11`.**После чего конектим кош на этом** [**САЙТЕ**](https://watch.testnet.analog.one/)**!  
Тыкаем что хотим:**

![](https://storage.googleapis.com/papyrus_images/394d235f4b738976019dadb8417e0e2b9a4eafe44dcfa9330853f06b3ca53232.png)

`12`. **Заходим в My Profile, сразу пополняем свой ак тестовыми токенами, которые мы уже получили, тыкаем на DEPOSIT и апруваем транзу в коше:**

![](https://storage.googleapis.com/papyrus_images/34cf3b5c040ae07cf18aec0871670463cc33b3509bea85fff1ceaa0b91fade91.png)

`13`.**Сразу выполняем задание с созданием API Keys. Тыкаем на иконку.Create new API.Вписываем никнейм и подписываем транзу**

![](https://storage.googleapis.com/papyrus_images/f96cfefc6ef3922ea305c5687e25323f3b4541f15b0070a1c8dadc4c043a3e1f.png)

![](https://storage.googleapis.com/papyrus_images/831a2fe58e059eedfcead8d59b1892e9a34acba53df8f5f936f3c71d43cdff9e.png)

* * *

`14`. \*\*Далее отправляемся выполнять ежедневные квесты во вкладке DEVELOPERS \*\*

`15`**.**

**Build and deploy** **SMART CONTRACT.**  
Для выполнения именно этого и других заданий в этом тестнете, нам нужен будет любимый тестовый эфир в сети SEPOLIA  
**Взять его можно бесплатно:**  
[ТУТ](https://www.infura.io/faucet/sepolia)  
[ТУТ](https://sepoliafaucet.com/)  
[ТУТ](https://faucet-sepolia.rockx.com/)  
[ТУТ](https://sepolia-faucet.pk910.de/)  
\*\*Либо, если вы дорожите своими временем и нервами, можете купить всего за 2 доллара, практически в любой сети 1.2ETH SEPOLIA [ЗДЕСЬ](https://www.gas.zip/)  
\*\*  
`16.`**После того когда на нашем коше появился тестовый ETH SEPOLIA, открываем** [**REMIX**](https://remix.ethereum.org/)

`17`**.Создаем папку и файл( сприставкой .sol) как показано на скрине**

![](https://storage.googleapis.com/papyrus_images/01d6c7936d5e0da0dc91c4a1f1174b23214c3b2865720499eed2b2d6e764fa4f.png)

![](https://storage.googleapis.com/papyrus_images/2e4075de6b9943be21e2274140a24aee0b020fe82e919272badf4f294d49e9dd.png)

  
`18`**.После чего вставляем этот код в компилятор**

    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.0;
    
    interface IGmpReceiver {
        function onGmpReceived(
            bytes32 id,
            uint128 network,
            bytes32 source,
            bytes calldata payload
        ) external payable returns (bytes32);
    }
    
    contract Counter is IGmpReceiver {
        address private immutable _gateway;
        uint256 public number;
    
        constructor(address gateway) {
            _gateway = gateway;
        }
    
        function onGmpReceived(
            bytes32,
            uint128,
            bytes32,
            bytes calldata
        ) external payable returns (bytes32) {
            require(msg.sender == _gateway, "unauthorized");
            number++;
            return bytes32(number);
        }
    }
    

`18`.**Нажимаем компилер, выставляем версию 0.8.26 , ждем апрува и зеленой галочки и преходим к деплою**

![](https://storage.googleapis.com/papyrus_images/0131cc7594c71b5a4b97aa0195083a353706912de66d8dd88b484dd33ba8bca3.png)

`19`.**В окно AdressGateway вставляем оф адресс контракта**

**0xB5D83c2436Ad54046d57Cd48c00D619D702F3814  
После чего нажимаем Deploy и обязательно проверяем, чтобы в окне Injected Providet - было выбрано Metamask и сеть Sepolia!!!  
Подписываем транзу в метамаске**

![](https://storage.googleapis.com/papyrus_images/5f476f20103b9a9d32e7c07a96163091b57d307e822a37a140588734121df8df.png)

`20`.**Далее нажимаем Debug и копируем адресс контракта!**

![](https://storage.googleapis.com/papyrus_images/55a988f571bd621b3071a01e392950c32ac0ce65deb27375e63317703b6539e8.png)

![](https://storage.googleapis.com/papyrus_images/d776a46bbbf931165f1fa785f84b88d2ecd7268a5e94e58ac30684fba3ef5a21.png)

`21`**.После чего переходим на этот** [**САЙТ**](https://eth-sepolia.blockscout.com/contract-verification)`22`**.Вставляем адрес и и заполняем все с такими настройками как на скрине**

![](https://storage.googleapis.com/papyrus_images/acda2ff7e0a1c8c146e4df0ab6e479b47d14dcd566a29deebf3154b846ce80a2.png)

![](https://storage.googleapis.com/papyrus_images/e9b03595c664396d9c686834134ab6fe12ece0943a826aa476b64ffc744a358f.png)

`23`.**Вставляем наш код, который использовали в к ремиксе и нажимаем VERIFY & Publish**

![](https://storage.googleapis.com/papyrus_images/926ffecbe6f814a0488930c6ff29658da9dcf16e4910d8b701def3239084de1a.png)

`24.`**Копируем наш верифнутый контракт и вставляем в окно с этим заданием, нажимаем клейм и получаем свои 15 АТP**

![](https://storage.googleapis.com/papyrus_images/a4a02e9f37135018bfa95aa1dab3e34cea7b396718e8c6f0249a283c9dd0a33b.png)

![](https://storage.googleapis.com/papyrus_images/e201567471be9744b580ba7508cf05810bcd5a3b8ed64e3348a25210e23ab283.png)

  
`25`.**Следующие задание с отправкой сообщений, также переходим в ремикс.  
Для этого задания вам понадобиться сохранить в одну папку 4 этих кодов-файлов с такими названиями  
  
1.BranchlessMath.sol**

    // SPDX-License-Identifier: MIT
    // Analog's Contracts (last updated v0.1.0) (src/utils/BranchlessMath.sol)
    
    pragma solidity ^0.8.20;
    
    /**
     * @dev Utilities for branchless operations, useful when a constant gas cost is required.
     */
    library BranchlessMath {
        /**
         * @dev Returns the smallest of two numbers.
         */
        function min(uint256 x, uint256 y) internal pure returns (uint256) {
            return select(x < y, x, y);
        }
    
        /**
         * @dev Returns the largest of two numbers.
         */
        function max(uint256 x, uint256 y) internal pure returns (uint256) {
            return select(x > y, x, y);
        }
    
        /**
         * @dev If `condition` is true returns `a`, otherwise returns `b`.
         */
        function select(bool condition, uint256 a, uint256 b) internal pure returns (uint256) {
            unchecked {
                // branchless select, works because:
                // b ^ (a ^ b) == a
                // b ^ 0 == b
                //
                // This is better than doing `condition ? a : b` because:
                // - Consumes less gas
                // - Constant gas cost regardless the inputs
                // - Reduces the final bytecode size
                return b ^ ((a ^ b) * toUint(condition));
            }
        }
    
        /**
         * @dev If `condition` is true returns `a`, otherwise returns `b`.
         */
        function select(bool condition, address a, address b) internal pure returns (address) {
            return address(uint160(select(condition, uint256(uint160(a)), uint256(uint160(b)))));
        }
    
        /**
         * @dev If `condition` is true return `value`, otherwise return zero.
         */
        function selectIf(bool condition, uint256 value) internal pure returns (uint256) {
            unchecked {
                return value * toUint(condition);
            }
        }
    
        /**
         * @dev Unsigned saturating addition, bounds to UINT256 MAX instead of overflowing.
         * equivalent to:
         * uint256 r = x + y;
         * return r >= x ? r : UINT256_MAX;
         */
        function saturatingAdd(uint256 x, uint256 y) internal pure returns (uint256) {
            unchecked {
                x = x + y;
                y = 0 - toUint(x < y);
                return x | y;
            }
        }
    
        /**
         * @dev Unsigned saturating subtraction, bounds to zero instead of overflowing.
         * equivalent to: x > y ? x - y : 0
         */
        function saturatingSub(uint256 a, uint256 b) internal pure returns (uint256) {
            unchecked {
                // equivalent to: a > b ? a - b : 0
                return (a - b) * toUint(a > b);
            }
        }
    
        /**
         * @dev Unsigned saturating multiplication, bounds to `2 ** 256 - 1` instead of overflowing.
         */
        function saturatingMul(uint256 a, uint256 b) internal pure returns (uint256) {
            unchecked {
                uint256 c = a * b;
                bool success;
                assembly {
                    // Only true when the multiplication doesn't overflow
                    // (c / a == b) || (a == 0)
                    success := or(eq(div(c, a), b), iszero(a))
                }
                return c | (toUint(success) - 1);
            }
        }
    
        /**
         * @dev Unsigned saturating division, bounds to UINT256 MAX instead of overflowing.
         */
        function saturatingDiv(uint256 x, uint256 y) internal pure returns (uint256 r) {
            assembly {
                r := div(x, y)
            }
        }
    
        /**
         * @dev Returns the ceiling of the division of two numbers.
         *
         * This differs from standard division with `/` in that it rounds towards infinity instead
         * of rounding towards zero.
         */
        function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {
            unchecked {
                // The following calculation ensures accurate ceiling division without overflow.
                // Since a is non-zero, (a - 1) / b will not overflow.
                // The largest possible result occurs when (a - 1) / b is type(uint256).max,
                // but the largest value we can obtain is type(uint256).max - 1, which happens
                // when a = type(uint256).max and b = 1.
                return selectIf(a > 0, ((a - 1) / b + 1));
            }
        }
    
        /**
         * @dev Cast a boolean (false or true) to a uint256 (0 or 1) with no jump.
         */
        function toUint(bool b) internal pure returns (uint256 u) {
            /// @solidity memory-safe-assembly
            assembly {
                u := iszero(iszero(b))
            }
        }
    
        /**
         * @dev Cast an address to uint256
         */
        function toUint(address addr) internal pure returns (uint256) {
            return uint256(uint160(addr))    }
    }
    

**2.Counter.sol**

    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.0;
    
    interface IGmpReceiver {
        function onGmpReceived(bytes32 id, uint128 network, bytes32 source, bytes calldata payload)
            external
            payable
            returns (bytes32);
    }
    
    contract Counter is IGmpReceiver {
        address private immutable _gateway;
        uint256 public number;
    
        // address 0x000000007f56768de3133034fa730a909003a165
        constructor(address gateway) {
            _gateway = gateway;
        }
    
        function onGmpReceived(bytes32, uint128, bytes32, bytes calldata) external payable returns (bytes32) {
            require(msg.sender == _gateway, "unauthorized");
            number++;
            return bytes32(number);
        }
    }
    

**3.IGateway.sol**

    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.0;
    
    import {GmpSender} from "./Primitives.sol";
    
    /**
    * @dev Required interface of an Gateway compliant contract
    */
    
    /*
    At Address - 0x000000007f56768de3133034fa730a909003a165
    
    submitMessage:
    gasLimit 30000
    data     0x01
    sepolia address 0xF871c929bE8Cd8382148C69053cE5ED1a9593EA7 and net 7
    shibuya address 0xB5D83c2436Ad54046d57Cd48c00D619D702F3814 and net 5
    */
    
    interface IGateway {
        event GmpCreated(
            bytes32 indexed id,
            bytes32 indexed source,
            address indexed destinationAddress,
            uint16 destinationNetwork,
            uint256 executionGasLimit,
            uint256 salt,
            bytes data
        );
    
        function networkId() external view returns (uint16);
    
        function deposit(GmpSender sender, uint16 sourceNetwork) external payable;
    
        function depositOf(GmpSender sender, uint16 sourceNetwork) external view returns (uint256);
    
        function submitMessage(
            address destinationAddress,
            uint16 destinationNetwork,
            uint256 executionGasLimit,
            bytes calldata data
        ) external payable returns (bytes32);
    }
    

**4.Primitives.sol**

    // SPDX-License-Identifier: MIT
    // Analog's Contracts (last updated v0.1.0) (src/Primitives.sol)
    
    pragma solidity >=0.8.0;
    
    import {BranchlessMath} from "./BranchlessMath.sol";
    
    /**
     * @dev GmpSender is the sender of a GMP message
     */
    type GmpSender is bytes32;
    
    /**
     * @dev Tss public key
     * @param yParity public key y-coord parity, the contract converts it to 27/28
     * @param xCoord affine x-coordinate
     */
    struct TssKey {
        uint8 yParity;
        uint256 xCoord;
    }
    
    /**
     * @dev Schnorr signature.
     * OBS: what is actually signed is: keccak256(abi.encodePacked(R, parity, px, nonce, message))
     * Where `parity` is the public key y coordinate stored in the contract, and `R` is computed from `e` and `s` parameters.
     * @param xCoord public key x coordinates, y-parity is stored in the contract
     * @param e Schnorr signature e component
     * @param s Schnorr signature s component
     */
    struct Signature {
        uint256 xCoord;
        uint256 e;
        uint256 s;
    }
    
    /**
     * @dev GMP payload, this is what the timechain creates as task payload
     * @param source Pubkey/Address of who send the GMP message
     * @param srcNetwork Source chain identifier (for ethereum networks it is the EIP-155 chain id)
     * @param dest Destination/Recipient contract address
     * @param destNetwork Destination chain identifier (it's the EIP-155 chain_id for ethereum networks)
     * @param gasLimit gas limit of the GMP call
     * @param salt Message salt, useful for sending two messages with same content
     * @param data message data with no specified format
     */
    struct GmpMessage {
        GmpSender source;
        uint16 srcNetwork;
        address dest;
        uint16 destNetwork;
        uint256 gasLimit;
        uint256 salt;
        bytes data;
    }
    
    /**
     * @dev Message payload used to revoke or/and register new shards
     * @param revoke Shard's keys to revoke
     * @param register Shard's keys to register
     */
    struct UpdateKeysMessage {
        TssKey[] revoke;
        TssKey[] register;
    }
    
    /**
     * @dev Message payload used to revoke or/and register new shards
     * @param revoke Shard's keys to revoke
     * @param register Shard's keys to register
     */
    struct Network {
        uint16 id;
        address gateway;
    }
    
    /**
     * @dev Status of a GMP message
     */
    enum GmpStatus {
        NOT_FOUND,
        SUCCESS,
        REVERT,
        INSUFFICIENT_FUNDS,
        PENDING
    }
    
    /**
     * @dev EIP-712 utility functions for primitives
     */
    library PrimitiveUtils {
        /**
         * @dev GMP message EIP-712 Type Hash.
         * Declared as raw value to enable it to be used in inline assembly
         * keccak256("GmpMessage(bytes32 source,uint16 srcNetwork,address dest,uint16 destNetwork,uint256 gasLimit,uint256 salt,bytes data)")
         */
        bytes32 internal constant GMP_MESSAGE_TYPE_HASH = 0xeb1e0a6b8c4db87ab3beb15e5ae24e7c880703e1b9ee466077096eaeba83623b;
    
        function toAddress(GmpSender sender) internal pure returns (address) {
            return address(uint160(uint256(GmpSender.unwrap(sender))));
        }
    
        function toSender(address addr, bool isContract) internal pure returns (GmpSender) {
            uint256 sender = BranchlessMath.toUint(isContract) << 160 | uint256(uint160(addr));
            return GmpSender.wrap(bytes32(sender));
        }
    
        // computes the hash of an array of tss keys
        function eip712hash(TssKey memory tssKey) internal pure returns (bytes32) {
            return keccak256(abi.encode(keccak256("TssKey(uint8 yParity,uint256 xCoord)"), tssKey.yParity, tssKey.xCoord));
        }
    
        // computes the hash of an array of tss keys
        function eip712hash(TssKey[] memory tssKeys) internal pure returns (bytes32) {
            bytes memory keysHashed = new bytes(tssKeys.length * 32);
            uint256 ptr;
            assembly {
                ptr := keysHashed
            }
            for (uint256 i = 0; i < tssKeys.length; i++) {
                bytes32 hash = eip712hash(tssKeys[i]);
                assembly {
                    ptr := add(ptr, 32)
                    mstore(ptr, hash)
                }
            }
    
            return keccak256(keysHashed);
        }
    
        // computes the hash of the fully encoded EIP-712 message for the domain, which can be used to recover the signer
        function eip712hash(UpdateKeysMessage memory message) internal pure returns (bytes32) {
            return keccak256(
                abi.encode(
                    keccak256("UpdateKeysMessage(TssKey[] revoke,TssKey[] register)TssKey(uint8 yParity,uint256 xCoord)"),
                    eip712hash(message.revoke),
                    eip712hash(message.register)
                )
            );
        }
    
        function eip712TypedHash(UpdateKeysMessage memory message, bytes32 domainSeparator)
            internal
            pure
            returns (bytes32)
        {
            return _computeTypedHash(domainSeparator, eip712hash(message));
        }
    
        function eip712hash(GmpMessage memory message) internal pure returns (bytes32 id) {
            bytes memory data = message.data;
            /// @solidity memory-safe-assembly
            assembly {
                // keccak256(message.data)
                id := keccak256(add(data, 32), mload(data))
    
                // now compute the GmpMessage Type Hash without memory copying
                let offset := sub(message, 32)
                let backup := mload(offset)
                {
                    mstore(offset, GMP_MESSAGE_TYPE_HASH)
                    {
                        let offset2 := add(offset, 0xe0)
                        let backup2 := mload(offset2)
                        mstore(offset2, id)
                        id := keccak256(offset, 0x100)
                        mstore(offset2, backup2)
                    }
                }
                mstore(offset, backup)
            }
        }
    
        function encodeCallback(GmpMessage calldata message, bytes32 domainSeparator)
            internal
            pure
            returns (bytes32 messageHash, bytes memory r)
        {
            bytes calldata data = message.data;
            /// @solidity memory-safe-assembly
            assembly {
                r := mload(0x40)
    
                // GmpMessage Type Hash
                mstore(add(r, 0x0004), GMP_MESSAGE_TYPE_HASH)
                mstore(add(r, 0x0024), calldataload(add(message, 0x00))) // message.source
                mstore(add(r, 0x0044), calldataload(add(message, 0x20))) // message.srcNetwork
                mstore(add(r, 0x0064), calldataload(add(message, 0x40))) // message.dest
                mstore(add(r, 0x0084), calldataload(add(message, 0x60))) // message.destNetwork
                mstore(add(r, 0x00a4), calldataload(add(message, 0x80))) // message.gasLimit
                mstore(add(r, 0x00c4), calldataload(add(message, 0xa0))) // message.salt
    
                // Copy message.data to memory
                let size := data.length
                mstore(add(r, 0x0104), size) // message.data length
                calldatacopy(add(r, 0x0124), data.offset, size) // message.data
    
                // Computed GMP Typed Hash
                messageHash := keccak256(add(r, 0x0124), size) // keccak(message.data)
                mstore(add(r, 0x00e4), messageHash)
                messageHash := keccak256(add(r, 0x04), 0x0100) // GMP eip712 hash
                mstore(0, 0x1901)
                mstore(0x20, domainSeparator)
                mstore(0x40, messageHash) // this will be restored at the end of this function
                messageHash := keccak256(0x1e, 0x42) // GMP Typed Hash
    
                // onGmpReceived
                size := and(add(size, 31), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0)
                size := add(size, 0xa4)
                mstore(add(r, 0x0064), 0x01900937) // selector
                mstore(add(r, 0x0060), size) // length
                mstore(add(r, 0x0084), messageHash) // GMP Typed Hash
                mstore(add(r, 0x00a4), calldataload(add(message, 0x20))) // msg.network
                mstore(add(r, 0x00c4), calldataload(add(message, 0x00))) // msg.source
                mstore(add(r, 0x00e4), 0x80) // msg.data offset
    
                size := and(add(size, 31), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0)
                size := add(size, 0x60)
                mstore(0x40, add(add(r, size), 0x40))
                r := add(r, 0x60)
            }
        }
    
        function eip712TypedHash(GmpMessage memory message, bytes32 domainSeparator)
            internal
            pure
            returns (bytes32 messageHash)
        {
            messageHash = eip712hash(message);
            messageHash = _computeTypedHash(domainSeparator, messageHash);
        }
    
        function _computeTypedHash(bytes32 domainSeparator, bytes32 messageHash) private pure returns (bytes32 r) {
            /// @solidity memory-safe-assembly
            assembly {
                mstore(0, 0x1901000000000000000000000000000000000000000000000000000000000000)
                mstore(0x02, domainSeparator)
                mstore(0x22, messageHash)
                r := keccak256(0, 0x42)
                mstore(0x22, 0)
            }
        }
    }
    

  
  
`26`.\*\*Сохраняем в папку и нажимаем в ремиксе Open your file from your file system. Выбираем все файлы и добавляем в ремикс \*\*

![](https://storage.googleapis.com/papyrus_images/a6ec7a1c9f1f411d98471a64158d88f4a4c3e9f9c15c7cf4563557d35037195c.png)

![](https://storage.googleapis.com/papyrus_images/513b701f12abf99557bd6b1ac624bc6336b77fdbb3b3e641f93d66352ead140d.png)

`27`.**После чего выбираем IGateway.sol, нажимаем compile, Injected Provider-Metamask, сеть Sepolia**

![](https://storage.googleapis.com/papyrus_images/b67c9dccea5582004c0dc903756d354dc1a59c1cd2b1c856bd7f5ccc6a411fb8.png)

`28`.**Ждем апрува и переходим к отправке сообщения. В окно At address добавляем этот адресс 0x000000007f56768de3133034fa730a909003a165, как показано на скрине**

![](https://storage.googleapis.com/papyrus_images/4140e0f20959476dbcf4dfa6afd29631af85e82c456651efde1d460deb0f7ccd.png)

  
`29`**После чего появляется igataway оконо , где нужно выбрать SUBMIT MESSAGE и заполнить следующие данные:  
Destination address: 0xF871c929bE8Cd8382148C69053cE5ED1a9593EA7  
DestinationNetwork:7  
ExecutionGasLimit: 30 000  
Data : 0x01**

**После чего наживаем TRANSACT**

![](https://storage.googleapis.com/papyrus_images/845c68dfc24eb749dad2682520fcb842eabf86a095d35925a0e28e3a8562833b.png)

![](https://storage.googleapis.com/papyrus_images/6380136b07e6781fd23f676fc07009e317a207e0b3c450a87dd289b86bb27b71.png)

`30`.**После чего подписываем транзакцию в мм и копируем хэш как на скрине**

![](https://storage.googleapis.com/papyrus_images/fbde9407258d1240ea23f6f3c3863313f0ef411b8324b2e1c0764f51e6093503.png)

  
`31`.**И вставляем его в это задание и получаем 20 ATP**_( есть нюанс, транзакция идет от пол часа, поэтому нужно вставить и нажать клейм  спустя какое то время)_

![](https://storage.googleapis.com/papyrus_images/a658ec29b0b8538a847914921688452a356efcf037da8496ec136c272655d25e.png)

`32`**.Далее нам нужно выполнить те же задания с только в сети SHIBULIA.Для этого нам нужны тестовые токены в этой сети. Отправляемся** [**СЮДА**](https://portal.astar.network/shibuya-testnet/assets)**, подключаем кошелек, добавляем сеть SHIBULIA , нажимаем на капельку и получаем тестовые токены**

![](https://storage.googleapis.com/papyrus_images/fe9fb9d6a85eced4d1f3a229fe77ac4311b66ef9b138893c4d9014530c56dd72.png)

  
`33`.**После чего отправляемся на  Remix и проделываем в се тоже самое, что и в предыдущий раз с первым деплоем, только выбрав сеть SHIBULIAСоздаем файл, вставляем этот код**  
\\

\`// SPDX-License-Identifier: MIT pragma solidity ^0.8.0;

interface IGmpReceiver { function onGmpReceived(bytes32 id, uint128 network, bytes32 source, bytes calldata payload) external payable returns (bytes32); }

contract Counter is IGmpReceiver { address private immutable \_gateway; uint256 public number;

    // example gw 0x7702eD777B5d6259483baAD0FE8b9083eF937E2A
    constructor(address gateway) {
        _gateway = gateway;
    }
    
    function onGmpReceived(bytes32, uint128, bytes32, bytes calldata) external payable returns (bytes32) {
        require(msg.sender == _gateway, "unauthorized");
        number++;
        return bytes32(number);
    }
    

}`\ \`34\`**.Нажимаем Compile, ждем верифа, переходим к деплою и в окно Att adress вставляем уже этот адресс  
0x7702eD777B5d6259483baAD0FE8b9083eF937E2A  
Нажимаем деплой, подписываем транзакцию и копируем адресс конракта.**

![](https://storage.googleapis.com/papyrus_images/b814ea44b2d322de242cee47c48724421557c72a0fa9ce9b6b28bd528f9469c2.png)

`35`**.После чего отправляемся** [**СЮДА**](https://shibuya.blockscout.com/contract-verification)**, вставляем адресс контракта, выбираем все те же настройки что и при предыдущем верифе, вставляем этот же код, что и в ремиксе и верифнутый контракт вставляем в окно с заданием на сайте и получаем 15 ATP!**

![](https://storage.googleapis.com/papyrus_images/1bc979ae455b313348f6be22cde911a9dd66a7278d531b843e7a8d101e91c7d9.png)

  
`36`.**Задание с отправкой сообщения в сети Shibulia приостановили:( и по ответам модереров в дисе, скорее всего уже не вернут. Поэтому нам осталось выполнить ежедневные задания на сайте ANALOG WATCH**

![](https://storage.googleapis.com/papyrus_images/8e0aec5b9b09e7b241a07dcee114ec578a0ca9dc350241bb56880db23a9b94df.png)

\*\*  
37.Для выполнения выполнения задание LIST SMART CONTRACT нам также необходимо задеплоить ещё один смарт котракт. Также отправляемся на [REMIX](https://remix.ethereum.org/)  
Создаем файл с приставкой .sol как и в прошлые разы. Юзать также можно этот код  
  
  
\*\*  
\` // SPDX-License-Identifier: MIT pragma solidity ^0.8.0;

interface IGmpReceiver { function onGmpReceived(bytes32 id, uint128 network, bytes32 source, bytes calldata payload) external payable returns (bytes32); }

contract Counter is IGmpReceiver { address private immutable \_gateway; uint256 public number;

    // example gw 0x7702eD777B5d6259483baAD0FE8b9083eF937E2A
    constructor(address gateway) {
        _gateway = gateway;
    }
    
    function onGmpReceived(bytes32, uint128, bytes32, bytes calldata) external payable returns (bytes32) {
        require(msg.sender == _gateway, "unauthorized");
        number++;
        return bytes32(number);
    }
    

}\`

  
\*\*Также выбираем сеть sepolia, в окно Adress вставляем этот код  
0x7702eD777B5d6259483baAD0FE8b9083eF937E2A  
Нажимаем делой, подписываем транзу и копируем адресс контракта \*\*

![](https://storage.googleapis.com/papyrus_images/17306d2554479fd268462a147103b0426322e83aaaf8fb71a454a21023d2912b.png)

  
38.**Далее идем на** [**САЙТ**](https://watch.testnet.analog.one/)**, нажимаем Smart Contract**

![](https://storage.googleapis.com/papyrus_images/4d6a1a8550e5149ce894fefc729c6ff7b7175bb4d4c234d7a3a297cd22436b02.png)

**Вставляем этот адрес, пишем символ, придумываем рандомное описание и выбираем теги, и нажимаем add function**

![](https://storage.googleapis.com/papyrus_images/b112123571069d0f8fd83377fac47269c5339c6e737dce8db94e7c4274c927a9.png)

  
`39`.**Далее нужно вставить ABI, находится он в ремиксе, вот здесь ! Копируем его и вставляем !**

![](https://storage.googleapis.com/papyrus_images/7da06f84a285be52532fbb773adef07b17aa897d1d13808b77f4e10534adf5e0.png)

![](https://storage.googleapis.com/papyrus_images/e44b7f8c689db23af1a3e8eab0cf262864881bd90fc857be1b58c38507ae88fe.png)

**40**.**Выбираем эту функцию  и тыкаем LIST**

![](https://storage.googleapis.com/papyrus_images/41dcbf073f458fd7e749a9cab0bc5c989b5d3637ab30cb26e3c56f60f281c49b.png)

`41`.**Сюдаааа, задание с контрактом мы выолняли! Выполняй это упражнение 1 раз в день и получай 5 АТP.Юзать один и тот же код можно! Главное каждый раз создавать новый смарт котракт**

![](https://storage.googleapis.com/papyrus_images/e453009b7953ce03aadc9ac3464ac2f39cbef03f42ba03ed7197c73e5780d56e.png)

`42`.**Далее нам нужно выолнить задание Build and deploy a View!  
Перходим сюда и из 163000 тысяч контрактов, находим те, где больше 2 функций, вписаваем рандом как на скрине и нажимаем Test query, если выдает ошибку, gjghj,eqnt новый контракт! Почему то деплоются только те, что с больше 2 функциями**

![](https://storage.googleapis.com/papyrus_images/a75a66b00bd9ea73f28f0e6504f9f1e1a268dcc476293eda04c2793a4a9f779c.png)

![](https://storage.googleapis.com/papyrus_images/6d0509688a62fe82c24d0135cd41face1a30ea3bae70f92f19ee9d7f0f3d5f96.png)

![](https://storage.googleapis.com/papyrus_images/e7437a90304513e50e5d476a3a4e7bee1ba9fbe5b2a3842efa7a9347f82b998b.png)

`43`.**Нажимаем деплой, также вписываем теги и описание и нажимаем некст**

![](https://storage.googleapis.com/papyrus_images/f0bce1d903c559bba9447512e2fde86e3d7c7eb7f2d8f0555f4329088a83ffb6.png)

**ВЫБИРАЕМ И ТЫКАЕМ РАНДОМ**

![](https://storage.googleapis.com/papyrus_images/89ddf3fe00316c0a707a9763e38f2c8d1532665939fc2cd2739b4d6ca04320f9.png)

\*\* Нажимаем Go to view PAge   и нажмаем Add Funds.  
Донатим немного тестовых токенов.\*\*

![](https://storage.googleapis.com/papyrus_images/ae212d862d86dff7195e7d4c666d46b35f9e38f40a9f754e19684d36afe64466.png)

`44`.**Вот мы и выполнили тестовое дейлки на вотч гейм. Выполняя 3 задания в день, фармится 22ATP**

![](https://storage.googleapis.com/papyrus_images/659bbf044a0671365f6c18ff7b07bafc174559c689adb61c019ffd50068e6b85.png)

**Есть выжившие? Кто дошел до конца - настоящий красавец, ведь сложность отработки проекта уменьшает конкуренцию, что увеличивает шансы на больший профит!  
До конца тестнета остается около 3 недель, а информацию о точной дате TGE и запуске майнета команда должны сообщить в ближайшее время! Если ещё не отрабатывал проект, самое время запрыгнуть в последний вагон. LFG!!!**

**Также настоятельно рекомендую выполнить на фулл гелакси компанию и иметь транзы и мин баланс в ефир сетке. Проекты, которые запускают тестнеты- часто за это бреют. Всем удачи!!!**

  
  
[Tg канал](https://t.me/crypto_galaxyyy)

[https://t.me/crypto\_galaxyyy](https://t.me/crypto_galaxyyy)

[Чат](https://t.me/crypto_galaxy_chat)

[https://t.me/crypto\_galaxy\_chat](https://t.me/crypto_galaxy_chat)

---

*Originally published on [Alex Bakugan ](https://paragraph.com/@alex-bakugan/analog)*
