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

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

  await tokenDrop.deployed();

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

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

]]></content:encoded></item><item><guid isPermaLink="true">https://teletype.in/@dimaprocrypto/usdtTransferFrom</guid><link>https://teletype.in/@dimaprocrypto/usdtTransferFrom?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=dimaprocrypto</link><comments>https://teletype.in/@dimaprocrypto/usdtTransferFrom?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=dimaprocrypto#comments</comments><dc:creator>dimaprocrypto</dc:creator><title>Как использовать Transfer и TransferFrom в других smart-contract для перевода Tether, если используется модификатор onlyPayloadSize?</title><pubDate>Mon, 28 Nov 2022 16:00:06 GMT</pubDate><media:content medium="image" url="https://img3.teletype.in/files/2e/72/2e72fc4c-bc72-42bc-8b77-4012a85b1525.png"></media:content><description><![CDATA[<img src="https://img3.teletype.in/files/61/29/61293c68-2a6f-4ad3-8459-b0d139767fe8.png"></img>Ситуация была простая...]]></description><content:encoded><![CDATA[
  <p id="imdS">Ситуация была простая...</p>
  <h2 id="P8GQ">Ошибка при вызове transferFrom</h2>
  <p id="qHxO"></p>
  <p id="DcQg">Требовалось написать контракт, который будет принимать от юзеров USDT в сети Ethereum и в дальнейшем выводить их по запросам тех же пользователей или owner&#x27;a.</p>
  <p id="Kydj">Выглядело это так:</p>
  <pre id="Xk6V">// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.0;

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


contract TransferUSDT is Ownable {

    IERC20 private immutable USDTContract;

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

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

    function deposit(uint _amount) external {
        require(getAllowance() &gt;= _amount);
        USDTContract.transferFrom(msg.sender, address(this), _amount);
        balances[msg.sender] += _amount;
    }
    
    ...
    
}</pre>
  <p id="U2kM">После аппрува токенов USDT для возможности списания их с адерса юзера в пользу контракта TransferUSDT, я вызвал функцию deposit и получил ошибку:</p>
  <figure id="PuTD" class="m_column">
    <img src="https://img3.teletype.in/files/61/29/61293c68-2a6f-4ad3-8459-b0d139767fe8.png" width="2114" />
  </figure>
  <h2 id="6lff">Неизвестный модификатор</h2>
  <p id="aVHq"></p>
  <p id="MEJ1">??? В поисках ответа я полез в контракт USDT и обнаружил не обычную функцию transferFrom:</p>
  <pre id="NCUl">// 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);
        }
    }</pre>
  <p id="C4QB"></p>
  <p id="CUNF">При положении deprecated = false, функция обращается к реализации transferFrom в родительском контракте:</p>
  <pre id="FW0X">contract StandardToken is BasicToken, ERC20 {

    mapping (address =&gt; mapping (address =&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 &gt; _allowance) throw;

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

0xa9059cbb0000000000000000000000000797350000000000000000000000000000000000000000000005150ac4c39a6f3f0000</pre>
  <p id="82CF">Таким образом в нашем случае размер data не должен превышать </p>
  <p id="eHIs">3 х 32 byte + 4 byte = 100 byte ,</p>
  <p id="kFF4">что соответствует 3м слотам по 32 байта под 3 аргумента, передаваемых в функции и 4 байта селектор функции.</p>
  <p id="499Z">В момент передачи контракт дополняет msg.data до 128 байт, что в итоге приводит к ошибке.</p>
  <h2 id="tJGI">Как обойти модификатор</h2>
  <p id="Y8Aw"></p>
  <p id="rCbZ">Для обхода этого модификатора можно использовать библиотеку OpenZeppelinSafeERC20.sol. По примеру, Aave:</p>
  <pre id="8JMM" data-lang="ejs">    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,
                &quot;User is sending ETH along with the ERC20 transfer. Check the value attribute of the transaction&quot;
            );
            ERC20(_token).safeTransferFrom(_user, feeAddress, _amount);
        } else {
            require(msg.value &gt;= _amount, &quot;The amount and the value sent to deposit do not match&quot;);
            //solium-disable-next-line
            (bool result, ) = feeAddress.call.value(_amount).gas(50000)(&quot;&quot;);
            require(result, &quot;Transfer of ETH failed&quot;);
        }
    }</pre>
  <p id="dmw7">Тогда наш код будет выглядеть так:</p>
  <pre id="3T1U">// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.0;

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

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

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

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

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

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

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

]]></content:encoded></item></channel></rss>