<?xml version="1.0" encoding="utf-8" ?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:tt="http://teletype.in/" xmlns:opensearch="http://a9.com/-/spec/opensearch/1.1/"><title>Dma ProCrypto</title><subtitle>Автор канала о разработке, Web3, solidity - Dima ProCrypto. 
Интересуюсь технологией blockchain с 2014 года.</subtitle><author><name>Dma ProCrypto</name></author><id>https://teletype.in/atom/dimaprocrypto</id><link rel="self" type="application/atom+xml" href="https://teletype.in/atom/dimaprocrypto?offset=0"></link><link rel="alternate" type="text/html" href="https://teletype.in/@dimaprocrypto?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=dimaprocrypto"></link><link rel="next" type="application/rss+xml" href="https://teletype.in/atom/dimaprocrypto?offset=10"></link><link rel="search" type="application/opensearchdescription+xml" title="Teletype" href="https://teletype.in/opensearch.xml"></link><updated>2026-04-05T14:59:44.774Z</updated><entry><id>dimaprocrypto:hardhat_deploy</id><link rel="alternate" type="text/html" href="https://teletype.in/@dimaprocrypto/hardhat_deploy?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=dimaprocrypto"></link><title>Deploy smart-contract with HardHat</title><published>2022-12-06T11:42:29.023Z</published><updated>2023-02-28T10:27:29.254Z</updated><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://img3.teletype.in/files/aa/f3/aaf354a3-a573-40d5-8771-29c25112145e.png"></media:thumbnail><summary type="html">В этой статье я по шагам опишу как задеплоить и верифицировать смарт-контракт при помощи HardHat.</summary><content type="html">
  &lt;p id=&quot;mog0&quot;&gt;В этой статье я по шагам опишу как задеплоить и верифицировать смарт-контракт при помощи HardHat.&lt;/p&gt;
  &lt;p id=&quot;de4g&quot;&gt;Полный туториал можно посмотреть в моем видео: &lt;a href=&quot;https://youtu.be/AJduzEcD0QY&quot; target=&quot;_blank&quot;&gt;https://youtu.be/AJduzEcD0QY&lt;/a&gt;&lt;/p&gt;
  &lt;p id=&quot;LQ8e&quot;&gt;Некоторые детали, я опущу, ожидая, что у вас уже есть некоторый опы.&lt;/p&gt;
  &lt;p id=&quot;tmsV&quot;&gt;И так:&lt;/p&gt;
  &lt;p id=&quot;0egj&quot;&gt;1. Устанавливаем Metamask, если еще нет: &lt;a href=&quot;https://metamask.io/download/&quot; target=&quot;_blank&quot;&gt;https://metamask.io/download/&lt;/a&gt;&lt;/p&gt;
  &lt;p id=&quot;cv33&quot;&gt;2. Скачиваем Node.js и устанавливаем на компьютер (необходимо для работы HardHat)&lt;/p&gt;
  &lt;p id=&quot;yn2a&quot;&gt;3. Создаем папку для проекта и переходим в нее&lt;/p&gt;
  &lt;pre id=&quot;TxQd&quot;&gt;  mkdir Ethereum
  cd ./Ethereum&lt;/pre&gt;
  &lt;p id=&quot;qlLn&quot;&gt;4. Устанавливаем HardHat&lt;/p&gt;
  &lt;pre id=&quot;uPYU&quot;&gt; npm install --save-dev hardhat&lt;/pre&gt;
  &lt;p id=&quot;q5XN&quot;&gt;5. Создаем новый проект&lt;/p&gt;
  &lt;pre id=&quot;vN9n&quot;&gt;npx hardhat&lt;/pre&gt;
  &lt;p id=&quot;chzQ&quot;&gt;в терминале выбираем js&lt;/p&gt;
  &lt;p id=&quot;NgCz&quot;&gt;6. Устанавливаем дополнительные пакеты: OpenZepplin (понадобятся в любом случае!), dotenv, ethersnan&lt;/p&gt;
  &lt;pre id=&quot;2dH3&quot;&gt;  npm install --save-dev @nomiclabs/hardhat-etherscan
  npm install dotenv  
  npm install @openzeppelin/contracts&lt;/pre&gt;
  &lt;p id=&quot;q2eT&quot;&gt;про dotenv можно почитать здесь &lt;a href=&quot;https://www.npmjs.com/package/dotenv&quot; target=&quot;_blank&quot;&gt;https://www.npmjs.com/package/dotenv&lt;/a&gt;&lt;/p&gt;
  &lt;p id=&quot;ou0K&quot;&gt;7. Открываем проект в редакторе и настроим hardhat.config.js&lt;/p&gt;
  &lt;p id=&quot;iSa3&quot;&gt;- необходимо настроить network&lt;/p&gt;
  &lt;p id=&quot;lQkf&quot;&gt;по дефолту:&lt;/p&gt;
  &lt;pre id=&quot;KMZ8&quot;&gt;    networks: {
    hardhat: {
    },
    goerli: {
      url: &amp;quot;https://eth-goerli.alchemyapi.io/v2/123abc123abc123abc123abc123abcde&amp;quot;,
      accounts: [privateKey1, privateKey2, ...]
    }
  }&lt;/pre&gt;
  &lt;p id=&quot;GsMI&quot;&gt;через dotenv:&lt;/p&gt;
  &lt;p id=&quot;GTPe&quot;&gt;создаем в корне файл .env&lt;/p&gt;
  &lt;p id=&quot;FL1d&quot;&gt;  ‼️ не забудьте добавить исключение в файл .gitignore, если планируете заливать папку на git&lt;/p&gt;
  &lt;p id=&quot;4ABo&quot;&gt;прописываем необходимые переменные:&lt;/p&gt;
  &lt;pre id=&quot;23qf&quot;&gt;  NETWORK=&amp;quot;sepolia&amp;quot;
  INFURA_URL=&amp;quot;https://sepolia.infura.io/v3/xxx0000&amp;quot;
  PRIVATE_KEY=&amp;quot;xxx000xxx&amp;quot;
  ETHERSCAN_API=&amp;quot;xxx000&amp;quot;&lt;/pre&gt;
  &lt;p id=&quot;3UKp&quot;&gt;где:&lt;/p&gt;
  &lt;ul id=&quot;HPc8&quot;&gt;
    &lt;li id=&quot;JZPZ&quot;&gt;вместо sepolia указываем совою сеть, в которую собираетесь деплоить контракт&lt;/li&gt;
    &lt;li id=&quot;EnEz&quot;&gt;регистрируемся на сайте &lt;a href=&quot;https://app.infura.io/&quot; target=&quot;_blank&quot;&gt;https://app.infura.io/&lt;/a&gt; , нажимаем на кнопку CREATE NEW KEY и выбираем нужную ссылку на вашу сеть, вставляем в кавычки INFURA_URL&lt;/li&gt;
    &lt;li id=&quot;0f9e&quot;&gt;заходим в Metamask, &amp;quot;три точки&amp;quot; -&amp;gt; реквизиты счета -&amp;gt; экспорт закрытого ключа, вставляем в PRIVATE_KEY&lt;/li&gt;
    &lt;li id=&quot;aFSH&quot;&gt;заходим на сайт &lt;a href=&quot;https://etherscan.io&quot; target=&quot;_blank&quot;&gt;https://etherscan.io&lt;/a&gt; , регистрируемся и в меню, которое раскрывается по клику на ваш ник в верхнем правом углу, нажимаем API Keys -&amp;gt; +Add вводим название -&amp;gt; create -&amp;gt; копируем новый ключ&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;5ZEJ&quot;&gt;Вставляем в hardhat.config.js&lt;/p&gt;
  &lt;pre id=&quot;irHs&quot;&gt;    networks: {
     [process.env.NETWORK] : {
       url: process.env.INFURA_URL,
       accounts: [process.env.PRIVATE_KEY]
     }
    }&lt;/pre&gt;
  &lt;p id=&quot;KbVH&quot;&gt;8. Импортируем необходимые зависимости&lt;/p&gt;
  &lt;pre id=&quot;wk3V&quot;&gt;require(&amp;quot;@nomiclabs/hardhat-etherscan&amp;quot;);
require(&amp;#x27;dotenv&amp;#x27;).config();&lt;/pre&gt;
  &lt;p id=&quot;9uds&quot;&gt;9. Проверим настройки HardHat&lt;/p&gt;
  &lt;pre id=&quot;8jcq&quot;&gt; npx hardhat&lt;/pre&gt;
  &lt;p id=&quot;YicO&quot;&gt;если все норм - выпадет список команд&lt;/p&gt;
  &lt;p id=&quot;kmFy&quot;&gt;10. Удаляем стандартный (Lock.sol)  и создаем ваш контракт в папке contracts&lt;/p&gt;
  &lt;p id=&quot;9Q2I&quot;&gt;после сохраниения скомпилируем контракты&lt;/p&gt;
  &lt;pre id=&quot;2nUO&quot;&gt;npx hardhat compile&lt;/pre&gt;
  &lt;p id=&quot;cktG&quot;&gt;11. Настроим скрип deploy.js&lt;/p&gt;
  &lt;p id=&quot;gYk7&quot;&gt;настройка зависит от конфигурации ваших контрактов (наличия аргументов и др)&lt;/p&gt;
  &lt;p id=&quot;sPeM&quot;&gt;стандартный файл выглядит так&lt;/p&gt;
  &lt;pre id=&quot;1hVc&quot;&gt;const hre = require(&amp;quot;hardhat&amp;quot;);

async function main() {
  const TokenDrop = await hre.ethers.getContractFactory(&amp;quot;TokenDrop&amp;quot;);
  const tokenDrop = await TokenDrop.deploy();

  await tokenDrop.deployed();

  console.log(&amp;quot;TokenDrop:&amp;quot;, tokenDrop.address);
}

// We recommend this pattern to be able to use async/await everywhere
// and properly handle errors.
main().catch((error) =&amp;gt; {
  console.error(error);
  process.exitCode = 1;
});
&lt;/pre&gt;
  &lt;p id=&quot;KufZ&quot;&gt;вместо TokenDrop прописываем названия своего контракта, также с большой и маленькой буквы&lt;/p&gt;
  &lt;p id=&quot;Qy48&quot;&gt;12. Deploy смарт-контракта&lt;/p&gt;
  &lt;p id=&quot;ox1U&quot;&gt; перед деплоем можно очистить скомпилированные контракты&lt;/p&gt;
  &lt;pre id=&quot;bC3M&quot;&gt;npx hardhat clean&lt;/pre&gt;
  &lt;p id=&quot;5R7i&quot;&gt;запускаем деплой&lt;/p&gt;
  &lt;pre id=&quot;eUB4&quot;&gt;npx hardhat run scripts/deploy.js --network sepolia&lt;/pre&gt;
  &lt;p id=&quot;4z7e&quot;&gt;13. Верифицируем смарт-контракт&lt;/p&gt;
  &lt;p id=&quot;QyYt&quot;&gt;для реботы etherscan в hardhat.config.js необходимо добавить:&lt;/p&gt;
  &lt;pre id=&quot;tpF0&quot;&gt;  etherscan: {
    apiKey: process.env.ETHERSCAN_API
  }&lt;/pre&gt;
  &lt;p id=&quot;YNYu&quot;&gt;после этого можно запустить команду для верификации&lt;/p&gt;
  &lt;pre id=&quot;YNYu&quot;&gt;npx hardhat verify xxx000xxx --network goerli&lt;/pre&gt;
  &lt;p id=&quot;hYJb&quot;&gt;При использовании аргументов при деплое, необходимо указать их в конце команды в ковычках&lt;/p&gt;
  &lt;pre id=&quot;PPEE&quot;&gt;npx hardhat verify CONTRACT_VER --network goerli &amp;quot;0xaC560B3BC37EC0B1D4600000000000000&amp;quot; &amp;quot;100&amp;quot;&lt;/pre&gt;
  &lt;p id=&quot;ztrD&quot;&gt;Если все успешно вы увидите надпись success в терминале.&lt;/p&gt;
  &lt;p id=&quot;FCcJ&quot;&gt;Более подробно я рассказываю в своем видео:  &lt;a href=&quot;https://youtu.be/AJduzEcD0QY&quot; target=&quot;_blank&quot;&gt;https://youtu.be/AJduzEcD0QY&lt;/a&gt;&lt;/p&gt;

</content></entry><entry><id>dimaprocrypto:usdtTransferFrom</id><link rel="alternate" type="text/html" href="https://teletype.in/@dimaprocrypto/usdtTransferFrom?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=dimaprocrypto"></link><title>Как использовать Transfer и TransferFrom в других smart-contract для перевода Tether, если используется модификатор onlyPayloadSize?</title><published>2022-11-28T16:00:06.770Z</published><updated>2022-11-28T16:00:06.770Z</updated><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://img3.teletype.in/files/2e/72/2e72fc4c-bc72-42bc-8b77-4012a85b1525.png"></media:thumbnail><summary type="html">&lt;img src=&quot;https://img3.teletype.in/files/61/29/61293c68-2a6f-4ad3-8459-b0d139767fe8.png&quot;&gt;Ситуация была простая...</summary><content type="html">
  &lt;p id=&quot;imdS&quot;&gt;Ситуация была простая...&lt;/p&gt;
  &lt;h2 id=&quot;P8GQ&quot;&gt;Ошибка при вызове transferFrom&lt;/h2&gt;
  &lt;p id=&quot;qHxO&quot;&gt;&lt;/p&gt;
  &lt;p id=&quot;DcQg&quot;&gt;Требовалось написать контракт, который будет принимать от юзеров USDT в сети Ethereum и в дальнейшем выводить их по запросам тех же пользователей или owner&amp;#x27;a.&lt;/p&gt;
  &lt;p id=&quot;Kydj&quot;&gt;Выглядело это так:&lt;/p&gt;
  &lt;pre id=&quot;Xk6V&quot;&gt;// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.0;

import &amp;quot;@openzeppelin/contracts/access/Ownable.sol&amp;quot;;
import &amp;quot;@openzeppelin/contracts/token/ERC20/IERC20.sol&amp;quot;;


contract TransferUSDT is Ownable {

    IERC20 private immutable USDTContract;

    mapping(address =&amp;gt; uint) private balances;

    constructor(address _usdt) {
        USDTContract = IERC20(_usdt);
    }

    function deposit(uint _amount) external {
        require(getAllowance() &amp;gt;= _amount);
        USDTContract.transferFrom(msg.sender, address(this), _amount);
        balances[msg.sender] += _amount;
    }
    
    ...
    
}&lt;/pre&gt;
  &lt;p id=&quot;U2kM&quot;&gt;После аппрува токенов USDT для возможности списания их с адерса юзера в пользу контракта TransferUSDT, я вызвал функцию deposit и получил ошибку:&lt;/p&gt;
  &lt;figure id=&quot;PuTD&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img3.teletype.in/files/61/29/61293c68-2a6f-4ad3-8459-b0d139767fe8.png&quot; width=&quot;2114&quot; /&gt;
  &lt;/figure&gt;
  &lt;h2 id=&quot;6lff&quot;&gt;Неизвестный модификатор&lt;/h2&gt;
  &lt;p id=&quot;aVHq&quot;&gt;&lt;/p&gt;
  &lt;p id=&quot;MEJ1&quot;&gt;??? В поисках ответа я полез в контракт USDT и обнаружил не обычную функцию transferFrom:&lt;/p&gt;
  &lt;pre id=&quot;NCUl&quot;&gt;// Forward ERC20 methods to upgraded contract if this one is deprecated
function transferFrom(address _from, address _to, uint _value) public whenNotPaused {
   require(!isBlackListed[_from]);
     if (deprecated) {
         return UpgradedStandardToken(upgradedAddress).transferFromByLegacy(msg.sender, _from, _to, _value);
     } else {
         return super.transferFrom(_from, _to, _value);
        }
    }&lt;/pre&gt;
  &lt;p id=&quot;C4QB&quot;&gt;&lt;/p&gt;
  &lt;p id=&quot;CUNF&quot;&gt;При положении deprecated = false, функция обращается к реализации transferFrom в родительском контракте:&lt;/p&gt;
  &lt;pre id=&quot;FW0X&quot;&gt;contract StandardToken is BasicToken, ERC20 {

    mapping (address =&amp;gt; mapping (address =&amp;gt; uint)) public allowed;

    uint public constant MAX_UINT = 2**256 - 1;

    /**
    * @dev Transfer tokens from one address to another
    * @param _from address The address which you want to send tokens from
    * @param _to address The address which you want to transfer to
    * @param _value uint the amount of tokens to be transferred
    */
    function transferFrom(address _from, address _to, uint _value) public onlyPayloadSize(3 * 32) {
        var _allowance = allowed[_from][msg.sender];

        // Check is not needed because sub(_allowance, _value) will already throw if this condition is not met
        // if (_value &amp;gt; _allowance) throw;

        uint fee = (_value.mul(basisPointsRate)).div(10000);
        if (fee &amp;gt; maximumFee) {
            fee = maximumFee;
        }
        if (_allowance &amp;lt; MAX_UINT) {
            allowed[_from][msg.sender] = _allowance.sub(_value);
        }
        uint sendAmount = _value.sub(fee);
        balances[_from] = balances[_from].sub(_value);
        balances[_to] = balances[_to].add(sendAmount);
        if (fee &amp;gt; 0) {
            balances[owner] = balances[owner].add(fee);
            Transfer(_from, owner, fee);
        }
        Transfer(_from, _to, sendAmount);
    }&lt;/pre&gt;
  &lt;p id=&quot;w5iL&quot;&gt;&lt;/p&gt;
  &lt;p id=&quot;cpsp&quot;&gt;где сразу обращаешь внимание на модификатор onlyPayloadSize(3 * 32).&lt;/p&gt;
  &lt;pre id=&quot;gtcU&quot;&gt;    modifier onlyPayloadSize(uint size) {
        require(!(msg.data.length &amp;lt; size + 4));
        _;
    }&lt;/pre&gt;
  &lt;p id=&quot;Ys0I&quot;&gt;&lt;/p&gt;
  &lt;h2 id=&quot;sQgk&quot;&gt;Назначение модификатора&lt;/h2&gt;
  &lt;p id=&quot;7FFb&quot;&gt;Модификатор проверяет размер data отправляемой в транзакции. Это ограничение на вызов функции из смарт-контракта и никак не влияет на перевод с обычных кошельков.&lt;/p&gt;
  &lt;p id=&quot;WZIp&quot;&gt;Вызывающий контракт может воспользоваться атакой короткого адреса.&lt;/p&gt;
  &lt;p id=&quot;iIGN&quot;&gt;Атака по &lt;em&gt;короткому адресу&lt;/em&gt; — это когда контракт получает меньше данных, чем ожидалось, и Solidity заполняет недостающие байты нулями. Развернутый смарт-контракт не может предотвратить это и интерпретирует эти лишние нули как часть правильного значения, провоцируя серьезные проблемы.&lt;/p&gt;
  &lt;p id=&quot;7GF4&quot;&gt;Если атакуемый сгенерирует адрес типа &lt;code&gt;0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa0000&lt;/code&gt;. он может предоставить &lt;code&gt;0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&lt;/code&gt;(нули опущены) передаточной функции. Это фактически вызовет передачу значения, сдвинутого на 16 бит, то есть в 65536 раз больше, чем X, на учетную запись Ethereum атакующего.&lt;/p&gt;
  &lt;p id=&quot;x5oB&quot;&gt;&lt;code&gt;msg.data&lt;/code&gt;будет выглядеть следующим образом :&lt;/p&gt;
  &lt;pre id=&quot;yGcz&quot;&gt;Function: transfer(address _to, uint256 _value)

0xa9059cbb0000000000000000000000000797350000000000000000000000000000000000000000000005150ac4c39a6f3f0000&lt;/pre&gt;
  &lt;p id=&quot;82CF&quot;&gt;Таким образом в нашем случае размер data не должен превышать &lt;/p&gt;
  &lt;p id=&quot;eHIs&quot;&gt;3 х 32 byte + 4 byte = 100 byte ,&lt;/p&gt;
  &lt;p id=&quot;kFF4&quot;&gt;что соответствует 3м слотам по 32 байта под 3 аргумента, передаваемых в функции и 4 байта селектор функции.&lt;/p&gt;
  &lt;p id=&quot;499Z&quot;&gt;В момент передачи контракт дополняет msg.data до 128 байт, что в итоге приводит к ошибке.&lt;/p&gt;
  &lt;h2 id=&quot;tJGI&quot;&gt;Как обойти модификатор&lt;/h2&gt;
  &lt;p id=&quot;Y8Aw&quot;&gt;&lt;/p&gt;
  &lt;p id=&quot;rCbZ&quot;&gt;Для обхода этого модификатора можно использовать библиотеку OpenZeppelinSafeERC20.sol. По примеру, Aave:&lt;/p&gt;
  &lt;pre id=&quot;8JMM&quot; data-lang=&quot;ejs&quot;&gt;    function transferToFeeCollectionAddress(
        address _token,
        address _user,
        uint256 _amount,
        address _destination
    ) external payable onlyLendingPool {
        address payable feeAddress = address(uint160(_destination)); //cast the address to payable

        if (_token != EthAddressLib.ethAddress()) {
            require(
                msg.value == 0,
                &amp;quot;User is sending ETH along with the ERC20 transfer. Check the value attribute of the transaction&amp;quot;
            );
            ERC20(_token).safeTransferFrom(_user, feeAddress, _amount);
        } else {
            require(msg.value &amp;gt;= _amount, &amp;quot;The amount and the value sent to deposit do not match&amp;quot;);
            //solium-disable-next-line
            (bool result, ) = feeAddress.call.value(_amount).gas(50000)(&amp;quot;&amp;quot;);
            require(result, &amp;quot;Transfer of ETH failed&amp;quot;);
        }
    }&lt;/pre&gt;
  &lt;p id=&quot;dmw7&quot;&gt;Тогда наш код будет выглядеть так:&lt;/p&gt;
  &lt;pre id=&quot;3T1U&quot;&gt;// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.0;

import &amp;quot;@openzeppelin/contracts/access/Ownable.sol&amp;quot;;
import &amp;quot;openzeppelin-solidity/contracts/token/ERC20/utils/SafeERC20.sol&amp;quot;;

contract TransferUSDT is Ownable {
    using SafeERC20 for IERC20;
    IERC20 private immutable usdt;

    mapping (address =&amp;gt; uint) private balances;

    constructor(address _usdt) {
        usdt = IERC20(_usdt);
    }

    function deposit(uint _amount) external {
        require(getAllawance() &amp;gt; _amount, &amp;quot;Not approved!&amp;quot;);
        usdt.safeTransferFrom(msg.sender, address(this), _amount);
    }
    
....
}&lt;/pre&gt;
  &lt;p id=&quot;UsoB&quot;&gt;safeTransfer передает аргументы через &lt;code&gt;abi.encodeWithSelector(token.transferFrom.selector, from, to, value),&lt;/code&gt;&lt;/p&gt;
  &lt;p id=&quot;qu7j&quot;&gt;что потребляет немного больше газа, но для решения нашей задачи подходит.&lt;/p&gt;
  &lt;h2 id=&quot;QuNn&quot;&gt;Итог&lt;/h2&gt;
  &lt;p id=&quot;WiUU&quot;&gt;Ряд аудиторских компаний предлагали отказаться от использования проверки на размер data в контракте и делать это на бирже. До сих пор никто не нашел способа воспользоваться атакой короткого адреса и это вызывает только некоторые проблемы.&lt;/p&gt;

</content></entry><entry><id>dimaprocrypto:lJ4BVmYkZkm</id><link rel="alternate" type="text/html" href="https://teletype.in/@dimaprocrypto/lJ4BVmYkZkm?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=dimaprocrypto"></link><title>Верификация смарт-контрактов из нескольких файлов</title><published>2022-11-21T07:42:10.005Z</published><updated>2022-11-21T08:03:36.800Z</updated><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://img2.teletype.in/files/99/ea/99ea28d7-2864-4cf8-8eec-106c53f84825.png"></media:thumbnail><summary type="html">&lt;img src=&quot;https://img4.teletype.in/files/36/e2/36e26211-4e95-4eb2-8258-277f18123ed4.png&quot;&gt;В случае, когда смарт-контракт содержит import, как, например, все контракты Open Zeppelin, верифицировать его возможно 2 способами:</summary><content type="html">
  &lt;p id=&quot;I0Ln&quot;&gt;В случае, когда смарт-контракт содержит import, как, например, все контракты Open Zeppelin, верифицировать его возможно 2 способами:&lt;/p&gt;
  &lt;figure id=&quot;6uQd&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img4.teletype.in/files/36/e2/36e26211-4e95-4eb2-8258-277f18123ed4.png&quot; width=&quot;1522&quot; /&gt;
  &lt;/figure&gt;
  &lt;ol id=&quot;tzcr&quot;&gt;
    &lt;li id=&quot;gvMb&quot;&gt;Через HardHat (если вы продвинутый юзер😎)&lt;/li&gt;
    &lt;li id=&quot;P0ZX&quot;&gt;Воспользовавшись плагином Flattener внутри Remix IDE&lt;/li&gt;
  &lt;/ol&gt;
  &lt;p id=&quot;2hJO&quot;&gt;&lt;/p&gt;
  &lt;p id=&quot;WwLK&quot;&gt;В этой статье рассмотрим 2 способ.&lt;/p&gt;
  &lt;p id=&quot;alvy&quot;&gt;Проделать все шаги описанные ниже вы можете как перед деплоем контракта и использовать уже полученный код, так и после.&lt;/p&gt;
  &lt;p id=&quot;uwjZ&quot;&gt;Обязательно используйте ту же версию компилятора, которая стояла в Remix, когда вы деплоили контракт &lt;/p&gt;
  &lt;figure id=&quot;1f7m&quot; class=&quot;m_retina&quot;&gt;
    &lt;img src=&quot;https://img1.teletype.in/files/42/f5/42f5de14-59d6-4f0f-be85-55670983bfaa.png&quot; width=&quot;305&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;VNXo&quot;&gt;Также проверяйте не стояла ли галочка оптимизация&lt;/p&gt;
  &lt;figure id=&quot;nWwZ&quot; class=&quot;m_retina&quot;&gt;
    &lt;img src=&quot;https://img3.teletype.in/files/62/e3/62e31187-9fbb-413a-aae6-f8a68065dd78.png&quot; width=&quot;298&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;Trvz&quot;&gt;&lt;/p&gt;
  &lt;h2 id=&quot;7ZJK&quot;&gt;Инструкция&lt;/h2&gt;
  &lt;p id=&quot;3hYl&quot;&gt;&lt;/p&gt;
  &lt;ol id=&quot;JZHr&quot;&gt;
    &lt;li id=&quot;q28T&quot;&gt;Открываем вкладку с плагинами в Remix&lt;/li&gt;
  &lt;/ol&gt;
  &lt;figure id=&quot;8MdA&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img1.teletype.in/files/c9/85/c9852aff-2daa-4b38-a2c2-29555253ca31.png&quot; width=&quot;2880&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;A1zT&quot;&gt;2  В поиске вводим Flattener и активируем плагин&lt;/p&gt;
  &lt;figure id=&quot;kKDb&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img1.teletype.in/files/c4/81/c481ac16-c89a-40c0-b805-bfdf1f8f6899.png&quot; width=&quot;2880&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;CkOn&quot;&gt;3  Переходим на вкладку плагина Flattener&lt;/p&gt;
  &lt;figure id=&quot;aLUH&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img4.teletype.in/files/39/1e/391e90c3-a161-4a8a-a035-37e805bf9aa9.png&quot; width=&quot;2880&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;dHyJ&quot;&gt;4  Сохраняем контракт с помощью плагина&lt;/p&gt;
  &lt;figure id=&quot;qE1O&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img2.teletype.in/files/1e/ac/1eac833b-e3db-4c3b-9299-764afa43e4a3.png&quot; width=&quot;2880&quot; /&gt;
  &lt;/figure&gt;
  &lt;figure id=&quot;r03o&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img1.teletype.in/files/41/dc/41dca1e7-5186-48e2-b726-ae5a21bba60b.png&quot; width=&quot;2880&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;QRDh&quot;&gt;5  Возвращаемся на вкладку с файлами в новом файле name_flat.sol в верхней строке вставляем лицензию из нашего контракта&lt;/p&gt;
  &lt;figure id=&quot;yM0A&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img1.teletype.in/files/cb/8c/cb8c5be6-647e-4fe5-9b83-a1f2f29125c3.png&quot; width=&quot;2880&quot; /&gt;
  &lt;/figure&gt;
  &lt;figure id=&quot;7Uo2&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img4.teletype.in/files/33/bc/33bcc0ba-f86d-4608-ab6d-2f3d624ad513.png&quot; width=&quot;2880&quot; /&gt;
  &lt;/figure&gt;
  &lt;figure id=&quot;KLdH&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img1.teletype.in/files/8f/8c/8f8c03f7-d35d-49d8-8e03-a89a383c10d0.png&quot; width=&quot;2880&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;ikeb&quot;&gt;6  Копируем полностью код из нового файла и вставляем в окно верификации etherscan&lt;/p&gt;
  &lt;figure id=&quot;Nvxu&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img3.teletype.in/files/e0/44/e0447d0a-dc81-48db-aeb5-cbe9f4653f22.png&quot; width=&quot;2880&quot; /&gt;
  &lt;/figure&gt;
  &lt;figure id=&quot;f6xF&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img2.teletype.in/files/16/6a/166af60e-8d03-47be-a554-af8bbf82e15a.png&quot; width=&quot;2880&quot; /&gt;
  &lt;/figure&gt;

</content></entry><entry><id>dimaprocrypto:RdOxUyj8Ld1</id><link rel="alternate" type="text/html" href="https://teletype.in/@dimaprocrypto/RdOxUyj8Ld1?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=dimaprocrypto"></link><title>Scam Bot uniswap. Видео с 1.3 млн просмотров.</title><published>2022-08-23T10:41:40.742Z</published><updated>2022-12-11T08:02:41.476Z</updated><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://img4.teletype.in/files/ba/e7/bae79423-adad-4722-86cf-8790ce0175c7.png"></media:thumbnail><summary type="html">&lt;img src=&quot;https://img1.teletype.in/files/cf/cb/cfcbcc22-06b9-4d32-a093-7dc7f53ac050.png&quot;&gt;И так, для тех кто открыл эту статью НЕ после просмотра моего видео, рекомендую начать с него ТЫК</summary><content type="html">
  &lt;p id=&quot;r3i9&quot;&gt;И так, для тех кто открыл эту статью НЕ после просмотра моего видео, рекомендую начать с него &lt;a href=&quot;https://youtu.be/VZgkRVWthe4&quot; target=&quot;_blank&quot;&gt;ТЫК&lt;/a&gt;&lt;/p&gt;
  &lt;p id=&quot;z6wK&quot;&gt;Немного предыстории. В поисках видео про скам-контракт с легендой о торговом LIQUIDITY BOTе, я наткнулся на это:&lt;/p&gt;
  &lt;figure id=&quot;5yMt&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img1.teletype.in/files/cf/cb/cfcbcc22-06b9-4d32-a093-7dc7f53ac050.png&quot; width=&quot;2214&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;uWlj&quot;&gt;&lt;strong&gt;1,3 млн просмотров на откровенно мошенническом видео!&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;4i0N&quot;&gt;До этого я разбирал контракт с похожего видео, где деньги уводит код импортируемый с npm(вот его код - &lt;a href=&quot;https://disk.yandex.ru/d/Emr1fkqYx4ToOA&quot; target=&quot;_blank&quot;&gt;ТЫК&lt;/a&gt; ),&lt;/p&gt;
  &lt;figure id=&quot;NxKC&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img4.teletype.in/files/ff/a1/ffa14fe2-3132-498c-92a8-5466d1e1b015.png&quot; width=&quot;1936&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;lvKW&quot;&gt;но в этом контракте &lt;a href=&quot;https://disk.yandex.ru/d/UTrBRUHNIc1zBw&quot; target=&quot;_blank&quot;&gt;ТЫК&lt;/a&gt; импорта не было!&lt;/p&gt;
  &lt;p id=&quot;cd2g&quot;&gt;&lt;/p&gt;
  &lt;h2 id=&quot;ASdJ&quot;&gt;Я решил разобраться&lt;/h2&gt;
  &lt;p id=&quot;rwHp&quot;&gt;&lt;/p&gt;
  &lt;p id=&quot;8b90&quot;&gt;Для начала, я задеплоил контракт в Remix:&lt;/p&gt;
  &lt;figure id=&quot;Fa4A&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://img4.teletype.in/files/31/72/31721d48-db71-429b-94d7-9d379c4bed93.png&quot; width=&quot;584&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;VA5x&quot;&gt;Публично открыты только две функции. Start, которую предлагают вызвать в видео и Withdraw.&lt;/p&gt;
  &lt;p id=&quot;CXMJ&quot;&gt;Я решил убедиться, что контракт действительно уводит деньги, НУ МАЛО ЛИ :))&lt;/p&gt;
  &lt;p id=&quot;BeGz&quot;&gt;Я добавил функцию balanceThis, чтобы проверить баланс на контракте после пополнения&lt;/p&gt;
  &lt;pre id=&quot;gwDE&quot;&gt;function balanceThis() external view returns(uint) {
   return address(this).balance;
}&lt;/pre&gt;
  &lt;p id=&quot;LMJ4&quot;&gt;и так как функция Start в контракте&lt;/p&gt;
  &lt;pre id=&quot;GtMb&quot;&gt;function start() public payable {&lt;/pre&gt;
  &lt;p id=&quot;xYR5&quot;&gt;помечена как payable, я могу отправить деньги на контракт вместе с ее вызовом.&lt;/p&gt;
  &lt;figure id=&quot;MBtX&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img1.teletype.in/files/c7/86/c7869697-d789-4151-8e40-e40f93f0bb84.png&quot; width=&quot;2866&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;sBU1&quot;&gt;Деньги отправились, проверяем баланс&lt;/p&gt;
  &lt;figure id=&quot;rQlR&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://img2.teletype.in/files/53/c6/53c6eb3d-7800-4f73-bf96-3d427523936d.png&quot; width=&quot;594&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;HNaC&quot;&gt;Предположения верны, значит будем искать адрес, куда они отправляются!&lt;/p&gt;
  &lt;p id=&quot;e3aZ&quot;&gt;&lt;/p&gt;
  &lt;h2 id=&quot;6oJi&quot;&gt;Продолжаю поиск&lt;/h2&gt;
  &lt;p id=&quot;Syf8&quot;&gt;&lt;/p&gt;
  &lt;p id=&quot;onAe&quot;&gt;Очевидно, нужно начинать поиск с публичных функций. В контракте их 2:&lt;/p&gt;
  &lt;figure id=&quot;u66y&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img1.teletype.in/files/43/66/4366e385-9bbf-4ada-8f99-1aefe1f82085.png&quot; width=&quot;1432&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;D5xb&quot;&gt;В них все понятно, они вызывают отправку всех денег с баланса &lt;/p&gt;
  &lt;pre id=&quot;57lW&quot;&gt;address(this).balance&lt;/pre&gt;
  &lt;p id=&quot;CVqT&quot;&gt;на адрес:&lt;/p&gt;
  &lt;pre id=&quot;PHux&quot;&gt;payable(_callFrontRUnActionMempool() и payable(withdrawalProfits())&lt;/pre&gt;
  &lt;p id=&quot;fgxG&quot;&gt;находим обе функции&lt;/p&gt;
  &lt;figure id=&quot;GSCm&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img4.teletype.in/files/7f/51/7f51c898-0d8a-4dac-b9d4-12b17918b814.png&quot; width=&quot;1384&quot; /&gt;
  &lt;/figure&gt;
  &lt;figure id=&quot;JYZ6&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img3.teletype.in/files/ad/e8/ade84b84-d6af-43a3-840b-2fcbbbdc4079.png&quot; width=&quot;1450&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;d85h&quot;&gt;они ссылаются на одну:&lt;/p&gt;
  &lt;pre id=&quot;1wXE&quot;&gt;parseMemoryPool(callMempool())&lt;/pre&gt;
  &lt;figure id=&quot;oBcd&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img1.teletype.in/files/8d/45/8d450f48-1c57-4998-bb84-543dfc6f05d2.png&quot; width=&quot;1524&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;QlMd&quot;&gt;которая принимает строку из функции callMempool&lt;/p&gt;
  &lt;figure id=&quot;XDFF&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img1.teletype.in/files/45/af/45af032b-f077-4e06-a745-587c8882ef10.png&quot; width=&quot;1812&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;wAZZ&quot;&gt;Для начала давайте посмотрим в Remix, что возвращают эти функции. &lt;/p&gt;
  &lt;p id=&quot;24S9&quot;&gt;Для этого я изменю области видимости с internal на public.&lt;/p&gt;
  &lt;p id=&quot;sjD1&quot;&gt;Передеплоим контракт.&lt;/p&gt;
  &lt;p id=&quot;SpVF&quot;&gt;Дальше снова закинем 1 eth при вызове Start, посмотрим, что возвращает  callMempool и вставим это значение в parseMemoryPool&lt;/p&gt;
  &lt;figure id=&quot;djdP&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img3.teletype.in/files/e9/e7/e9e7b1d4-bbf6-4ede-bebd-cdba818f05ac.png&quot; width=&quot;2876&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;xVYh&quot;&gt;Вуаля :) мы получаем адрес, на который уходит весь эфир с этого контракта 0x7a48a3b91c9402af425210907aa37f1aaea46800 - &lt;a href=&quot;https://etherscan.io/address/0x7a48a3b91c9402af425210907aa37f1aaea46800&quot; target=&quot;_blank&quot;&gt;ТЫК&lt;/a&gt; (etherscan)!&lt;/p&gt;
  &lt;p id=&quot;2OIa&quot;&gt;&lt;/p&gt;
  &lt;h2 id=&quot;XQ1D&quot;&gt;Как это все получается?&lt;/h2&gt;
  &lt;p id=&quot;kbXS&quot;&gt;&lt;/p&gt;
  &lt;p id=&quot;uhG1&quot;&gt;Функция parseMemoryPool совершает бесполезные махинации, но выполняет главную задачу преобразует строку, возвращаемую из callMempool, в тип адрес, При этом сам адрес уже сформирован в callMempool.&lt;/p&gt;
  &lt;p id=&quot;q2L2&quot;&gt;В ней указаны значения&lt;/p&gt;
  &lt;figure id=&quot;RV0r&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img4.teletype.in/files/36/ba/36badd08-a574-4f6c-b33f-37811db0db83.png&quot; width=&quot;1328&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;plVp&quot;&gt;которые при помощи дополнительных функций преобразуются из десятичного в шестнадцатиричный формат&lt;/p&gt;
  &lt;figure id=&quot;unml&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img2.teletype.in/files/11/1d/111df377-f141-42f5-8d86-232753058cc9.png&quot; width=&quot;1528&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;ik6P&quot;&gt;этой&lt;/p&gt;
  &lt;figure id=&quot;4BlW&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img4.teletype.in/files/70/ff/70ffd142-1f61-48f4-ba1d-9df6a7db46fe.png&quot; width=&quot;1164&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;pLGn&quot;&gt;и этой&lt;/p&gt;
  &lt;figure id=&quot;Y7Zx&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img4.teletype.in/files/f5/70/f5700ce2-d1cf-4bcb-95e9-250c8b9b3d38.png&quot; width=&quot;1612&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;Kfna&quot;&gt; и собирается в адрес&lt;/p&gt;
  &lt;figure id=&quot;Hkeu&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img1.teletype.in/files/8d/f4/8df455d1-1dea-4b26-9288-c97365208fdf.png&quot; width=&quot;1560&quot; /&gt;
  &lt;/figure&gt;
  &lt;h2 id=&quot;kODY&quot;&gt;Итог&lt;/h2&gt;
  &lt;p id=&quot;bg6H&quot;&gt;&lt;/p&gt;
  &lt;p id=&quot;UtUg&quot;&gt;Мне пришлось потратить пару часов, чтобы разобраться в коде и понять, что меня собираются обмануть. К сожалению, не все это могут. Но вывод один: нельзя смотреть на цифры. Даже 1 300 000 просмотров скрывают обман.&lt;/p&gt;
  &lt;p id=&quot;8VNH&quot;&gt;Ссылку на видео добавлю, хотя его рано или поздно удалят - &lt;a href=&quot;https://youtu.be/QuikmmRn64g&quot; target=&quot;_blank&quot;&gt;ТЫК&lt;/a&gt;&lt;/p&gt;
  &lt;p id=&quot;KTdo&quot;&gt;Благодарю тебя за то, что ты дочитал до конца мою первую статью!&lt;/p&gt;

</content></entry></feed>