<?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>Parkinson</title><generator>teletype.in</generator><description><![CDATA[Parkinson]]></description><image><url>https://img4.teletype.in/files/7b/44/7b44d62a-e06a-4968-9981-e157f3ea2c6f.png</url><title>Parkinson</title><link>https://teletype.in/@oregoleh</link></image><link>https://teletype.in/@oregoleh?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=oregoleh</link><atom:link rel="self" type="application/rss+xml" href="https://teletype.in/rss/oregoleh?offset=0"></atom:link><atom:link rel="next" type="application/rss+xml" href="https://teletype.in/rss/oregoleh?offset=10"></atom:link><atom:link rel="search" type="application/opensearchdescription+xml" title="Teletype" href="https://teletype.in/opensearch.xml"></atom:link><pubDate>Mon, 06 Apr 2026 20:07:08 GMT</pubDate><lastBuildDate>Mon, 06 Apr 2026 20:07:08 GMT</lastBuildDate><item><guid isPermaLink="true">https://teletype.in/@oregoleh/Diamond</guid><link>https://teletype.in/@oregoleh/Diamond?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=oregoleh</link><comments>https://teletype.in/@oregoleh/Diamond?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=oregoleh#comments</comments><dc:creator>oregoleh</dc:creator><title>Как внедрить стандарт Diamond</title><pubDate>Tue, 21 Feb 2023 14:51:04 GMT</pubDate><media:content medium="image" url="https://img3.teletype.in/files/20/ea/20ea0199-f037-43a4-8ebd-73ef00dbab30.png"></media:content><description><![CDATA[<img src="https://img3.teletype.in/files/2b/4c/2b4c82b8-2330-42b9-934a-d9c45ccff2bc.png"></img>Diamond Standard, EIP-2535, был создан Ником Маджем как стандартизированная архитектура для реализации смарт-контрактов через прокси. В этой статье мы рассмотрим плюсы использования Diamond Standard и принципы его работы. Вы узнаете как создать и развернуть приложение блокчейна с помощью Diamond Standard!

-Общий обзор
-Зачем использовать
-Хранилище приложений и алмазное хранилище
-Diamond.sol
-DiamondCut.sol
-LoupeFacet.sol
-Как развернуть Diamond Standard
-Заключение]]></description><content:encoded><![CDATA[
  <figure id="ptWp" class="m_original">
    <img src="https://img3.teletype.in/files/2b/4c/2b4c82b8-2330-42b9-934a-d9c45ccff2bc.png" width="923" />
  </figure>
  <p id="Efyz">Diamond Standard, EIP-2535, был создан Ником Маджем как стандартизированная архитектура для реализации смарт-контрактов через прокси. В этой статье мы рассмотрим плюсы использования Diamond Standard и принципы его работы. Вы узнаете как создать и развернуть приложение блокчейна с помощью Diamond Standard!<br /><br /><em>-Общий обзор<br />-Зачем использовать<br />-Хранилище приложений и алмазное хранилище<br />-Diamond.sol<br />-DiamondCut.sol<br />-LoupeFacet.sol<br />-Как развернуть Diamond Standard<br />-Заключение</em></p>
  <h1 id="3a50">Общий обзор</h1>
  <p id="a0ee">Алмазный стандарт работает путем развертывания контракта под названием <code>Diamond.sol</code>. <code>Diamond.sol</code>, затем вызывает другие смарт-контракты через <code>delegatecall()</code>. Это позволяет <code>Diamond.sol</code>выполнять код вызываемого контракта в контексте <code>Diamond.sol</code>. Все контракты, которые вызываются с помощью, <code>delegatecall()</code>называются фасетами. Фасеты можно заменять, удалять и добавлять с течением времени, что позволяет разработчикам создавать модульные приложения на блокчейнах, совместимых с EVM. Алмазный стандарт требует от вас реализации <code>DiamondLoupeFacet.sol</code>. <code>DiamondLoupeFacet.sol</code>отвечает за документирование других аспектов вашего протокола. <code>DiamondLoupeFacet.sol</code>обеспечивает прозрачность, позволяя пользователям видеть адреса и функции фасетов. Еще одно требование Алмазного стандарта <code>DiamondCutFacet.sol</code>. <code>DiamondCutFacet.sol</code>отвечает за все обновления вашего приложения.<code>DiamondCutFacet.sol</code>также генерирует события при вызове, обеспечивая другой уровень прозрачности для пользователей протокола. Хотя это и не является обязательным требованием, <code>LibDiamond.sol</code>это библиотека, которая предоставляет множество вспомогательных функций для написания приложения с помощью стандарта Diamond. При создании приложения с помощью Diamond Standard вы можете использовать один из двух способов сохранения переменных состояния. Их называют <code>App Storage</code>и <code>Diamond Storage</code>. Мы рассмотрим все компоненты Diamond Standard более подробно в оставшейся части статьи.</p>
  <p id="c405">Алмазный стандарт имеет три различных варианта реализации. К счастью, если вы решите, что выбрали неправильную реализацию, можно обновить приложение до другой реализации. <code>diamond-1</code>является самой базовой реализацией. Сложность <code>diamond-1</code>проще всего понять, а затраты на газ самые низкие. Не рекомендуется вызывать <code>DiamondLoupeFacet.sol</code>функции по цепочке с <code>diamond-1</code>(или <code>diamond-2</code>) из-за высоких затрат на газ. <code>diamond-3</code>, с другой стороны, выбирает оптимизацию <code>DiamondLoupeFacet.sol</code>функций вызова в цепочке. Компромисс заключается в том, что звонки обходятся дороже <code>DiamondCutFacet.sol</code>. <code>diamond-2</code>очень похоже на<code>diamond-1</code>, но оптимизирует затраты на газ по сравнению со сложностью для понимания. Вам, как разработчику, решать, какая из этих реализаций лучше всего подходит для вашего приложения.</p>
  <p id="4f83">Из-за сложности Diamond Standard рекомендуется следовать общему шаблону при создании приложений. Я свяжу эти шаблоны внизу статьи вместе с дополнительными материалами для чтения.</p>
  <h1 id="9ec4">Зачем использовать Алмазный стандарт?</h1>
  <p id="96bb"><u>Основная критика стандарта Diamond — его сложность (надеюсь, я смогу помочь решить эту проблему). Несмотря на сложность, Diamond Standard обеспечивает следующие преимущества:</u></p>
  <ul id="BJQE">
    <li id="7b53"><u>Практических ограничений на размер вашего приложения нет. Все смарт-контракты имеют максимальный размер 24 КБ. Поскольку Diamond Standard использует <code>Diamond.sol</code>свои <code>delegatecall()</code>грани, размер контракта остается относительно небольшим.</u></li>
    <li id="b591"><u>Вы используете только один адрес для множества функций. Опять же, благодаря <code>delegatecall()</code>, вы можете добавить все необходимые функции в один смарт-контракт. Это включает в себя реализацию токенов с тем же адресом, что и ваш протокол.</u></li>
    <li id="7557"><u>Он обеспечивает организованный способ обновления ваших смарт-контрактов. Это может помочь аудиторам понять и защитить ваше приложение.</u></li>
    <li id="0cbe"><u>Это позволяет вам постепенно обновлять свои смарт-контракты. Вместо повторного развертывания всего контракта вы можете просто добавить, заменить или удалить фасет, чтобы обеспечить желаемую функциональность вашего приложения.</u></li>
    <li id="0a0c"><u>Это обеспечивает высокий уровень прозрачности для вашего прокси-контракта. Как упоминалось ранее, <code>DiamondLoupeFacet.sol</code>позволяет пользователям видеть, где находятся ваши функции в блокчейне и что они выполняют. Посетите <a href="https://louper.dev/" target="_blank">https://louper.dev/</a> , чтобы проанализировать функциональность смарт-контрактов, использующих преимущества Diamond Standard.</u></li>
    <li id="6130"><u>Практически нет ограничений на количество аспектов, которые можно использовать в вашем приложении. Единственный способ, которым вы не сможете добавить больше фасетов в свой протокол, — это нехватка <code>Diamond.sol</code>места для хранения данных фасетов. Для этого потребуется смехотворно большое количество граней, вплоть до того, что это практически невозможно.</u></li>
    <li id="4939"><u>Фасеты могут быть повторно использованы несколькими <code>Diamond.sol</code>контрактами. Это позволяет экономить на газе при развертывании приложений, которые заимствуют функциональные возможности.</u></li>
    <li id="9893"><u>При желании вы можете запустить оптимизатор с более высокими настройками. Оптимизатор Solidity помогает оптимизировать затраты газа при вызове внешних функций. Однако это увеличивает байт-код развертывания контракта. Это может привести к тому, что ваш смарт-контракт превысит максимальный размер смарт-контракта. Поскольку вы можете развертывать столько аспектов, сколько хотите, вы можете настроить оптимизатор на столько запусков, сколько пожелаете, не беспокоясь о том, что ваш контракт слишком велик.</u></li>
  </ul>
  <p id="nMiX"><u>Есть много причин, по которым вы хотели бы использовать Diamond Standard в своем приложении, но не забывайте слишком усложнять свое приложение. Если ваш протокол может работать с одним смарт-контрактом и ни одно из вышеперечисленных преимуществ не применимо к вашему приложению, нет необходимости использовать Diamond Standard. В конечном итоге это только усложнит ваше приложение и увеличит расходы на газ. Однако, если вы находитесь в ситуации, когда вам нужен шаблон прокси для вашего приложения, я лично рекомендую использовать Diamond Standard.</u></p>
  <h1 id="2496">Хранилище приложений и алмазное хранилище</h1>
  <p id="3389"><u>Архитектура переменных состояния — один из наиболее важных аспектов вашего блокчейн-приложения. Я решил сначала рассмотреть этот раздел, чтобы дать вам хорошее представление о том, как переменные состояния управляются с помощью Diamond Standard. Очевидно, что прокси в значительной степени полагаются на <code>delegatecall()</code>выполнение кода из ваших фасетных контрактов в контексте вашего основного контракта ( <code>Diamond.sol</code>). Поскольку все хранилище наших переменных состояния хранится в <code>Diamond.sol</code>, нам нужно убедиться, что наши переменные не перезаписывают друг друга. Прежде чем мы рассмотрим правильный способ организации наших переменных состояния, давайте рассмотрим пример неправильного способа управления переменными состояния.</u><br /><br /></p>
  <section style="background-color:hsl(hsl(34,  84%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="htiO">pragma solidity^0.8.17;0.8.17;</p>
    <p id="zC00">contract Main {<br /> uint256 public verySpecialVar;<br /> uint256 public notSoSpecialVar;<br /> // delegate calls SpecialVarManager to update verySpecialVar<br /> function setVerySpecialVar(address _specialVarManager) external {<br /> _specialVarManager.delegatecall(<br /> abi.encodeWithSignature(&quot;writeSpecialVar()&quot;)<br /> );<br /> }<br /> // delegate calls NotSpecialVarManager to update notSoSpecialVar<br /> function setNotSoSpecialVar(address _notSpecialVarManager) external {<br /> _notSpecialVarManager.delegatecall(<br /> abi.encodeWithSignature(&quot;writeNotSpecialVar()&quot;)<br /> );<br /> }</p>
    <p id="zA4m">}<br />contract SpecialVarManager {<br /> uint256 verySpecialVar;<br /> function writeSpecialVar() external {<br /> verySpecialVar = 100;<br /> }<br />}<br />contract NotSpecialVarManager {<br /> uint256 notSoSpecialVar;<br /> function writeNotSpecialVar() external {<br /> notSoSpecialVar = 50;<br /> }<br />}</p>
  </section>
  <p id="9f2d"><u>Если вы вызовите, </u><code>setVerySpecialVar()</code><u>вы увидите, </u><code>verySpecialVar</code><u>что был обновлен до 100! Теперь давайте позвоним <code>setNotSoSpecialVar</code>и посмотрим, что произойдет. Мы видим, <code>notSoSpecialVar</code>что он все еще не инициализирован и равен 0. Если мы проверим, то <code>verySpecialVar</code>увидим, что сейчас он установлен на 50. Почему? Ну, в схеме хранения <code>NotSpecialVarManager</code>нет <code>verySpecialVar</code>. Поэтому, когда мы вызываем <code>writeNotSpecialVar()</code>via, <code>delegatecall()</code>мы сообщаем <code>Main</code>об обновлении слота хранения с 0 до 50. Solidity не заботится о том, как вы называете свои переменные; он смотрит только на положение слота для хранения.</u></p>
  <p id="90bd"><u>Имея это в виду, нам нужен способ организовать наши переменные состояния, чтобы мы не перезаписывали наши слоты хранения. Первый способ сделать это — с помощью Diamond Storage.</u></p>
  <p id="b8d1"><u>Diamond Storage использует количество слотов для хранения Solidity в смарт-контракте (2²⁵⁶). Теория, лежащая в основе Diamond Storage, заключается в том, что, поскольку слотов для хранения так много, что если мы хэшируем уникальное значение, мы получим случайный слот для хранения, который почти наверняка не будет конфликтовать с другим слотом для хранения. Это может показаться рискованным, но на самом деле это тот же процесс, который Solidity использует для хранения отображений и динамических массивов. Diamond Storage дает возможность вашим фасетам сохранять переменные состояния, специфичные для их контракта, а также позволяет фасетам совместно использовать переменные состояния, если это необходимо.</u></p>
  <p id="fec1"><u>Поскольку сложность Diamond Standard требует небольшой настройки, для этих примеров хранения я не буду использовать Diamond Standard. Основная цель этого раздела — понять принципы хранения переменных состояния. Реализация в Diamond Standard в основном такая же.</u></p>
  <pre id="rYMg"></pre>
  <p id="Zt1P">pragma solidity^0.8.17;0.8.17;</p>
  <p id="z5SU">library SharedLib {<br /> // struct that with state variable<br /> struct DiamondStorage {<br /> uint256 sharedVar;<br /> }<br /> // returns a storage variable with our state variable<br /> function diamondStorage() internal pure returns(DiamondStorage storage ds) {<br /> // gets a &quot;random&quot; storage positon by hashing a string<br /> bytes32 storagePosition = keccak256(abi.encode(&quot;Diamond.Storage.SharedLib&quot;));<br /> // assigns our struct storage slot to storage position<br /> assembly {<br /> ds.slot := storagePosition<br /> }</p>
  <p id="eCW0"> }<br />}<br />// not the actual Diamond Standard<br />contract PseudoDiamond {<br /> // delegate calls Facet1 to update sharedVar<br /> function writeToSharedVar(address _facet1, uint256 _value) external {<br /> // writes via delegate call<br /> _facet1.delegatecall(<br /> abi.encodeWithSignature(&quot;writeShared(uint256)&quot;, _value)<br /> );<br /> }<br /> // delegate calls Facet2 to read sharedVar<br /> function readSharedVar(address _facet2) external returns (uint256) {<br /> // returns result of delegate call<br /> (bool success, bytes memory _valueBytes) = _facet2.delegatecall(<br /> abi.encodeWithSignature(&quot;readShared()&quot;)<br /> );<br /> // since return value is bytes array we use assembly to retrieve our uint<br /> bytes32 _value;<br /> assembly {<br /> let location := _valueBytes<br /> _value := mload( add(location, 0x20) )<br /> }<br /> return uint256(_value);<br /> }<br />}<br />contract Facet1 {<br /> function writeShared(uint256 _value) external {<br /> // initializes the storage struct by calling library function<br /> SharedLib.DiamondStorage storage ds = SharedLib.diamondStorage();<br /> // writes to shared variable<br /> ds.sharedVar = _value;</p>
  <p id="E9Zz"> }<br />}<br />contract Facet2 {</p>
  <p id="4Q6w"> function readShared() external view returns (uint256) {<br /> // initializes the storage struct by calling library function<br /> SharedLib.DiamondStorage storage ds = SharedLib.diamondStorage();</p>
  <p id="MI1r"> // returns shared variable<br /> return ds.sharedVar;</p>
  <p id="qFnS"> }<br />}</p>
  <p id="182e"><u>Если вы позвоните <code>PseudoDiamond.writeSharedVar()</code>, то <code>PseudoDiamond.readSharedVar()</code>увидите свое значение. Используя библиотеку и индексируя «случайный» слот для хранения, мы можем обмениваться переменными между двумя смарт-контрактами. Когда мы используем <code>delegatecall()</code>оба аспекта, он смотрит на позицию хранения структуры <code>DiamondStorage</code>для доступа к этой переменной. Благодаря явной связи между аспектами того, где мы хотим хранить наши данные, мы предотвращаем коллизии переменных состояния. Если вы хотите иметь переменные состояния только для одного из ваших аспектов, вы можете просто создать библиотеку, аналогичную <code>SharedLib</code>, и реализовать ее только в этом конкретном аспекте.</u></p>
  <p id="96ed"><u>Хранилище приложений работает немного по-другому. Вы создаете файл Solidity, а внутри этого файла создаете структуру с именем <code>AppStorage</code>. Затем вы помещаете в эту структуру столько переменных состояния, сколько хотите, включая другие структуры. Затем первое, что вы делаете внутри своих смарт-контрактов, — это инициализируете их <code>AppStorage</code>. Это устанавливает слот хранения 0 в начало структуры. Это создает удобочитаемое общее состояние между контрактами. Давайте посмотрим на пример!</u></p>
  <p id="tbhj"><strong>pragma solidity^0.8.17;0.8.17;</strong></p>
  <p id="wVfV"><strong>// struct with state variable<br />struct StateVars {<br /> uint256 sharedVar;<br />}<br />// our app storage struct<br />struct AppStorage {<br /> StateVars state;<br />}<br />// not the actual Diamond Standard<br />contract PseudoDiamond {<br /> AppStorage s;<br /> // delegate calls Facet1 to update sharedVar<br /> function writeToSharedVar(address _facet1, uint256 _value) external {<br /> // writes via delegate call<br /> _facet1.delegatecall(<br /> abi.encodeWithSignature(&quot;writeShared(uint256)&quot;, _value)<br /> );<br /> }<br /> // delegate calls Facet2 to read sharedVar<br /> function readSharedVar(address _facet2) external returns (uint256) {<br /> // returns result of delegate call<br /> (bool success, bytes memory _valueBytes) = _facet2.delegatecall(<br /> abi.encodeWithSignature(&quot;readShared()&quot;)<br /> );<br /> // since return value is bytes array we use assembly to retrieve our uint<br /> bytes32 _value;<br /> assembly {<br /> let location := _valueBytes<br /> _value := mload( add(location, 0x20) )<br /> }<br /> return uint256(_value);<br /> }<br />}<br />contract Facet1 {<br /> AppStorage s;<br /> function writeShared(uint256 _value) external {<br /> // writes to our state variable in storage<br /> s.state.sharedVar = _value;<br /> }<br />}<br />contract Facet2 {<br /> AppStorage s;</strong></p>
  <p id="Pg9I"><strong> function readShared() external view returns (uint256) {<br /> // returns state variable from app storage<br /> return s.state.sharedVar;<br /> }<br />}</strong></p>
  <p id="51cd"><u>Если вы посмотрите на значение в слоте хранения 0 для <code>PseudoDiamond</code>, вы увидите 100, что является нашим значением! Важное замечание о App Storage: если вам нужно обновить AppStorage после развертывания, обязательно добавьте новые переменные состояния в конец AppStorage, чтобы предотвратить коллизии хранилища. Лично я предпочитаю App Storage для организации Diamond Storage, но оба они выполняют свою работу. Также стоит отметить, что Diamond Storage и App Storage не являются эксклюзивными. Даже если вы используете App Storage для управления переменными состояния <code>LibDiamond.sol</code>, используйте Diamond Storage для управления данными аспектов.</u></p>
  <h1 id="a1e5">Diamond.sol</h1>
  <p id="f9ab"><u>Как упоминалось ранее, <code>Diamond.sol</code>это смарт-контракт, который вызывается при взаимодействии с вашим приложением. Если это помогает думать об этом таким образом, <code>Diamond.sol</code>«управляет» остальной частью вашего приложения. Все фасетные функции будут казаться <code>Diamond.sol</code>собственными функциями .</u></p>
  <p id="d9dd"><u>Давайте сначала посмотрим, что происходит в конструкторе <code>diamond-1</code>.</u><br /><br /></p>
  <p id="jcpD"><strong>contract Diamond { </strong></p>
  <p id="P26G"><strong> constructor(address _contractOwner, address _diamondCutFacet) payable { constructor(address _contractOwner, address _diamondCutFacet) payable { <br /> LibDiamond.setContractOwner(_contractOwner);<br /> // Add the diamondCut external function from the diamondCutFacet<br /> IDiamondCut.FacetCut[] memory cut = new IDiamondCut.FacetCut[](1);<br /> bytes4[] memory functionSelectors = new bytes4[](1);<br /> functionSelectors[0] = IDiamondCut.diamondCut.selector;<br /> cut[0] = IDiamondCut.FacetCut({<br /> facetAddress: _diamondCutFacet,<br /> action: IDiamondCut.FacetCutAction.Add,<br /> functionSelectors: functionSelectors<br /> });<br /> LibDiamond.diamondCut(cut, address(0), &quot;&quot;); <br /> }<br /> // rest of code<br />}</strong></p>
  <p id="jjEV"><u>Во-первых, вне контракта у нас есть структура, которая форматирует наши данные. Затем мы передаем эту структуру в качестве параметра вместе с другой структурой, которая выглядит так:</u></p>
  <p id="oxr6"><strong>struct FacetCut {<br /> address facetAddress;address facetAddress;<br /> FacetCutAction action;<br /> bytes4[] functionSelectors;<br />}<br /></strong><u><code>FacetCut</code>предоставляет адрес фасета, действие, которое мы хотим выполнить с фасетом (добавить, заменить или удалить), и селекторы функций для функций фасета. Затем мы устанавливаем владельца контракта и добавляем любые данные фасета, предоставленные Diamond. Позже мы более подробно рассмотрим, как это работает. После этого, если мы захотим, мы можем инициализировать переменные состояния. Имейте в виду, что вы никогда не должны выполнять какие-либо назначения переменных состояния в конструкторе фасета, потому что он будет выполнять эту операцию внутри смарт-контракта фасета, а не <code>Diamond.sol</code>.<br /></u></p>
  <p id="fomf">Пока все выглядит довольно просто, поэтому давайте посмотрим, что происходит в конструкторе для <code>diamond-2</code>и <code>diamond-3</code>.</p>
  <p id="MzFc"><strong>contract Diamond { </strong></p>
  <p id="WiXh"><strong> constructor(address _contractOwner, address _diamondCutFacet) payable { constructor(address _contractOwner, address _diamondCutFacet) payable { <br /> LibDiamond.setContractOwner(_contractOwner);<br /> // Add the diamondCut external function from the diamondCutFacet<br /> IDiamondCut.FacetCut[] memory cut = new IDiamondCut.FacetCut[](1);<br /> bytes4[] memory functionSelectors = new bytes4[](1);<br /> functionSelectors[0] = IDiamondCut.diamondCut.selector;<br /> cut[0] = IDiamondCut.FacetCut({<br /> facetAddress: _diamondCutFacet,<br /> action: IDiamondCut.FacetCutAction.Add,<br /> functionSelectors: functionSelectors<br /> });<br /> LibDiamond.diamondCut(cut, address(0), &quot;&quot;); <br /> }<br /> // rest of code<br />}<br /><br /></strong>На этот раз мы передаем только владельца контракта и адрес <code>DiamondCutFacet.sol</code>. Далее мы назначаем владельца Алмаза. После этого мы добавляем <code>diamondCut()</code>функцию, чтобы мы могли добавить больше аспектов. Мы делаем это, сначала инициализируя массив памяти одним элементом типа struct <code>FacetCut</code>, который мы видели ранее. Затем мы инициализируем другой массив одним элементом. На этот раз это массив <code>bytes4</code>, и он используется для хранения <code>diamondCut()</code>селектора функций . Затем мы назначаем селектор функции массиву, вызывая функцию интерфейса Diamond Cut <code>diamondCut</code>и получая ее селектор. После этого мы можем назначить <code>cut[0]</code>. Мы используем адрес <code>DiamondCutFacet.sol</code>, add (потому что мы хотим добавить эту грань к нашему Алмазу) и массив селекторов функций. Наконец, мы фактически добавляем<code>diamondCut</code>. Это много незнания того, что происходит под капотом, поэтому, если это поможет, вы можете перечитать этот раздел после того, как мы пройдемся по <code>DiamondCut.sol</code>. Пока просто поймите, что мы добавляем фасеты в конструкторе.</p>
  <p id="c8a5">Последняя часть — <code>Diamond.sol</code>это <code>fallback()</code>функция. Вот как мы будем называть наши грани в Diamond Standard. Он выглядит почти одинаково во всех трех реализациях Diamond Standard, так что давайте рассмотрим его!</p>
  <p id="Fvaz"><strong>// Find facet for function that is called and execute the<br />// function if a facet is found and return any value.<br />fallback() external payable {<br /> LibDiamond.DiamondStorage storage ds;<br /> bytes32 position = LibDiamond.DIAMOND_STORAGE_POSITION;<br /> // get diamond storage<br /> assembly {<br /> ds.slot := position<br /> }<br /> // get facet from function selector<br /> address facet = address(bytes20(ds.facets[msg.sig]));<br /> require(facet != address(0), &quot;Diamond: Function does not exist&quot;);<br /> // Execute external function from facet using delegatecall and return any value.<br /> assembly {<br /> // copy function selector and any arguments<br /> calldatacopy(0, 0, calldatasize())<br /> // execute function call using the facet<br /> let result := delegatecall(gas(), facet, 0, calldatasize(), 0, 0)<br /> // get any return value<br /> returndatacopy(0, 0, returndatasize())<br /> // return any return value or error back to the caller<br /> switch result<br /> case 0 {<br /> revert(0, returndatasize())<br /> }<br /> default {<br /> return(0, returndatasize())<br /> }<br /> }<br />}<br /></strong><u>Первое, что мы делаем, это инициализируем Diamond Storage. Здесь мы будем хранить данные нашего фасета. Далее, где находится разница в <code>fallback()</code>s. Мы смотрим <code>diamond-2</code>выше. Во всех трех мы проверяем, существует ли адрес фасета.<br />Вот как мы регистрируемся <code>diamond-1</code>:</u></p>
  <p id="hBo4"><strong>// get facet from function selector<br />address facet = ds.facetAddressAndSelectorPosition[msg.sig].facetAddress;<br />if(facet == address(0)) {<br /> revert FunctionNotFound(msg.sig);<br />}</strong></p>
  <p id="MQvk"><u>Вот как мы регистрируем <code>diamond-3</code>:</u></p>
  <p id="hnwJ"><strong>// get facet from function selector<br />address facet = ds.selectorToFacetAndPosition[msg.sig].facetAddress;<br />require(facet != address(0), &quot;Diamond: Function does not exist&quot;);<br /><br /></strong></p>
  <p id="6a63"><u>Основное различие в трех реализациях заключается в том, что <code>diamond-2</code>мы храним селекторы в сопоставлении 32-байтовых слотов памяти.</u></p>
  <p id="e37b"><u>Наконец, мы используем Yul для <code>delegatecall()</code>наших аспектов, копируя данные вызова, которые были отправлены на <code>Diamond.sol</code>, и проверяя, был ли вызов успешным.</u></p>
  <p id="Mw6f"><u>На этом наш раздел о <code>Diamond.sol</code>. Далее мы рассмотрим, что происходило, когда мы вызывали <code>diamondCut()</code>.</u><br /><br /></p>
  <h1 id="2ca4">DiamondCut.sol</h1>
  <p id="60b9"><u>Как мы уже обсуждали, <code>DiamondCut.sol</code>отвечает за добавление, удаление и замену граней в нашем Алмазе. Все три реализации используют несколько иной подход, но достигают одной и той же цели. Давайте посмотрим, как работает diamond-1</u></p>
  <p id="meEp"><strong>contract DiamondCutFacet is IDiamondCut {<br /> /// @notice Add/replace/remove any number of functions and optionally execute/// @notice Add/replace/remove any number of functions and optionally execute<br /> /// a function with delegatecall<br /> /// @param _diamondCut Contains the facet addresses and function selectors<br /> /// @param _init The address of the contract or facet to execute _calldata<br /> /// @param _calldata A function call, including function selector and arguments<br /> /// _calldata is executed with delegatecall on _init<br /> function diamondCut(<br /> FacetCut[] calldata _diamondCut,<br /> address _init,<br /> bytes calldata _calldata<br /> ) external override {<br /> LibDiamond.enforceIsContractOwner();<br /> LibDiamond.diamondCut(_diamondCut, _init, _calldata);<br /> }<br />}</strong></p>
  <p id="a950"><u>Как видите, этот контракт сильно зависит от <code>LibDiamond.sol</code>. Все, что мы делаем, исходя из общего обзора, — это проверяем, что владелец контракта сделал этот вызов, а затем вызываем <code>diamondCut()</code>. Давайте посмотрим, что происходит в <code>LibDiamond.sol</code>. Прежде чем мы это сделаем, я должен указать на одну большую деталь о <code>LibDiamond.sol</code>. <code>LibDiamond.sol</code>использует исключительно <code>internal</code>функции. Это добавляет байт-код к нашему контракту, избавляя нас от необходимости использовать другой файл <code>delegatecall()</code>.</u></p>
  <p id="75e9"><u>Хорошо, теперь, когда мы понимаем, как сэкономить на топливе в <code>LibDiamond.sol</code>, давайте посмотрим на код <code>diamondCut()</code>.</u></p>
  <p id="Ethc"><strong>// Internal function version of diamondCut<br />function diamondCut(<br /> IDiamondCut.FacetCut[] memory _diamondCut,<br /> address _init,<br /> bytes memory _calldata<br />) internal {<br /> for (uint256 facetIndex; facetIndex &lt; _diamondCut.length; facetIndex++) {<br /> bytes4[] memory functionSelectors = _diamondCut[facetIndex].functionSelectors;<br /> address facetAddress = _diamondCut[facetIndex].facetAddress;<br /> if(functionSelectors.length == 0) {<br /> revert NoSelectorsProvidedForFacetForCut(facetAddress);<br /> }<br /> IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;<br /> if (action == IDiamond.FacetCutAction.Add) {<br /> addFunctions(facetAddress, functionSelectors);<br /> } else if (action == IDiamond.FacetCutAction.Replace) {<br /> replaceFunctions(facetAddress, functionSelectors);<br /> } else if (action == IDiamond.FacetCutAction.Remove) {<br /> removeFunctions(facetAddress, functionSelectors);<br /> } else {<br /> revert IncorrectFacetCutAction(uint8(action));<br /> }<br /> }<br /> emit DiamondCut(_diamondCut, _init, _calldata);<br /> initializeDiamondCut(_init, _calldata);<br />}<br /><br /></strong></p>
  <p id="11bc"><u>Мы берем те же параметры, что и раньше для этой функции. Сначала мы прокручиваем нашу <code>FacetCut</code>структуру. Внутри цикла мы получаем наш селектор функций и адрес фасетной функции. Мы удостоверяемся, что селектор фасета действителен, и возвращаемся в противном случае. Затем нам нужно проверить действие, которое мы выполняем с этой конкретной функцией (добавить, заменить или удалить). Найдя действие, мы вызываем вспомогательную функцию, которая коррелирует с этим действием. Затем мы создаем событие, чтобы обеспечить прозрачность для наших пользователей. Наконец, мы проверяем, работает ли наш фасет, <code>initializeDiamondCut()</code>проверяя, имеет ли наш контракт код и может ли он быть вызван через <code>delegatecall()</code>with <code>_calldata</code>.</u></p>
  <p id="cf19"><u>Теперь, когда мы знаем, как это <code>diamondCut()</code>работает, давайте посмотрим, как мы выполняем каждое действие, начинающееся с <code>Add</code>.</u></p>
  <p id="YqNG"><strong>function addFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal { addFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal { <br /> if(_facetAddress == address(0)) {<br /> revert CannotAddSelectorsToZeroAddress(_functionSelectors);<br /> }<br /> DiamondStorage storage ds = diamondStorage();<br /> uint16 selectorCount = uint16(ds.selectors.length); <br /> enforceHasContractCode(_facetAddress, &quot;LibDiamondCut: Add facet has no code&quot;);<br /> for (uint256 selectorIndex; selectorIndex &lt; _functionSelectors.length; selectorIndex++) {<br /> bytes4 selector = _functionSelectors[selectorIndex];<br /> address oldFacetAddress = ds.facetAddressAndSelectorPosition[selector].facetAddress;<br /> if(oldFacetAddress != address(0)) {<br /> revert CannotAddFunctionToDiamondThatAlreadyExists(selector);<br /> } <br /> ds.facetAddressAndSelectorPosition[selector] = FacetAddressAndSelectorPosition(_facetAddress, selectorCount);<br /> ds.selectors.push(selector);<br /> selectorCount++;<br /> }<br />}<br /><br /></strong></p>
  <p id="c61c"><u>Входными параметрами являются адрес фасетного контракта и селектор конкретной функции, с которой мы работаем. Мы хотим убедиться, что этот контракт существует, проверив, является ли адрес нулевым адресом. Далее мы инициализируем Diamond Storage. Затем мы получаем количество селекторов, которые уже есть у нашего Алмаза. После этого мы проверяем, есть ли у нашего фасета код контракта. Теперь нам нужно убедиться, что этой функции еще нет в Diamond. Мы делаем это, перебирая селекторы функций и проверяя, существует ли уже адрес. В противном случае мы нажимаем наш селектор на наши сохраненные селекторы.</u></p>
  <p id="0a36"><u>Теперь давайте посмотрим, как заменить грань!<br /><br /></u><strong>function replaceFunctions (адрес _facetAddress, bytes4[] memory _functionSelectors) internal { replaceFunctions (адрес _facetAddress, bytes4 [] memory _functionSelectors) internal { <br /> DiamondStorage storage  ds  = diamondStorage(); <br /> if (_facetAddress == address( 0 )) { <br /> revert CannotReplaceFunctionsFromFacetWithZeroAddress (_functionSelectors) ; <br /> } <br /> forceHasContractCode(_facetAddress, &quot; ); <br /> for (uint256 selectorIndex; selectorIndex &lt; _functionSelectors.length; selectorIndex++) { <br /> bytes4 selector  = _functionSelectors[selectorIndex]; <br /> адрес  oldFacetAddress  = ds.facetAddressAndSelectorPosition[селектор].facetAddress; <br /> // нельзя заменить неизменяемые функции — в данном случае функции, определенные непосредственно в ромбе <br /> if (oldFacetAddress == address( this )) { <br /> revert CannotReplaceImmutableFunction (selector) ; <br /> } <br /> if (oldFacetAddress == _facetAddress) { <br /> revert CannotReplaceFunctionWithTheSameFunctionFromTheSameFacet (селектор) ; <br /> } <br /> если (oldFacetAddress == адрес( 0 )) {<br /> вернуть CannotReplaceFunctionThatDoesNotExists (селектор) ; <br /> } <br /> // заменить старый адрес фасета<br /> ds.facetAddressAndSelectorPosition[selector].facetAddress = _facetAddress; <br /> }</strong></p>
  <p id="UVXg"><br /></p>
  <p id="d075">Как вы могли заметить, <code>Replace</code>запускается так же, как <code>Add</code>. Мы инициализируем Diamond Storage, проверяем, имеет ли фасет допустимый адрес и размер кода, затем прокручиваем селекторы. Во-первых, мы проверяем, является ли селектор неизменным. Затем мы проверяем, является ли функция, которую мы хотим заменить, той же функцией, которую мы добавляем. После этого мы проверяем, действителен ли адрес фасета. В противном случае мы заменяем нашу грань.</p>
  <p id="9ed1">Теперь давайте проверим наше последнее действие,</p>
  <p id="MHvN"><br /></p>
  <p id="Q46A">function removeFunctions (адрес _facetAddress, bytes4[] memory _functionSelectors) internal { removeFunctions (адрес _facetAddress, bytes4 [] memory _functionSelectors) internal { <br /> DiamondStorage storage  ds  = diamondStorage(); <br /> uint256  selectorCount  = ds.selectors.length; <br /> if (_facetAddress != <strong>адрес</strong>( 0 )) { <br /> revert RemoveFacetAddressMustBeZeroAddress (_facetAddress) ; <br /> } <br /> for (uint256 selectorIndex; selectorIndex &lt; _functionSelectors.length; selectorIndex++) { <br /> bytes4  selector  =_functionSelectors[<strong>селекторИндекс</strong>]; <br /> FacetAddressAndSelectorPosition memory  oldFacetAddressAndSelectorPosition  = ds.facetAddressAndSelectorPosition[селектор]; <br /> if (oldFacetAddressAndSelectorPosition.facetAddress == address( 0 )) { <br /> revert CannotRemoveFunctionThatDoesNotExist (селектор) ; <br /> } </p>
  <p id="ZVZN"> // нельзя удалить неизменяемые функции — <strong>функции, определенные непосредственно в ромбе </strong><br /> if (oldFacetAddressAndSelectorPosition.facetAddress == address( this )) { <br /> revert CannotRemoveImmutableFunction (selector) ; <br /> }<br /> // <strong>заменить селектор на последний селектор</strong><br /> selectorCount--; <br /> if (oldFacetAddressAndSelectorPosition.selectorPosition!= selectorCount) { <br /> bytes4  lastSelector  = ds.selectors[selectorCount]; <br /> ds.selectors[oldFacetAddressAndSelectorPosition.selectorPosition] = lastSelector; <br /> ds.facetAddressAndSelectorPosition[lastSelector].selectorPosition = oldFacetAddressAndSelectorPosition.selectorPosition; <br /> } <br /> // <strong>удалить последний селектор</strong><br /> ds.selectors.pop(); <br /> удалить ds.facetAddressAndSelectorPosition[селектор];</p>
  <p id="4ZFK"><br /></p>
  <p id="bc12">Опять же, мы начинаем с инициализации Diamond Storage, проверяя, имеет ли фасет действительный адрес, а затем прокручиваем селекторы. Затем мы получаем селектор функций и позицию в памяти. Мы проверяем, что он действительно существует, а затем проверяем, что он не является неизменным. После этого мы перемещаем наш селектор в конец массива и выполняем операцию <code>pop()</code>для его удаления.</p>
  <p id="1e4f"><code>diamond-2</code>и <code>diamond-3</code>обе достигают той же цели, что и <code>diamond-1</code>функция <code>diamondCut()</code>, но используют другой синтаксис и архитектуру. Для простоты этой статьи мы не будем останавливаться на них. Однако, если достаточное количество людей будет заинтересовано в том, чтобы узнать, как они работают, я могу написать новую статью в будущем, в которой будут более подробно описаны различия в реализациях.</p>
  <h1 id="29a6">LoupeFacet.sol</h1>
  <p id="82f3">Теперь, когда мы понимаем, как обновлять функции в нашем Алмазе, давайте рассмотрим, как мы можем просматривать наши грани. Помните, что for <code>diamond-1</code>и <code>diamond-2</code>не рекомендуется вызывать эти функции по цепочке. <code>diamond-3</code>, однако сильно оптимизирован для вызова этих функций в цепочке. Опять же, мы будем только повторяться <code>diamond-1</code>, но если вы понимаете, что происходит, вы должны быть в состоянии как понять, так и реализовать любую из других реализаций Diamond Standard.</p>
  <p id="f890">Сначала мы рассмотрим <code>facets()</code>. <code>facets()</code>, возвращает все грани и их селекторы для Diamond.</p>
  <p id="kRrQ"><em><strong>function facets() external override view returns (Facet[] memory facets_) {facets() external override view returns (Facet[] memory facets_) {<br /> LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();<br /> uint256 selectorCount = ds.selectors.length;<br /> // create an array set to the maximum size possible<br /> facets_ = new Facet[](selectorCount);<br /> // create an array for counting the number of selectors for each facet<br /> uint16[] memory numFacetSelectors = new uint16[](selectorCount);<br /> // total number of facets<br /> uint256 numFacets;<br /> // loop through function selectors<br /> for (uint256 selectorIndex; selectorIndex &lt; selectorCount; selectorIndex++) {<br /> bytes4 selector = ds.selectors[selectorIndex];<br /> address facetAddress_ = ds.facetAddressAndSelectorPosition[selector].facetAddress;<br /> bool continueLoop = false;<br /> // find the functionSelectors array for selector and add selector to it<br /> for (uint256 facetIndex; facetIndex &lt; numFacets; facetIndex++) {<br /> if (facets_[facetIndex].facetAddress == facetAddress_) {<br /> facets_[facetIndex].functionSelectors[numFacetSelectors[facetIndex]] = selector; <br /> numFacetSelectors[facetIndex]++;<br /> continueLoop = true;<br /> break;<br /> }<br /> }<br /> // if functionSelectors array exists for selector then continue loop<br /> if (continueLoop) {<br /> continueLoop = false;<br /> continue;<br /> }<br /> // create a new functionSelectors array for selector<br /> facets_[numFacets].facetAddress = facetAddress_;<br /> facets_[numFacets].functionSelectors = new bytes4[](selectorCount);<br /> facets_[numFacets].functionSelectors[0] = selector;<br /> numFacetSelectors[numFacets] = 1;<br /> numFacets++;<br /> }<br /> for (uint256 facetIndex; facetIndex &lt; numFacets; facetIndex++) {<br /> uint256 numSelectors = numFacetSelectors[facetIndex];<br /> bytes4[] memory selectors = facets_[facetIndex].functionSelectors;<br /> // setting the number of selectors<br /> assembly {<br /> mstore(selectors, numSelectors)<br /> }<br /> }<br /> // setting the number of facets<br /> assembly {<br /> mstore(facets_, numFacets)<br /> }<br />}</strong></em></p>
  <p id="e4ya">Обратите внимание, что входных параметров нет, и мы указываем, что будем возвращать <code>factes_</code>. <code>factes_</code>представляет собой структуру данных, которая выглядит следующим образом:</p>
  <p id="nyf1"><strong>struct Facet {<br /> address facetAddress;address facetAddress;<br /> bytes4[] functionSelectors;<br />}</strong></p>
  <p id="3fec">Первое, что мы делаем внутри функции, это инициализируем Diamond Storage. Затем мы получаем количество имеющихся у нас селекторов. После этого мы инициализируем массив, который будем возвращать в конце нашей функции. Затем мы создаем массив для отслеживания количества функций на фасет и переменную для отслеживания количества фасетов. Затем мы прокручиваем наши селекторы функций. Внутри нашего цикла мы ищем, к какому аспекту принадлежит наш селектор. Нам нужно перебрать фасеты, чтобы найти, какой адрес соответствует адресу наших текущих селекторов функций. После того, как мы находим наш фасет, мы добавляем наш селектор функций в массив этого фасета, если он существует. В противном случае мы создаем массив. После того, как мы закончим наш цикл, мы еще раз пройдемся по граням. Внутри этого цикла мы сохраняем количество селекторов в памяти, чтобы вернуться позже. Окончательно, мы сохраняем количество граней и возвращаемся. Причина, по которой мы сохраняем количество селекторов и фасетов, заключается в том, что мы изначально инициализировали наши массивы до максимально возможного размера. Теперь, когда мы знаем, сколько конкретных селекторов и фасетов мы будем возвращать, мы сообщаем Solidity правильный размер возвращаемого массива.</p>
  <p id="13f1">Следующая функция, которую мы рассмотрим, это <code>facetFunctionSelectors()</code>. <code>facetFunctionSelectors()</code>возвращает селекторы функций для определенного аспекта. Он принимает в качестве параметра адрес целевого фасета и возвращает массив, <code>bytes4[]</code>представляющий селекторы функций.</p>
  <p id="V4k9"><strong>function facetFunctionSelectors(address _facet) external override view returns (bytes4[] memory _facetFunctionSelectors) {facetFunctionSelectors(address _facet) external override view returns (bytes4[] memory _facetFunctionSelectors) {<br /> LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();<br /> uint256 selectorCount = ds.selectors.length;<br /> uint256 numSelectors;<br /> _facetFunctionSelectors = new bytes4[](selectorCount);<br /> // loop through function selectors<br /> for (uint256 selectorIndex; selectorIndex &lt; selectorCount; selectorIndex++) {<br /> bytes4 selector = ds.selectors[selectorIndex];<br /> address facetAddress_ = ds.facetAddressAndSelectorPosition[selector].facetAddress;<br /> if (_facet == facetAddress_) {<br /> _facetFunctionSelectors[numSelectors] = selector;<br /> numSelectors++;<br /> }<br /> }<br /> // Set the number of selectors in the array<br /> assembly {<br /> mstore(_facetFunctionSelectors, numSelectors)<br /> }<br />}</strong></p>
  <p id="35cc">Снова инициализируем Diamond Storage. Затем мы получаем количество селекторов функций и инициализируем наш возвращаемый массив. Далее мы прокручиваем селекторы. Здесь мы проверяем, совпадает ли адрес селектора с нашим целевым аспектом. Если это так, мы сохраняем этот селектор функций. Наконец, мы сохраняем количество селекторов и возвращаемся.</p>
  <p id="aada">Теперь рассмотрим <code>facetAddresses()</code>, который возвращает массив адресов граней нашего Алмаза.</p>
  <p id="zazb"><strong>function facetAddresses() external override view returns (address[] memory facetAddresses_) {facetAddresses() external override view returns (address[] memory facetAddresses_) {<br /> LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();<br /> uint256 selectorCount = ds.selectors.length;<br /> // create an array set to the maximum size possible<br /> facetAddresses_ = new address[](selectorCount);<br /> uint256 numFacets;<br /> // loop through function selectors<br /> for (uint256 selectorIndex; selectorIndex &lt; selectorCount; selectorIndex++) {<br /> bytes4 selector = ds.selectors[selectorIndex];<br /> address facetAddress_ = ds.facetAddressAndSelectorPosition[selector].facetAddress;<br /> bool continueLoop = false;<br /> // see if we have collected the address already and break out of loop if we have<br /> for (uint256 facetIndex; facetIndex &lt; numFacets; facetIndex++) {<br /> if (facetAddress_ == facetAddresses_[facetIndex]) {<br /> continueLoop = true;<br /> break;<br /> }<br /> }<br /> // continue loop if we already have the address<br /> if (continueLoop) {<br /> continueLoop = false;<br /> continue;<br /> }<br /> // include address<br /> facetAddresses_[numFacets] = facetAddress_;<br /> numFacets++;<br /> }<br /> // Set the number of facet addresses in the array<br /> assembly {<br /> mstore(facetAddresses_, numFacets)<br /> }<br />}</strong></p>
  <p id="2f14">Опять же, первое, что мы делаем, это инициализируем Diamond Storage, получаем количество селекторов функций и инициализируем наш возвращаемый массив. Мы также снова просматриваем наши селекторы. Мы проверяем адрес фасета нашего селектора. Затем мы проверяем, видели ли мы этот адрес раньше. Если у нас есть, мы пропускаем эту итерацию цикла. В противном случае мы добавляем этот новый адрес в наш возвращаемый массив. Опять же, мы обновляем размер массива и возвращаем его.</p>
  <p id="bce3">Последняя функция, которую мы рассмотрим, <code>DiamondLoupeFacet.sol</code>это <code>facetAddress</code>. Эта функция возвращает адрес фасета, предоставленного селектором функции.</p>
  <p id="dqsq"><strong>facetAddress(bytes4 _functionSelector) external override view returns (address facetAddress_) {<br /> LibDiamond.DiamondStorage storage ds</strong></p>
  <p id="b8e6">Эта функция довольно проста. Мы инициализируем Diamond Storage и используем то, как мы храним наши селекторы, чтобы вернуть наш адрес фасета.</p>
  <p id="5f49">На этом мы завершаем наш раздел, посвященный аспекту лупы. Теперь мы знаем, как Diamond Standard обеспечивает прозрачность для своих пользователей. Далее мы рассмотрим, как работает развертывание Diamond Standard.</p>
  <h1 id="d054">Как развернуть Diamond Standard</h1>
  <p id="9fac">При развертывании Diamond вам необходимо развернуть фасеты, а затем развернуть файлы <code>Diamond.sol</code>. Таким образом, вы можете сообщить своему Бриллианту, какие контракты он будет вызывать. Самый простой способ развернуть Diamond — с помощью пакета npm <code>diamond-util</code>. Вот как его установить</p>
  <p id="6KfP"><strong>npm i diamond-utili diamond-util</strong></p>
  <p id="kfPn">После его установки вы можете развернуть свой Diamond с помощью следующего кода.</p>
  <p id="mRfR"><strong>/ eslint-disable-next-line no-unused-vars<br />const deployedDiamond = await diamond.deploy({<br /> diamondName: &#x27;LeaseDiamond&#x27;,<br /> facets: [<br /> &#x27;DiamondCutFacet&#x27;,<br /> &#x27;DiamondLoupeFacet&#x27;,<br /> &#x27;Facet1&#x27;,<br /> &#x27;Facet2&#x27;<br /> ],<br /> args: [/* your parameters */]<br />})</strong></p>
  <p id="FZC2"><strong>// init facets<br />const diamondCutFacet = await ethers.getContractAt(&#x27;DiamondCutFacet&#x27;, deployedDiamond.address)<br />const diamondLoupeFacet = await ethers.getContractAt(&#x27;DiamondLoupeFacet&#x27;, deployedDiamond.address)<br />const facet1 = await ethers.getContractAt(&#x27;Facet1&#x27;, deployedDiamond.address)<br />const facet2 = await ethers.getContractAt(&#x27;Facet2&#x27;, deployedDiamond.address)</strong></p>
  <p id="523a">Эта библиотека берет на себя большую часть работы за нас! Все, что нам нужно сделать, это перечислить наши аспекты, и библиотека развернет их вместе с бриллиантом. Обратите внимание, что когда мы инициализируем наши контракты, <code>ethers.js</code>мы устанавливаем адрес на <code>Diamond.sol</code>адрес .</p>
  <p id="5bc3">Если вы хотите добавить новый аспект, вы можете сделать это, вызвав <code>DiamondCutFacet.sol</code>. Вот пример.</p>
  <p id="mEOW">const FacetCutAction = { Add: 0, Replace: 1, Remove: 2 }</p>
  <p id="u9nC">const Facet3 = await ethers.getContractFactory(&#x27;Facet3&#x27;)<br />const facet3 = await Facet3.deploy()<br />await facet3.deployed()<br />const selectors = getSelectors(facet3).remove([&#x27;supportsInterface(bytes4)&#x27;])<br />tx = await diamondCutFacet.diamondCut(<br /> [{<br /> facetAddress: facet3.address,<br /> action: FacetCutAction.Add,<br /> functionSelectors: selectors<br /> }],<br /> ethers.constants.AddressZero, &#x27;0x&#x27;, { gasLimit: 800000 }<br />)</p>
  <p id="4pUx">receipt = await tx.wait()</p>
  <h1 id="8023">Заключение</h1>
  <p id="tYlJ"><br />Как вы видите, сначала мы развертываем наш фасет. Затем мы используем наш пакет npm для получения селекторов функций. Затем мы вызываем DiamondCutFacet.sol, чтобы обновить наш Diamond. Replace работает аналогично, только вы должны убедиться, что селекторы, которые вы заменяете, уже есть в Diamond. Remove, также работает аналогично, но убедитесь, что селекторы, которые вы передаете, являются теми, которые вы хотите удалить.</p>
  <p id="ziaL">Поздравляем! Теперь вы знаете, как создать и развернуть блокчейн-приложение с помощью стандарта Diamond!</p>
  <p id="Q393">Заключение<br />На этом я завершаю свою статью о стандарте Diamond Standard. Надеюсь, я помог вам разобраться в сложностях стандарта Diamond Standard и понять, как реализовать его в своих собственных проектах.</p>

]]></content:encoded></item><item><guid isPermaLink="true">https://teletype.in/@oregoleh/a8bLj9okzQT</guid><link>https://teletype.in/@oregoleh/a8bLj9okzQT?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=oregoleh</link><comments>https://teletype.in/@oregoleh/a8bLj9okzQT?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=oregoleh#comments</comments><dc:creator>oregoleh</dc:creator><title>Как заявить права на свой DNS-домен в ENS?</title><pubDate>Wed, 01 Feb 2023 22:38:07 GMT</pubDate><media:content medium="image" url="https://img4.teletype.in/files/be/ae/beae10a4-45a1-46d9-849b-e00d5ffe5e73.png"></media:content><description><![CDATA[<img src="https://img4.teletype.in/files/ff/2a/ff2a054f-f7da-43bd-ba0c-c8c4767d82e5.png"></img>В зависимости от вашего провайдера DNS это может быть очень просто или довольно сложно.]]></description><content:encoded><![CDATA[
  <figure id="a2e2" class="m_column">
    <img src="https://img4.teletype.in/files/ff/2a/ff2a054f-f7da-43bd-ba0c-c8c4767d82e5.png" width="1705" />
  </figure>
  <h1 id="a127">1 — Настройка подписи DNSSEC</h1>
  <p id="f9e9">В зависимости от вашего провайдера DNS это может быть очень просто или довольно сложно.</p>
  <p id="3657">Если ваш DNS-провайдер уже поддерживает домены, подписанные DNSSEC, отлично! Следуйте их инструкциям по настройке DNSSEC.</p>
  <p id="7b79">Если они этого не сделают, вам нужно будет перейти к тому, кто это делает. Я рекомендую либо <a href="https://www.easydns.com/" target="_blank">EasyDNS,</a> либо <a href="https://cloudplatform.googleblog.com/2017/11/DNSSEC-now-available-in-Cloud-DNS.html" target="_blank">Google Cloud DNS</a> . Руководство EasyDNS по настройке DNSSEC находится <a href="https://www.nic.ru/help/nastrojka-dnssec_7965.html" target="_blank">здесь</a> , а руководство Google — <a href="https://cloud.google.com/dns/dnssec-config" target="_blank">здесь</a> .</p>
  <p id="8dc9">Независимо от того, какой провайдер вам нужен, убедитесь, что вы выбрали подписи RSA и хеширование SHA256.</p>
  <p id="6367">После настройки DNSSEC ваш провайдер DNS предоставит вам некоторые данные — записи DS или RRSIG. Вам нужно будет предоставить эти записи вашему регистратору. Это позволяет им вставить соответствующий «клей», чтобы убедиться, что все работает от начала до конца.</p>
  <p id="f9ba">Когда вы закончите этот шаг, используйте <a href="https://dnssec-debugger.verisignlabs.com/" target="_blank">отладчик Verisign DNSSEC</a> , чтобы убедиться, что все работает, прежде чем двигаться дальше.</p>
  <h1 id="72b9">2 — Добавление TXT-записи</h1>
  <p id="066b">Регистратор DNS в ENS ищет запись TXT с определенным именем и форматом, чтобы проверить, какой адрес Ethereum должен быть передан во владение доменом.</p>
  <p id="6549">Чтобы заявить о праве собственности на <em>mydomain.xyz</em> , создайте запись TXT в своей зоне DNS, <em>_ens.mydomain.xyz</em> , с текстовыми данными в форме <code>a=0x1234...</code>, где <code>0x1234...</code>адрес Ethereum, которому вы хотите передать контроль над записью ENS.</p>
  <h1 id="6552">3 — Взаимодействие с оракулом DNSSEC</h1>
  <p id="2224">Затем вам нужно доказать оракулу DNSSEC содержимое созданной вами записи TXT. Для этого вы можете использовать этот инструмент <a href="https://github.com/arachnid/dnsprove" target="_blank">dnsprove</a> , который я написал. Он позаботится обо всей тяжелой работе за вас.</p>
  <p id="4462">Сначала загрузите инструмент в <a href="https://golang.org/doc/code.html#Workspaces" target="_blank">рабочее пространство golang</a> и скомпилируйте его.</p>
  <p id="e74b">Затем бегите <code>dnsprove --address=0xd7296b6044ffd0565062345c2eaa4017024b2d22 --keyfile=/path/to/keyfile TXT _ens.mydomain.xyz</code>.</p>
  <p id="2db2">Чтобы команда работала, вам необходимо иметь работающий узел Ethereum <code>localhost:8545</code>— или вы можете указать собственное местоположение с помощью <code>--rpc=http://host:port</code>.</p>
  <p id="5ce3">Здесь адрес — это адрес оракула DNSSEC на Ropsten. Ключевой файл — это путь к файлу хранилища ключей JSON для учетной записи, которую вы хотите использовать для отправки транзакций.</p>
  <p id="4183">Прежде чем вы спросите, да, иронично, что эта команда еще не поддерживает имена ENS для указания адреса оракула DNSSEC.</p>
  <p id="e5d9">DNSSEC выполнит серию DNS-запросов, чтобы установить цепочку доверия. Затем DNSSEC сверится с оракулом, чтобы увидеть, какие шаги еще не были проверены или устарели.</p>
  <p id="4570"><code>dnsprove</code>затем запросит у вас разрешение на отправку транзакций, подтверждающих оставшиеся записи. Как только вы даете свое разрешение, транзакции отправляются, и Ethereum теперь официально осведомлен о ваших записях DNS!</p>
  <h1 id="4cb0">4 — Заявка на ваш домен в ENS</h1>
  <p id="8099">Наконец, вы можете заявить права на свой домен в ENS. В консоли geth выполните следующее:</p>
  <pre id="G3Fd">var registrar = web3.eth.contract([{&quot;константа&quot;:true,&quot;inputs&quot;:[],&quot;name&quot;:&quot;ens&quot;,&quot;outputs&quot;:[{&quot;name&quot;:&quot;&quot;,&quot;type&quot;:&quot; адрес&quot;}],&quot;оплачиваемый&quot;:ложь,&quot;stateMutability&quot;:&quot;представление&quot;,&quot;тип&quot;:&quot;функция&quot;},{&quot;константа&quot;:истина,&quot;входы&quot;:[],&quot;имя&quot;:&quot;rootDomain&quot;, &quot;выходы&quot;: [{&quot;имя&quot;:&quot;&quot;,&quot;тип&quot;:&quot;байты&quot;}],&quot;оплачиваемый&quot;:false,&quot;stateMutability&quot;:&quot;вид&quot;,&quot;тип&quot;:&quot;функция&quot;},{&quot;константа&quot; :true,&quot;inputs&quot;:[],&quot;name&quot;:&quot;oracle&quot;,&quot;outputs&quot;:[{&quot;name&quot;:&quot;&quot;,&quot;type&quot;:&quot;address&quot;}],&quot;payable&quot;:false,&quot;stateMutability&quot; :&quot;Посмотреть&quot;,&quot;тип&quot;:&quot;функция&quot;},{&quot;константа&quot;:ложь,&quot;входы&quot;:[{&quot;имя&quot;:&quot;имя&quot;,&quot;тип&quot;:&quot;байты&quot;}],&quot;имя&quot;:&quot;требование&quot;,&quot;выходы&quot; :[],&quot;payable&quot;:false,&quot;stateMutability&quot;:&quot;nonpayable&quot;,&quot;type&quot;:&quot;function&quot;},{&quot;constant&quot;:true,&quot;inputs&quot;:[],&quot;name&quot;:&quot;rootNode&quot;,&quot; outputs&quot;:[{&quot;name&quot;:&quot;&quot;,&quot;type&quot;:&quot;bytes32&quot;}],&quot;payable&quot;:false,&quot;stateMutability&quot;:&quot;view&quot;,&quot;type&quot;:&quot;function&quot;},{&quot;inputs&quot;: [{&quot;имя&quot;:&quot;_dnssec&quot;,&quot;тип&quot;:&quot;адрес&quot;},{&quot;имя&quot;:&quot;_ens&quot;,&quot;тип&quot;:&quot;адрес&quot;},{&quot;имя&quot;:&quot;_rootDomain&quot;,&quot;тип&quot;: &quot;bytes&quot;},{&quot;name&quot;:&quot;_rootNode&quot;,&quot;type&quot;:&quot;bytes32&quot;}],&quot;payable&quot;:false,&quot;stateMutability&quot;:&quot;nonpayable&quot;,&quot;type&quot;:&quot;constructor&quot;}]).at( &quot;0xf8d18b3c5de9892681998076bebcba32e62e0835&quot;);function encodeName(buf, off, name) {   if(name == &quot;.&quot;) {     buf.writeUInt8(0, off++);     вернуться;   }for(var часть name.split(&quot;.&quot;)) {     buf.writeUInt8(part.length, off++);     buf.write(part, off)     off += part.length;   }   возврат; }function hexEncodeName(name) {   if(!name.endsWith(&quot;.&quot;)) name = name + &quot;.&quot;;   var buf = новый буфер (имя.длина + 1);   var off = encodeName(buf, 0, name);   вернуть &quot;0x&quot; + buf.toString (&quot;hex&quot;, 0, off); }registrar.claim(hexEncodeName(&#x27;myname.xyz&#x27;), {from: myaddress})</pre>
  <p id="aa39">Запустите это, и как только транзакция будет добыта, все готово!</p>
  <p id="0579">Запись ENS, соответствующая <code>myname.xyz</code>, теперь принадлежит вашей учетной записи, и вы можете настроить ее так же, как и любое другое имя — возможно, с помощью <a href="https://manager.ens.domains/" target="_blank">manager.ens.domains</a> .</p>

]]></content:encoded></item><item><guid isPermaLink="true">https://teletype.in/@oregoleh/USEITMRDEVELOPER</guid><link>https://teletype.in/@oregoleh/USEITMRDEVELOPER?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=oregoleh</link><comments>https://teletype.in/@oregoleh/USEITMRDEVELOPER?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=oregoleh#comments</comments><dc:creator>oregoleh</dc:creator><title>Как использовать ChatGPT для разработчиков? +расширение для VSCODE</title><pubDate>Sun, 22 Jan 2023 11:06:35 GMT</pubDate><media:content medium="image" url="https://img4.teletype.in/files/39/49/3949c858-fe02-4970-a69d-e88f759bd2f1.png"></media:content><description><![CDATA[<img src="https://img1.teletype.in/files/80/65/80651d05-57f7-40e7-bb93-dec2f7041473.jpeg"></img>
1. Использование ChatGPT для разработчиков]]></description><content:encoded><![CDATA[
  <figure id="HqSf" class="m_column">
    <img src="https://img1.teletype.in/files/80/65/80651d05-57f7-40e7-bb93-dec2f7041473.jpeg" width="2400" />
  </figure>
  <h2 id="8FKg">Сегодня мы рассмотрим как использовать ChatGPT для разработчиков, прояснив некоторые детали а так же я покажу расширение VSCode с функциями, подобными ChatGPT.</h2>
  <p id="w1Pz"><br /><u><strong>1. Использование ChatGPT для разработчиков</strong></u></p>
  <ul id="nUOt">
    <li id="858a"><strong>Используйте его, чтобы помочь вам найти ошибки в вашем коде</strong> . Если у вас есть сегмент кода, который вы не можете отладить, вы можете поместить его в ChatGPT с информацией о том, что вы ожидаете, и что происходит на самом деле. Модель может помочь вам найти проблему.</li>
    <li id="34ff"><strong>Используйте его, чтобы помочь найти пограничные случаи в вашем коде</strong> . Модель обладает большой вычислительной мощностью, поэтому она может генерировать крайние случаи, для которых ваш код не сработает, и которые вы, возможно, не сможете определить так быстро.</li>
    <li id="b6b7"><strong>Используйте его для идей продукта</strong> . Задавая ему вопросы, связанные с продуктом, вы можете быстро получить список возможных вариантов использования вашего программного обеспечения на основе других продуктов и идей, на которых оно обучалось. Обычно это не дает нестандартных идей, но помогает найти пробелы в вашем продукте по сравнению с другими.</li>
    <li id="07f7"><strong>Используйте его для написания тестовых случаев. </strong>ChatGPT компетентен в написании юнит-тестов, и получение тестовых случаев из модели невелико, так как они просто не пройдут, если они неверны, и будут явно неправильно сформулированы, если он не тестирует то, что должен. Кроме того, поскольку модульные тесты, как правило, прямолинейны, вероятность того, что модель все сделает правильно, высока, если вы введете формат: протестируйте компонент X с входными данными a, b и c и ожидайте, что на выходе будет Y.</li>
    <li id="ae0a"><strong>Используйте его, чтобы получить архитектурные и инфраструктурные варианты</strong> . При оценке различных стратегий для задачи, которая, как вы знаете, потребует изменений в инфраструктуре, может быть полезно запросить мнение ChatGPT. Он может дать вам идеи, но не стоит полностью полагаться на его ответ, он должен быть не более чем источником вдохновения, если вы не уверены, куда идти.</li>
  </ul>
  <p id="j4B2"><strong><u>2. Как не использовать ChatGPT:<br /><br /></u></strong></p>
  <ul id="l6dL">
    <li id="666a"><strong>НЕ используйте его, чтобы научиться программировать</strong> . Генерируемый код не гарантируется правильным. Он может быть функциональным, но даже если он функциональный, это может быть не лучший способ кодирования. Например: я заметил, что когда я попросил его написать компоненты React, он использует общий элемент реквизита и не определяет каждое свойство явно, как это является отраслевым стандартом. Кроме того, он не абстрагирует аналогичный код автоматически в функции, поэтому код обычно слишком многословен.</li>
    <li id="05ea"><strong>НЕ используйте его для генерации кода, который требует много контекста</strong> . Если вы надеетесь, что модель сделает вашу работу, у меня для вас плохие новости. Невозможно предоставить модели контекст всей кодовой базы или продукта, поэтому, если у вас еще нет четкого представления о том, как подойти к задаче, ChatGPT реально не очень поможет.</li>
    <li id="1b16"><strong>НЕ используйте его для школьных или университетских заданий</strong> . Помимо того, что ответ может быть неверным, а также того, что, возможно, другие студенты будут использовать его с той же целью, ведущей к обнаружению плагиата, вы ничему не научитесь. Решение задач — это то, что заставило меня больше всего расти во время моего формального образования в области разработки программного обеспечения. Не лекция, а задания — это то, чему я научился больше всего, поэтому, если вы обманываете с помощью ChatGPT, вы просто лишаете себя лучшей карьеры.</li>
  </ul>
  <h1 id="aa96">CodeGPT: расширение VSCode с функциями, подобными ChatGPT</h1>
  <figure id="hLRx" class="m_original">
    <img src="https://img4.teletype.in/files/79/e2/79e2bafb-6d91-4eed-9d0d-ac95623f3925.jpeg" width="828" />
    <figcaption>Будьте внимательны. Это расширение нужно использовать на свое усмотрение. </figcaption>
  </figure>
  <p id="6d95">Это расширение позволяет нам использовать GPT-3 внутри VSCode через официальный API OpenAI. Это что-то вроде наличия ChatGPT в нашем редакторе кода!</p>
  <p id="77a0">С CodeGPT мы можем генерировать код, объяснять код, рефакторить код и многое другое. Давайте посмотрим, как его настроить и изучить все его функции.</p>
  <h2 id="e4e9">Настройка CodeGPT на VSCode</h2>
  <p id="74f7">Чтобы установить это расширение, нам нужно открыть VSCode, перейти к расширениям и выполнить поиск «Код GPT». Как только мы находим его, мы нажимаем «установить».</p>
  <figure id="i673" class="m_original">
    <img src="https://img4.teletype.in/files/fe/4b/fe4beff6-49b0-4b1c-9c93-939e1b367edf.jpeg" width="344" />
  </figure>
  <p id="5b75">После установки кода GPT нам нужно перейти в «Настройки» и перейти к «Код GPT» (в macOS перейдите в строку меню и нажмите «Код», затем выберите «Настройки», чтобы найти параметр «Настройки»).</p>
  <p id="b042">В настройках мы увидим следующее.</p>
  <figure id="XoP6" class="m_column">
    <img src="https://img1.teletype.in/files/43/fc/43fc174a-a9bb-4764-be53-0b4ea4891890.jpeg" width="828" />
  </figure>
  <p id="32h7">Чтобы работать с этим расширением, вам нужно ввести <a href="https://beta.openai.com/account/api-keys" target="_blank">ключ API OpenAI</a> в первое поле на изображении выше.</p>
  <figure id="D7be" class="m_original">
    <img src="https://img4.teletype.in/files/78/58/7858bc85-bd52-4b7d-a7d9-97ef4fbc5872.jpeg" width="833" />
  </figure>
  <p id="2b7b">Вы можете оставить остальные поля как есть, но если вы хотите их настроить, имейте это в виду:</p>
  <ul id="2J5L">
    <li id="1c2f">Max tokens: Максимальное количество токенов, которое вы хотите получить за каждый запрос к API.</li>
    <li id="4436">Model: В настоящее время в этом расширении доступны 3 модели ( <code>text-davinci-003</code>, <code>code-cushman-001</code>и <code>code-davinci-002</code>). Среди этих вариантов <code>code-davinci-002</code>самый мощный, когда дело доходит до кодирования.</li>
    <li id="f0ac">Temperature: контролирует степень случайности в выводе ( <a href="https://algowriting.medium.com/gpt-3-temperature-setting-101-41200ff0d0be" target="_blank">чем ниже температура, тем больше вероятность того, что GPT-3 выберет слова с более высокой вероятностью появления</a> ) .</li>
  </ul>
  <h2 id="b7a7">Изучение CodeGPT</h2>
  <p id="a86d">Вот основные функции CodeGPT</p>
  <ul id="efdj">
    <li id="260a">Сгенерировать код: вам нужно только ввести комментарий с запросом определенного кода, затем нажать, <code>cmd-shift-i</code>и CodeGPT откроет новое окно с кодом.</li>
  </ul>
  <figure id="L1YH" class="m_retina">
    <img src="https://img1.teletype.in/files/43/5e/435ef633-349e-4c4e-a4a8-caf70300e643.gif" width="576" />
  </figure>
  <ul id="8rm0">
    <li id="bb0a">Объяснить код: выберите код, щелкните его правой кнопкой мыши и выберите параметр «Объяснить кодGPT». CodeGPT откроет новое окно и объяснит код.</li>
  </ul>
  <figure id="EH5d" class="m_column">
    <img src="https://img4.teletype.in/files/b8/21/b821e5c2-c61e-48b5-9852-4e5d2b1e912f.jpeg" width="828" />
  </figure>
  <p id="LBy4"><u>Вот результат</u></p>
  <figure id="iiuj" class="m_column">
    <img src="https://img2.teletype.in/files/d8/d3/d8d34a53-46ee-4784-918c-82906cc8a764.jpeg" width="828" />
  </figure>
  <p id="fGa5">Для получения дополнительной информации об этом расширении нажмите <a href="https://marketplace.visualstudio.com/items?itemName=DanielSanMedium.dscodegpt&ssr=false#overview" target="_blank">здесь.</a></p>

]]></content:encoded></item><item><guid isPermaLink="true">https://teletype.in/@oregoleh/SocialInteractionFromParkinson</guid><link>https://teletype.in/@oregoleh/SocialInteractionFromParkinson?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=oregoleh</link><comments>https://teletype.in/@oregoleh/SocialInteractionFromParkinson?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=oregoleh#comments</comments><dc:creator>oregoleh</dc:creator><title>Социальное взаимодействие для успешного построения карьеры в web3</title><pubDate>Tue, 10 Jan 2023 19:50:00 GMT</pubDate><media:content medium="image" url="https://img3.teletype.in/files/6c/3a/6c3ad1c5-6269-4094-8e9d-6393f99d6b36.png"></media:content><category>Social Interaction</category><description><![CDATA[<img src="https://img4.teletype.in/files/70/a4/70a41db8-7622-4b04-a7b6-33d3ea6d4380.png"></img>Всем привет. В сети огромное кол-во информации о том, как отшлифовать свои навыки, но мало сказано том, как их успешно применять и продавать в мире, где без связей с людьми подниматься по лестнице гораздо труднее. 
]]></description><content:encoded><![CDATA[
  <figure id="3jND" class="m_column">
    <img src="https://img4.teletype.in/files/70/a4/70a41db8-7622-4b04-a7b6-33d3ea6d4380.png" width="1200" />
    <figcaption>by Parkinson</figcaption>
  </figure>
  <p id="wNUV"><em>Всем привет. В сети огромное кол-во информации о том, как отшлифовать свои навыки, но мало сказано том, как их успешно применять и продавать в мире, где без связей с людьми подниматься по лестнице гораздо труднее. <br /></em></p>
  <p id="xhUZ">Сегодня речь пойдет о социальном взаимодействии в сети и жизни. Я постараюсь дать максимально полезную информацию от себя о:</p>
  <ul id="INks">
    <li id="897E"><u>Портфолио, продажа себя, социальный капитал</u></li>
    <li id="4zNY"><u>Поиск единомышленников</u></li>
    <li id="a0y6"><u>Как находить связи и строить с ними отношения</u></li>
    <li id="8WR7"><u>Поиск клиентов</u></li>
    <li id="00Yy"><u>Значимость twitter и его отличие от linkdln</u></li>
    <li id="uNrr"><u>За что поднимают зарплату? Фокусы для работодателей.</u><br /><br />. <u>Ваш username: BenJun.</u></li>
  </ul>
  <p id="a0qt">Для того, чтобы все нижеперечисленное было понятно и усвоилось, давайте сыграем в небольшую игру. Представьте что вы персонаж который только-только приобрел навыки и может претендовать на джуна в блокчейн-разработке</p>
  <figure id="kHhf" class="m_original">
    <img src="https://img4.teletype.in/files/fd/83/fd8350a5-6ffe-4e3a-804d-bce804bcf59e.jpeg" width="768" />
    <figcaption>MrBenJun</figcaption>
  </figure>
  <p id="2hWv"><em>Все что делает игрок, должно заноситься в GitHub. Все ваши проекты в процессе учебы должны быть опубликованы. Ваша задача - собрать из всей своих действий список проектов. Не стоит включать режим самозванца и считать что ваши проекты мусор. Однако, выбрать из них самые стоящие все равно стоит. Пусть они будут в закрепе. </em></p>
  <h2 id="lkUp" data-align="center">Портфолио, продажа себя <br /></h2>
  <p id="XiHg" data-align="center"><em><br />Собирайте о себе как можно больше информации в цифровом формате. Когда на собеседовании вы только-только сядете на стул или подключитесь к комнате в Google Meets перед работодателем будет белый лист. Ваша задача - за короткое время успеть раскрасить себя так, чтобы вас захотели купить. Естественно, рассказать о себе будет недостаточно и вы должны будете кидать на стол свои достижения.<br />Наилучшая концепция портфолио:<br />Заполненный GitHub, опыт работы в команде, доказательства участия в сообществе, наличие единомышленников, знакомства с некоторыми локальными лидерами мнений. Переходя к самому собеседованию BenJun&#x27;A</em><br /><br />Эффектность фактов и скромность поведения вызывает уважение и заинтересованность. Один мой товарищ проходил собеседования держа свое туловище руками. Он создавал образ скромного парня с кучей ментальных проблем, но рассказывая о своих высококвалифицированных прошлых проектах и работе которую он проделывал так, что на работодателей это производило нужный эффект. (Поговорим об этом подробнее в разделе фокусы)<br />Тщательно подготавливайтесь к собеседованию, чтобы говорить на нем четко. <br />(О том, как подготовиться к собеседованию я напишу отдельный пост)<br /><strong><br /><em>Социальный капитал</em><br /><br /></strong>Социальный капитал показывает, какое влияние вы имеете в социальных кругах. Хорошими показателями для определения социального капитала являются:</p>
  <ul id="q7ab">
    <li id="6p9z">релевантные подписчики на социальных платформах в отрасли</li>
    <li id="KfSl">репутация, сформированная созданием вклада в сеть</li>
    <li id="HI19">друзья в сети, которые помогут вам расти, у которых вы можете учиться, на которых вы можете положиться, с которыми вы можете обсудить свои идеи и получить от них конструктивную критику.</li>
    <li id="dczs">связи с людьми, которые могут представить вас или поручиться за вас в различных ситуациях</li>
  </ul>
  <p id="u9uF">Существуют различные методы накопления социального капитала. Большинство из них заключается в выводе соответствующего контента, создании сетей и взаимодействии с людьми в сети, создании продуктов, различных способах вклада в экосистему, предоставлении ценности (или развлечения) и многие другие.</p>
  <p id="SUC3">Чтобы встретить «хороших» людей в пространстве, вам также нужно проводить свое время в правильных местах и ​​делать правильные вещи, эта статья поможет вам оптимизировать свое внимание и сэкономить время, не тратя его впустую на пустые действия. Вы получите практические советы в следующих разделах.</p>
  <p id="sK3r">Еще одним важным аспектом накопления социального капитала является размещение контента, который другие люди находят интересным, привлекательным, актуальным или ценным. Как разработчик в пространстве, ваш контент должен быть ценным для других людей : для разработчиков и других людей, желающих получить более технический обзор области/продуктов/проектов, над которыми вы работаете. Существует также большой потенциал для накопления социального капитала путем создания образовательных ресурсов, таких как подборки, забавные факты, руководства, учебные пособия, обзоры и т.д<br /></p>
  <h2 id="bUEc" data-align="center">Поиск единомышленников</h2>
  <p id="7inP"></p>
  <p id="6C78">Успешная учеба невозможна без сообщества как и работа. Поиск единомышленников важен в обоих случаях. Вам нужно получать и также обмениваться информацией с людьми чтобы иметь разные точки зрения. Закрывшись дома от всего мира наедине со статьями и кодом обернется либо ментальной трагедией, либо  результат будет малоэффективным. <br />Касательно телеграмма: окунитесь в cообщество с помощью разных чатов, где собираются наставники, стажеры, инвесторы и многие другие люди. В нашей сфере огромное кол-во людей с интересным background&#x27;ом, не упускайте эту возможность. <br />Поймите одну вещь: человеку который имеет знания и занимается определенным делом всегда будет приятно отвечать на вопросы касательно его деятельности. Многим ли людям было бы неприятно если бы у них брали интервью? Я считаю что нет. Не бойтесь спрашивать, когда-то эти люди были такими же как и вы. Спрашивайте, но старайтесь четко формулировать свои вопросы. Однако, не забывайте что у вас под рукой есть Google. Лично я задаю вопросы более опытным ребятам в том случае, если не нахожу информации в поисковике. <br />Это может быть ошибкой в технической задаче и т.п. <br /><br />Человеку становится спокойнее, когда он чувствует стабильность. Редко ей можно окружить себя полностью, но касательно социального взаимодействия это возможно. Вам нужна принадлежность к определенной группе людей. В поиске чатов, вы сможете стать участником социальной группы. Приносите вклад в эту соц.группу: делитесь информацией, отвечайте на вопросы на которые знаете ответ, помогайте новым ребятам. Зарабатывая уважение и значимость: вы сможете взаимодействовать с определенными людьми в личных сообщениях. Чем больше у вас будет таких людей, тем больше шанс собрать небольшую команду в будущем. Держите связь.<br /><br /><em><u>Окружив себя единомышленниками, BenJun должен найти связи. </u></em></p>
  <h2 id="NvSt" data-align="center">Как находить связи и строить с ними отношения</h2>
  <p id="4SRF" data-align="center"><em><strong><u>Каждая ситуация с поиском связей является уникальной, поэтому я написал несколько практических советов которые вы можете использовать а так же информацию для общего понимания как работает этот механизм</u>.</strong></em></p>
  <p id="zMVa"><br />Хотя они доступны не всем, но по всему миру проводятся мероприятия, на которых люди из разных сообществ в рамках web3 и криптографии собираются вместе для организации конференций, хакатонов, вечеринок, встреч, переговоров и многого другого. Мероприятия в реальной жизни — одно из лучших мест, где можно найти единомышленников, с которыми можно подружиться, получить работу, пообщаться с другими интересными людьми в этой области, учиться, расширять свои границы и т. д. , <br /><br />Недооценено, насколько вы можете вырасти как разработчик, если окружите себя людьми, обладающими теми же качествами, которые вы хотите приобрести для себя. Окружающие вас люди могут подтолкнуть вас к росту и привести к новым высотам, поскольку они ставят перед вами новые задачи и помогают вам на этом пути. Это непредсказуемая штука которая всегда подкидывает сюрпризы, но ваша активность на подобных конференциях определенно даст вам неплохой социальный буст. <br /><br />Для чего вам нужны связи? Для того чтобы в определенный момент они исполнили вашу просьбу. Но для этого нужно использовать прием, который называется взаимопомощь. Ваша задача помогать человеку, отдавая бескорыстно информацию, помощь с проектами и чем только можно на первых этапах ваших отношений. Для формирования потребности у человека помочь вам с чем-либо нужно время. Однако, это рабочий прием который основан на психологии. Это практический совет, попробуйте и вы ощутите его действие.<br />Так же вам нужно формировать свою значимость. На самом деле, это внерамочное понятие в этой теме. Ваша задача иметь или получить то, что будет нужно или интересно другим. <br /><br />Алкоголь позволяет укрепить взаимоотношения. Используйте походы в бар для получения информации, либо повысить свою значимость в глазах человека. В состоянии алкогольного опьянения некоторые рассказанные вами факты, или показанные проекты привлекают внимание и удивляют намного сильнее, чем в трезвом состоянии. Используйте способ с растительным маслом, для того чтобы не потерять связь с реальность. Около двух столовых ложок растительного масла способны создать защитную оболочку в вашем желудке от алкоголя, остается лишь надеть маску пьяного парня.<br />Помимо алкоголя, такие вещи как совместный обед, стрельба в тире и прочие вещи которые вы можете сделать вдвоем получая одновременно дофамин, способны усилить близость. Если ваша цель определенный человек, все становится немного проще. Ваша задача: при каждой с ним встречи стараться принести как можно больше дофамина в совместное времяпровождение. </p>
  <h2 id="Ez0q" data-align="center"><u>                                   Поиск клиентов                                         <br /></u></h2>
  <figure id="QMK9" class="m_custom">
    <img src="https://img2.teletype.in/files/53/2f/532f8436-67b4-4958-a525-913f88aefa9e.jpeg" width="485.1612903225806" />
    <figcaption>Help me</figcaption>
  </figure>
  <p id="ZGIM">Так же я настоятельно рекомендую искать и их на различных конференциях. <br /><br />Переходя в режим поиска online я скажу лишь то, что вам будет достаточно чатов. <br />Никакие биржи труда неактуальны для фриланса на первых этапах. Вам нужны конкретные пользователи в сети, желательно не привязанные к большой компании или стартапу. В первое время вам нужно будет добыть себе коммерческое портфолио, и в большинстве случаев, только одиночки вам с этим и помогут. Люди, ищущие исполнителей для себя менее требовательны чем HR-менеджеры из компаний. <br /><br />Предлагайте и делайте работу для людей с аудиторией в социальных сетях. Когда я был в другой сфере, я предлагал медийным личностям свои услуги за бесплатно, взамен получая ссылки на свои социальные сети которые видели десятки тысяч человек. С этих ссылок я получал огромное кол-во сообщений и 20% из них заканчивались знаком подписания договора - рукопожатием.<br />Делайте работу качественно, особенно для клиентов с большой аудиторией. Стоит попытаться чтобы после исполнения вашего заказа, вы включили в человеке режим сарафанного радио.<br />Чем больше о вас узнает людей, тем большее кол-во клиентов вы сможете привлечь. Охотьтесь на аудиторию. </p>
  <h2 id="3QC2" data-align="center">    Значимость twitter и его отличие от linkdln</h2>
  <figure id="tnWB" class="m_original">
    <img src="https://img1.teletype.in/files/07/f0/07f04cd5-afb2-4fab-b13a-bd32901f32cf.jpeg" width="548" />
    <figcaption>платформы социальных сетей, используемые b2b-маркетологами для целей контент-маркетинга</figcaption>
  </figure>
  <p id="Oahy">Twitter — это место, где можно найти работу по разработке блокчейна, LinkedIn редко используется для найма талантов в этой области, хотя это тоже не редкость. Поскольку большая часть культуры web3/crypto находится в Твиттере, это естественное место для общения разработчиков, основателей, создателей и пользователей. Чем большую ценность вы предоставляете сообществу, тем больше подписчиков вы получите, а значит, тем больше охват как у разработчика. Все команды жаждут хороших разработчиков, поэтому чем больше у вас будет релевантных подписчиков, тем больше шансов, что вас обнаружит команда, которая хочет нанять разработчика блокчейна в вашей области знаний. Создание вашей репутации в Твиттере может продвинуть вас вперед больше, чем вы ожидаете.</p>
  <p id="sCS9">Если вам удастся продемонстрировать мастерство в каком-либо заданном навыке в web3, то вам гарантирована должность практически в любом месте, поскольку все команды ищут таланты. Если вы только начинаете, но проявляете сильное стремление и инициативу в обучении, многие команды попросят взять вас под свое крыло, чтобы улучшить свои навыки, запачкав руки и учась, создавая по ходу дела. Благодаря активности на соответствующих социальных платформах, таких как Twitter, Discord и Telegram, и общению с нужными людьми найти работу становится относительно легко, поскольку все ищут таланты.</p>
  <h1 id="8OjS" data-align="center">         Социальные взаимодействия (bonus) <br /></h1>
  <p id="9jcg"><em>Когда вы находитесь на упомянутых выше социальных платформах, вы должны нацеливаться на людей, которые помогают вам расти, и устанавливать с ними связи.</em></p>
  <ul id="hEKA">
    <li id="EDN2"><em>эксперты в интересующей вас области</em></li>
  </ul>
  <p id="PYtl"><em>Если вы общаетесь с людьми, обладающими опытом в тех областях, в которых вы хотите стать квалифицированным, вам будет намного легче их изучить, вы получите хорошие связи, которые продвинут вас вперед в вашей карьере, и вы также, скорее всего, получите больше возможностей и ресурсов для роста в качестве разработчика, нанявшись на работу, получив советы о том, как эффективно изучить свою область специализации и многое другое!</em></p>
  <ul id="wWdV">
    <li id="sMji"><em>люди пытаются научиться тому же, что и вы</em></li>
  </ul>
  <p id="yQKH"><em>Хорошо делиться идеями и получать двустороннюю обратную связь по любой теме, которую вы изучаете, от других людей, изучающих тот же материал, что и вы, особенно если они более опытны, чем вы. Еще одна веская причина учиться в группах (в идеале в парах) заключается в том, что обучение — это лучший способ закрепить свои знания, поскольку, когда вам нужно просто объяснить сложную тему, вам нужно хорошо понимать любую данную тему, чтобы вы могли объяснить это. </em></p>
  <h2 id="xk77">Контент (bonus)</h2>
  <p id="p2UV"></p>
  <p id="IFja"><em>Чтобы накопить социальный капитал, размещение хорошего контента на различных популярных социальных платформах имеет решающее значение, поскольку людям нравится подписываться на отдельных лиц и группы, от которых они могут получить пользу. Например: если вы начнете говорить о создании в DeFi, то люди, заинтересованные в DeFi, начнут подписываться на вас, ставить лайки и ретвитить ваши сообщения, участвовать в обсуждениях в комментариях и т. д. Как разработчик блокчейна в любой специализации, вы можете использовать разные способы. предоставлять интересный контент и распространять его на разных социальных платформах.</em></p>
  <ul id="a9Ha">
    <li id="TiAs"><em>документ &gt; создать в начале Когда вы начинаете работать разработчиком блокчейна, у вас обычно не будет никаких новых открытий, интересных вещей, которые вы создаете, или проектов, над которыми вы работаете, поэтому хорошо поделиться своим собственным процессом обучения и своим путешествием. стать разработчиком блокчейна.</em></li>
    <ul id="8yTP">
      <li id="sxYn"><em>расскажите о том, что вы узнали в своем путешествии:<br />полезно говорить о различных ресурсах, которые вы используете для изучения интересующих вас тем, делиться ими с другими и рассказывать им, как они помогли вам узнать о конкретной теме, а также предоставлять комментарии и полезные советы, которые могут быть упущены людьми, просматривающими ресурсы и не углубляющимися в них.</em></li>
      <li id="HR5M"><em>говорить об инструментах, которые вы используете: разработчики любят говорить о своих инструментах, какие библиотеки они используют, какие IDE и расширения они используют для написания кода, какие сервисы и приложения они используют ежедневно, чтобы организовать себя и быть продуктивными, и многое другое. более.</em></li>
      <li id="BBJk"><em>задавайте вопросы о вещах, которые вы изучаете: есть вероятность, что у многих людей, которые следят за вами, задавались те же вопросы, что и у вас в прошлом, и они могут дать вам много полезной информации по любой заданной теме.</em></li>
      <li id="Dtp6"><em>будьте активны в темах, которые имеют отношение к вашим интересам: если в интересующем вас пространстве происходят соответствующие события, рекомендуется участвовать в публичных дискуссиях с другими людьми вокруг этих событий, чтобы получить лучший обзор что происходит, и попытаться извлечь из этого ценную информацию / уроки</em></li>
    </ul>
    <li id="2y03"><em>ретвитить то, что происходит в сфере ваших интересов, с комментариями/мнениями</em></li>
    <li id="ZStn"><em>резюмировать статьи, доклады, события, обновления, обсуждать код в интересующих вас проектах/областях.</em></li>
    <li id="UZme"><em>шитпост (выражайте свою индивидуальность / будьте собой) для участия (расширяете свою сеть, развлекаясь): будьте креативны, разработка не обязательно должна быть всем, о чем вы говорите, многие также используют социальные платформы, чтобы подружиться и повеселиться, так что вы также можете делать забавный контент, беззаботные темы на любую заданную тему, публиковать фотографии вашей собаки или что угодно. Выражение собственной индивидуальности также полезно для создания личного бренда в социальных сетях.</em></li>
  </ul>
  <h2 id="cbL7"><u>За что поднимают зарплату? Фокусы для работодателей.</u></h2>
  <p id="C453">В сети куча людей бесконечно твердит что уровень вашей заработной платы напрямую зависит от качества вашей работы, статичных приложенных усилий за рабочие дни, и многое другое характеризующиеся неким &quot;плодом состояния потока&quot;, но в реальной жизни это выглядит немного иначе.<br /><br />Безусловно выполнять свою работу качественно и ставить перед собой цели чуть выше ваших реальных возможностей ведет вас наверх и необходимо для развития. Это так же может влиять на заработную плату, но если вы грамотно будете показывать это работодателю. <br /><br />Сегодня я зайду в эту тему немного с иной стороны, и о том как ваша продуктивность отражается на заработную плату говорить не стану. Довольно мейнстрима. Ибо все это на самом деле малоэффективно если вы работаете на кого-либо. Продуктивность и все вышенаписанное стоит применять когда вы работаете на себя. А знаете что на самом деле эффективно? Фокусы.<br /><br />Начну с примера из реальной жизни. Пусть его имя будет так же - BenJun. <br />BenJun работает в сфере кибербеза и считается квалифицированных специалистом, но почему-то его зарплата не переваливает больше чем за 75тыс рублей. Почему так? Разбирая тему подробнее, давайте подумаем кто ему платит деньги и что из себя представляет этот человек? <br />BenJun получает деньги от человека, который знаком с кибербезом достаточно поверхностно. Его задача - находить клиентов и эксплуатировать BenJun&#x27;а. <br />Несколько месяцев подряд BenJun активно пытался работать очень искусно, делая необычные вещи и крайне гениальные проекты. Однако, все эти гениальности проявлялись в мелочах, и знаете, для высококвалифицированного специалиста эта самая гениальность выглядит иначе, чем для обычного начальника который не посвящает этой деятельности все свободное время. Планка того, что гениально у специалиста выше, чем у обычного человека. (так в любой сфере) Следовательно, получается так, что BenJun делает поистине гениальные мелочи, но начальник слишком поверхностен в этой деятельности чтобы их понять. И после выплеска всей своей креативности и энергии BenJun остается с той же самой зарплатой. Однако к нему в штат приходит новый сотрудник который на несколько лет меньше в этой сфере, но уже через два месяца его заработная плата дошла до 100 тысяч рублей в месяц. Что он сделал?<br />В один из дней сотрудник вставил флешку в ноутбук своего начальника и удаленно выводил на его экране: калькулятор, текстовый документ и другие приложения. Начальник не понимал что происходит, но после всего этого сотрудник подходил к нему и объяснял что произошло. Таких мелочей в его днях становилось больше, и зарплата росла. <br /><br />А теперь давайте разберем этот механизм:<br /><br />Фокус заключался в том, что сотрудник делал простые, но эффектные вещи. Эффектных в сознании начальника. Так уж устроен наш мир, но работает это действительно так, как бы вас это не забавляло. <br />Психология и фокусы способны вести вас вверх с бешеной скоростью, в любой сфере в которой вы начинаете работать. <br />Однако не всегда это работает везде и всегда. Сначала стоит проанализировать действительно ли ваш начальник как в примере выше. Исключения бывают реже, чем такой подход с фокусами. Именно в этих исключениях вы и сможете плодить свои гениальные проекты, однако, если вы действительно способны кодить подобное, стоит работать на себя. Люди будут лишь продавать ваш товар. <br /><br />Возвращаемся к теме.<br /><br />Вывод таков, что эффектность и фокусы действуют на работодателей &quot;магическим&quot; образом. Опять же, как я уже и говорил в разделе про поиск связей: впечатление. К сожалению, в нашей жизни это действительно рабочий метод. И он является эффективным в большинстве сфер.<br /></p>
  <p id="Ca9U" data-align="right"><em>«Единственная перспектива у продвинутого парня в этой стране — работать клоуном у пидарасов. А кто не хочет работать клоуном у пидорасов, будет работать пидорасом у клоунов. За тот же самый мелкий прайс» - В. Пелевин<br /><br /></em></p>
  <p id="aIDU" data-align="center">Вы так же должны выполнять свою работу качественно, но поймите одну вещь: Поднятие вашей заработной платы будет зависеть в большинстве от фокусов, нежели от профессионально выполненной рутины.<br /><br /><strong>GAME OVER<br />Winner&#x27;s nickname: BenJun</strong></p>
  <p id="9GJF">Надеюсь что я дал вам полезную информацию которую вы сможете применить в своей жизни, либо которая изменит ваше представление или мышление по поводу некоторых вещей. Если вам интересен подобный материал, вы можете поддержать меня в моем телеграмм канале <a href="https://t.me/Solidity_RUS_ETH" target="_blank">https://t.me/Solidity_RUS_ETH</a><br /></p>

]]></content:encoded></item><item><guid isPermaLink="true">https://teletype.in/@oregoleh/IAQqKxcegdb</guid><link>https://teletype.in/@oregoleh/IAQqKxcegdb?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=oregoleh</link><comments>https://teletype.in/@oregoleh/IAQqKxcegdb?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=oregoleh#comments</comments><dc:creator>oregoleh</dc:creator><title>Осознай пузырь. Выйди из матрицы.</title><pubDate>Sat, 26 Nov 2022 16:22:43 GMT</pubDate><media:content medium="image" url="https://img2.teletype.in/files/9f/95/9f95daa0-fc4d-43a0-9ed5-5a66a352319a.png"></media:content><description><![CDATA[<img src="https://img2.teletype.in/files/5b/7b/5b7b3dcd-77f8-445e-8f4f-23c8e3835e25.jpeg"></img>Раньше новости почти полностью относились к вещательным и печатным источникам новостей, но теперь примерно 62% пользователей получают новости из социальных сетей и других источников новостей в Интернете.]]></description><content:encoded><![CDATA[
  <figure id="eGcp" class="m_original">
    <img src="https://img2.teletype.in/files/5b/7b/5b7b3dcd-77f8-445e-8f4f-23c8e3835e25.jpeg" width="1280" />
    <figcaption>Пузырь </figcaption>
  </figure>
  <p id="4M28">Раньше новости почти полностью относились к вещательным и печатным источникам новостей, но теперь примерно 62% пользователей получают новости из социальных сетей и других источников новостей в Интернете.</p>
  <p id="ciCT">Многие люди принимают все, происходящее в интернете, за реальную картину мира. Однако алгоритмы поисковых сетей настроены таким образом, что создают «информационный пузырь» вокруг каждого пользователя. Как это делается? Очень просто.</p>
  <p id="Y9Jl">Браузер анализирует предпочтения и личные данные человека и выдает ему соответствующие рекомендации. Например, подсовывает, как кажется системе, интересные человеку видеоролики, статьи или посты в соцсетях.</p>
  <p id="5S2o">Каждый «лайк» и комментарий анализируется и вносится в алгоритм. С очередным обновлением система корректирует информационную ленту с учетом предпочтений.</p>
  <p id="bkV4">Причем, если не ставить лайки и не писать комментарии, программа считывает время просмотра того или иного материала. Бывает, что одну инфу пролистываешь, а другую внимательно изучаешь, а что-то и вовсе скачиваешь или добавляешь в закладки.</p>
  <p id="oadY">Мир стремительно меняется и поток информации увеличивается с каждым днем. В каждой стране система агитации и пропаганды не всегда может своевременно справится с потоком информации и адекватно на него отреагировать.</p>
  <p id="m8qI">Любая государственная система – штука довольно неповоротливая и любая вещь проходит многочисленные этапы согласований. Поэтому зачастую люди не получают четкого ответа и ищут информацию в Сети. А там их ждут всезнающие алгоритмы поисковых сетей, которые подскажут что почитать/посмотреть/послушать.Каждый «лайк» и комментарий анализируется и вносится в алгоритм. С очередным обновлением система корректирует информационную ленту с учетом предпочтений.</p>
  <p id="vWdy"></p>
  <p id="P6x1">Следовательно для некоторых, этой банальной информации, я предоставлю решение выхода из &quot;матрицы&quot;.</p>
  <p id="3Vzb">Несколько дней назад я нашёл крайне амбициозный поисковик metaphor:</p>
  <p id="j5rk">https://metaphor.systems/</p>
  <p id="4Wld">Его ранжирование не основано на коммерции. Первые страницы что он выдаст вам по запросу, не проплачены и не выданы благодаря алгоритмам &quot;чтобы прочитал именно это&quot;. Он основан он на алгоритме &quot;выдать самое подходящее&quot; Вы сами можете сравнить ранжирование попробовав задать вопрос в Google, Yandex и затем в Metaphor. Например: Кто такой Сноуден?</p>
  <p id="3cE6"> Вполне вероятно, что Google и Yandex на первую строку выкинет вам википедию, в отличии от того же самого Metaphor. На первых строках нет банального wiki, а так же куча сайтов на первой строке с более подходящими ответами которые гугл почему-то не показывает. <br /></p>
  <p id="Mmka">Свободу искателям информации!</p>

]]></content:encoded></item><item><guid isPermaLink="true">https://teletype.in/@oregoleh/CKDu6PrjwZY</guid><link>https://teletype.in/@oregoleh/CKDu6PrjwZY?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=oregoleh</link><comments>https://teletype.in/@oregoleh/CKDu6PrjwZY?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=oregoleh#comments</comments><dc:creator>oregoleh</dc:creator><title>Как стать 1000 летним вампиром?</title><pubDate>Tue, 15 Nov 2022 16:40:32 GMT</pubDate><media:content medium="image" url="https://img1.teletype.in/files/05/77/0577b540-101e-462a-97a1-2fe2be0ce1d6.png"></media:content><description><![CDATA[<img src="https://img3.teletype.in/files/21/42/214216c4-ad82-4452-addd-6540af315cfe.jpeg"></img>Различный опыт развивает человека с разной скоростью. Вы можете всю жизнь работать на скучной работе и в 60 лет быть не намного круче среднего подростка. С другой стороны, у некоторых людей настолько разнообразный и богатый жизненный опыт, что к 30 годам они становятся такими же потрясающими, как 1000-летний вампир.]]></description><content:encoded><![CDATA[
  <figure id="KPoW" class="m_custom">
    <img src="https://img3.teletype.in/files/21/42/214216c4-ad82-4452-addd-6540af315cfe.jpeg" width="527.0913705583756" />
    <figcaption>Халдеи из романа &quot;Empire V&quot; В.Пелевина</figcaption>
  </figure>
  <p id="cJHX">Различный опыт развивает человека с разной скоростью. Вы можете всю жизнь работать на скучной работе и в 60 лет быть не намного круче среднего подростка. С другой стороны, у некоторых людей настолько разнообразный и богатый жизненный опыт, что к 30 годам они становятся такими же потрясающими, как 1000-летний вампир.</p>
  <p id="wxBV">Это напоминает мне о том, что можно провести свою жизнь с большей или меньшей эффективностью, иногда на порядки. Кроме того, хотя у нас нет реального продления жизни, нам важно содержание, а не время работы. Если вы можете изменить свои привычки так, чтобы успевать делать в 3 раза больше, это все равно, что втрое увеличить эффективную продолжительность жизни.</p>
  <p id="qZ9a">Так как же можно добиться 100-кратного ускорения и за 10 лет стать 1000-летним вампиром? Это абсурдно амбициозно, но мы можем попробовать:</p>
  <p id="Y0Oe">Делайте трудные вещи<br />Некоторые события способствуют вашему личностному развитию. Вы можете систематически накапливать их, чтобы как можно быстрее стать грозным.</p>
  <p id="PB98">Пол Грэм говорит, что многие из основателей, которых он видит (как глава YC), очень быстро становятся более потрясающими, поскольку их заставляет нужда. Это кажется правдоподобным и подтверждается другими источниками. По сути, &quot;научись плавать, прыгнув в глубокую воду&quot;; люди склонны выбирать легкий путь, который приводит к меньшему развитию, когда им предоставляется шанс, поэтому возможность отстраниться может быть полезной.</p>
  <p id="rGvu">Это был и опыт моего товарища. На его работе главный инженер заболел раком мозга, и его де-факто повысили до руководителя двух проектов, которые он затем выровнял, чтобы быть в состоянии выполнять. Поначалу это было довольно страшно, но теперь ему скучно и хочется чего-то еще, что бросило бы вызов. (добавление: сейчас ему совсем не скучно; у другой команды, которой он помогает, сумасшедшее время кризиса) Кажется, очень трудно просто делать лучше без такого принуждения; насколько я могу судить, он мог бы работать гораздо усерднее, чем сейчас, но силы воли, по сути, не существует, поэтому он этого не делает.</p>
  <p id="ltaE">В связи с этим, еще один парень добился больших результатов после службы в армии и попадания под действие слезоточивого газа в окопе, когда он был мокрым, холодным, измученным, лишенным сна и голодным, что заставило его пройти через такие испытания, о которых он и не думал. Очевидно, это в какой-то степени перекалибровало его представления о том, насколько хорошо он должен жить и насколько все тяжело, так что теперь он миллионер и просто супер.Privet)</p>
  <p id="cCjG">Так что механизм, стоящий за многим из этого, похоже, заключается в перекалибровке того, что кажется трудным, пугающим или выходящим за пределы вашей обычной сферы. Раньше я боялся телефонных звонков и таких странных вещей, как танцевать на улице в присутствии незнакомых людей, но теперь не так сильно; кажется, что я просто забыл, что это было страшно. В случае с телефоном было несколько случаев, когда у меня не было времени бояться, мне нужно было просто сделать дело. В случае с танцем, я делал это самостоятельно настолько, что это стало нормой, так что даже не возникало мысли о том, что люди увидят меня, потому что это не казалось странным.</p>
  <p id="FTE2">Так что, если связать это воедино, есть опыт, которому вы можете подвергнуть себя, чтобы заставить нормализоваться и акклиматизироваться к трудным вещам. Например, некоторые люди занимаются тем, что называют &quot;терапией отторжения&quot; или &quot;расширением зоны комфорта&quot;, по сути, выходят на улицу и специально делают неловкие или пугающие вещи, чтобы перекалибровать свою интуицию и научить свой мозг, что они не так уж и страшны.</p>
  <p id="Jm7d">Что касается неудач, то проекты по самосовершенствованию обычно терпят неудачу, если они требуют постоянного приложения силы воли. Это просто факт, что в таких случаях вы будете сбиваться с пути. Поэтому вы должны сделать так, чтобы сбиться с пути было невозможно. Вы должны сделать так, чтобы выпасть из вагона было страшнее, чем подняться на уровень выше и просто сделать это. Именно эта идея лежит в основе Beeminder, который забирает ваши деньги, если вы не делаете то, что обещали себе на прошлой неделе. (dont use Beeminder :) )</p>
  <p id="AuAZ">Я полагаю, что тезис всего этого заключается в том, что эти повышения уровня постоянны, поскольку они делают вас более похожим на 1000-летнего вампира, и вы не можете просто вернуться к своему старому скучному смертному. Если это правда, то вывод о том, что вы должны искать сложные вещи, кажется довольно интересным и важным.</p>
  <p id="piHC"><strong>                                                                        Широта опыта</strong><br /><br />Подумайте о 1000-летнем вампирах; они должны были делать все. Сражались в битвах, руководили армиями, строили великие произведения, были влюблены, были везде, наблюдали большинство аспектов человеческого опыта и вообще видели все.</p>
  <p id="fkQf">Вещи, которые вы можете делать, имеют резко убывающую отдачу; первые несколько раз, когда вы смотрите великие фильмы, приносят большую часть пользы, то же самое с видеоиграми, 4chan, большинством работ и большинством опыта в целом. Поэтому очень важно менять те вещи, которые вы делаете часто, чтобы оставаться в той острой, первоначально растущей части кривой обучения. Вы можете получить 90% опыта вампира, затратив 10% его времени, если сосредоточитесь на наиболее познавательных частях каждого опыта.</p>
  <p id="fYLn"><br />Таким образом, помимо выполнения сложных заданий, которые повышают ваш уровень, вы можете добиться больших успехов, выполняя множество заданий и меняя их, как только вам надоест (что, надеюсь, будет выверено в соответствии с вашим уровнем сложности).</p>
  <p id="1i8F">В начале арабской революции в Ливии один американский студент взял летний отпуск в колледже, чтобы участвовать в революции. Уверен, он многому научился. Если бы вы могли сделать достаточно таких вещей, вы бы уже были на пути к тому, чтобы соответствовать вампиру.</p>
  <p id="KtSH">Это на самом деле идет рука об руку с выполнением трудных дел; когда вы не чувствуете вызова (вы находитесь на плоской части этой кривой опыта), вероятно, лучше всего броситься с головой в какой-нибудь новый проект, и потому что он новый, и потому что он трудный.</p>
  <p id="1AY9">Переключение часто имеет дополнительное преимущество в нормализации стратегических изменений и тренировке мыслей типа &quot;что я должен делать&quot;, что не повредит, если вы намерены действительно делать полезные вещи в своей жизни.</p>
  <p id="CPUV">Вероятно, есть много случаев, когда полное переключение не является оптимальным. Например, вы не станете экспертом в Х, если переключитесь с Х сразу после того, как узнаете основы. Возможно, вы хотите часто переключаться на побочные вещи, но глубоко погрузиться в X. Или же вы, вероятно, хотите время от времени переключаться на X, возможно, посмотреть на вещи с другой точки зрения, решить другую проблему или что-то в этом роде. This is есть теория преднамеренной практики в экспертизе.</p>
  <p id="1NK0">Не забывайте о форме кривой опыта. Как только вы начинаете чувствовать, что она выравнивается, найдите способ сделать ее снова свежей.</p>
  <p id="E83P"><strong>                                                         Делайте вещи быстро<br /></strong><br />Другой важный аспект этой идеи заключается в том, что каждый час - это возможность, и вы хотите использовать ее наилучшим образом. Это кажется совершенно очевидным, но я понял это гораздо лучше, подумав о том, как стать 1000-летним вампиром.</p>
  <p id="hsKZ">Большой пример - промедление. У меня есть много дел, которые уже долгое время висят в моем списке дел, по сути, угнетая меня своим присутствием. Я не могу расслабиться и заняться новыми делами, пока в моем списке все еще остается одно дурацкое дело. Ключевой момент заключается в том, что если вы обрабатываете дела в списке дел сейчас, вместо того чтобы халтурить и делать их позже, вы убираете их с дороги и можете заняться чем-то другим позже, и таким образом быстрее становитесь вампиром.</p>
  <p id="SUx7">Поэтому мы с другом немного углубились в эту тему и начали замечать эти альтернативные издержки, и действительно стали выполнять дела быстрее. Я уверен, что это еще не все; мы еще не достигли оптимального уровня в &quot;Делать это сейчас&quot;, так что, возможно, стоит поразмышлять над этим еще.</p>
  <p id="Cz2Q">В качестве конкретного примера: я пишу сегодня, потому что понял, что мне нужно просто убрать все свои писательские идеи с дороги, чтобы освободить место для еще большего великолепия.</p>
  <p id="UhOR">Обратная сторона этой идеи заключается в том, что многие вещи являются пустой тратой времени, в том смысле, что они просто сжигают время жизни и ничего вам не дают, или даже ослабляют вас. Следовательно для того, чтобы не терять времени анализируйте с разных сторон то, за что собираетесь браться.</p>
  <p id="IFVl">Такие вредные привычки, как чтение всякой ерунды в Интернете (серфинг), просмотр телевизора, порнографии, видеоигры, недосыпание и так далее, - это очевидные потери. Это очень трудно усвоить, но концепция 1000-летнего вампира помогла мне осознать величину затрат. Хотите ли вы проснуться в 30 лет и понять, что потратили свою молодость на бессмысленное дерьмо, или вы хотите оторвать свою задницу и написать то, что вы хотели написать прямо сейчас, и стать чертовым вампиром через 10 лет?</p>
  <p id="f1Gg">Но дело не только во вредных привычках; многое зависит от вашего более широкого положения в жизни, которое заставляет или не заставляет вас тратить время. Например, повторяющаяся работа за зарплату, которая не бросает вам вызов, - это просто торговля огромным куском своей жизни за не очень большие деньги. Конечно, иногда приходится работать, но вы должны понимать, что отдать половину своей жизни - это довольно грубая сделка, которой следует избегать. Вы даже не получаете ничего за проезд на работу и работу по дому. Поймите одну вещь: многим людям платят гроши за то, что они отдают в рабство себя и свое время . Поставьте себе цель выбраться из порочного круга и сделать так, чтобы вам платили не за ваше время, а за ваши навыки. Стремитесь к тому, чтобы ваша минута стоила намного больше, чем зарплата сотрудников KFC в месяц. Вы должны стать уникальным во многих вещах, придерживаться своей идеологии и уметь делать что-то крутое, что сможет сделать небольшое количество людей. Чем полезнее и профессиональнее ваши навыки, тем дороже вы сможете продать минуту своего времени.</p>
  <blockquote id="3jif">У меня 168 часов в неделю, из которых только 110 можно использовать (сон), а если учесть все домашние дела, работу за зарплату, вредные привычки и промедление, то я, вероятно, живу только 30 часов в неделю. Это полный бред; три четверти моей жизни выброшены на ветер. Я мог бы прожить в четыре раза больше, если бы смог избавиться от этих вещей.</blockquote>
  <p id="LnFI">Так что это просто концепция альтернативных затрат времени, облеченная в более рельефную форму. Базовые экономические концепции кажутся очень ценными в этом смысле.</p>
  <p id="io9E">Сделай это сейчас, чтобы потом заняться чем-то другим. Избегайте дерьмовой работы.<br /><br />                                           <strong>Социальная среда и стимуляция</strong><br /><br />Я замечаю, что я наиболее оживлен и выполняю свою лучшую интеллектуальную работу, когда общаюсь с другими людьми, которые умны и заинтересованы в глубоких технических беседах. <br /><br /><em><u>(Скоро откроются двери в наш будущий SPACE на квартире)<br /><br /></u></em>Другие вещи, такие как определенные модели давления времени, создают этот эффект, когда я работаю во много раз интенсивнее и эффективнее, чем в противном случае. Отличным примером являются технические экзамены; я могу быстро ответить на сотни технических вопросов.</p>
  <p id="jrm1">Кажется, что это хорошая идея - вызвать это состояние, когда вы более живы (это состояние &quot;потока&quot;?), если вы хотите прожить больше жизни. Также кажется вполне возможным делать это чаще, общаясь с правильными людьми и подвергая себя правильным условиям работы и тому подобное.</p>
  <p id="lnjz">Одна вещь, которая всплывает, это то, что это довольно истощает, в том смысле, что я иногда чувствую себя измотанным и не могу многого добиться после дня более интенсивной работы. Так ли это на самом деле? Возможно. Тем не менее, я не приблизился к пределу, даже учитывая необходимость отдыха, в целом.</p>
  <p id="kV12">Я должен провести исследование, чтобы узнать об этом больше. Если это связано с &quot;потоком&quot;, то было много исследований, AFAIK.</p>
  <p id="4Y8h">Мне также следует поторопиться и переехать в страну, где есть подходящее интеллектуальное сообщество, которое будет стимулировать меня гораздо лучше, чем та скудная группа мозгов, которую я смог собрать на данный момент после отлетов моих старых друзей в Европу после войны. Тех, с кем были идеально сплетены языки. Хотя, я нахожусь в поиске мозгов в этой стране до сих пор. Возможно, что в ближайшее время у меня все таки получится создать сообщество вампиров в России.</p>
  <p id="HxZa">Другое преимущество хорошего интеллектуального сообщества в том, что оно может стимулировать делать более крутые вещи. Когда все ваши друзья открывают компании или занимаются чем-то другим, сидеть на диване кажется очень плохой идеей.</p>
  <p id="32GM">Поэтому, если мы хотим прожить больше жизни, найти больше способов войти в состояние стимулированного потока кажется разумным решением, будь то создание условий для этого в ваших рабочих привычках, помещение себя в более сложную социальную и интеллектуальную среду или что-то еще.</p>
  <p id="QE01">                                                        <strong>Суммирование<br /></strong><br />Итак, как быстро мы можем достичь общего результата, если будем делать все это?</p>
  <p id="kzBQ">Если стремиться к получению нового опыта, чтобы продолжать учиться, я думаю, можно добиться 10-кратного ускорения по сравнению с тем, что вы можете делать по умолчанию. Очевидно, что это может быть больше или меньше, в зависимости от обстоятельств и вещей, которые вы не предскажете.</p>
  <p id="9K8L">Кроме того, мне кажется, что я могу сделать в 4 раза больше, если буду поддерживать привычку делать это сейчас и избегать некачественной работы. Как это сделать, я пока не знаю, но это возможно.</p>
  <p id="0CSi">Я не знаю, как оценить реальный выигрыш от стимулирующей среды. Кажется, что он может быть действительно очень высоким, или просто еще один прирост эффективности, в зависимости от того, как это происходит. Допустим, в дополнение ко всему прочему, мы можем реально подтолкнуть себя в 2 или 3 раза сильнее за счет социальных и экологических эффектов.</p>
  <p id="jaAN">Делать трудные вещи кажется огромной задачей, но в то же время она связана с тем, что мы уже учли, делая новые вещи. Значит, явно помнить о необходимости делать трудные вещи в дополнение к этому? Может быть, в 5 раз? Это опять же будет сильно варьироваться в зависимости от того, какие возможности вы сможете найти, и от неизвестных факторов, но 5x кажется достаточно безопасным, учитывая смертный уровень изобретательности и силы воли.</p>
  <p id="LAd0">Итак, все вместе: тот, кто:</p>
  <ol id="9fCV">
    <li id="dvTk"><em><u>Часто задумывается о том, на каком этапе кривой опыта он находится, и принимает соответствующие меры,</u></em></li>
    <li id="4tCX"><em><u>Поддерживает привычку делать что-то сейчас и визуализирует эти альтернативные затраты,</u></em></li>
    <li id="cttM"><em><u>Помещает себя в стимулирующую среду, такую как интеллектуальное сообщество , и окружает себя стимулирующими людьми и событиями,</u></em></li>
    <li id="OSOS"><em><u>Стремится получить самый тяжелый опыт для становления характера, например, попасть под действие слезоточивого газа в окопе или построить компанию с нуля </u></em>                                                                                                  </li>
  </ol>
  <p id="DmcY">Может получить 500-кратное ускорение и прожить 1000 нормальных лет за 2. Это кажется довольно диким, но ни одна из этих вещей не является чем-то необычным, и такие люди, как Илон Маск или Элиэзер Юдковски, похоже, делают примерно на такую же величину больше, чем среднестатистический.... (Внимание! Русский M@T)</p>
  <p id="Sk0d">Возможно, они не так легко ускоряются, или есть какая-то другая загвоздка, но цель кажется достижимой, и эти вещи помогут. С другой стороны, они почти наверняка самоподкрепляются ; 1000-летний вампир овладел бы искусством проживать жизнь со все более высокой эффективностью.</p>
  <p id="iP6d">Это, кажется, согласуется с тем, что все эти вещи распределены по закону мощности, что, конечно, затрудняет их обобщение одним числом, таким как 500.</p>
  <p id="cO0F">Последний вопрос, конечно, заключается в том, какого реального ускорения мы можем ожидать от вас или от меня в результате прочтения этой статьи. Получение более чем 2-3-кратного ускорения от низкоуровневого понимания или прочтения статьи в блоге кажется просто поразительным, не говоря уже о 500-кратном. Но, тем не менее, законы силы имеют место. <br /><br />Вероятно, у вас будет огромная отдача от того, что вы отнесетесь к этой идее серьезно.<br /><br />#Parkinson<br />#Бункер</p>

]]></content:encoded></item><item><guid isPermaLink="true">https://teletype.in/@oregoleh/m1VvZmx_xKP</guid><link>https://teletype.in/@oregoleh/m1VvZmx_xKP?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=oregoleh</link><comments>https://teletype.in/@oregoleh/m1VvZmx_xKP?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=oregoleh#comments</comments><dc:creator>oregoleh</dc:creator><title>Как развернуть смарт-контракт на один и тот же адрес в разных блокчейнах?</title><pubDate>Fri, 11 Nov 2022 11:03:17 GMT</pubDate><description><![CDATA[Вы когда-нибудь развертывали смарт-контракт и замечали развернутый адрес? Кажется, что это набор случайных символов, и хотя это так, этот адрес является детерминированным.]]></description><content:encoded><![CDATA[
  <p id="mFTq">Вы когда-нибудь развертывали смарт-контракт и замечали развернутый адрес? Кажется, что это набор случайных символов, и хотя это так, этот адрес является детерминированным.</p>
  <p id="DCJg">Краткий обзор учетной записи и адреса в Ethereum:</p>
  <p id="IRHO">В Ethereum существует два типа учетных записей: внешняя учетная запись (EOA) и контрактная учетная запись. Оба типа учетных записей имеют связанный с ними адрес. Адрес в Ethereum — это 42-символьный шестнадцатеричный адрес.</p>
  <p id="NTmK">Например, адрес смарт-контракта UniswapV3Factory Uniswap — 0x1F98431c8aD98523631AE4a59f267346ea31F984 , и он одинаков в основной сети Ethereum, Polygon, Optimism, Arbitrum и Avalanche. То же самое относится ко всем смарт-контрактам Uniswap.</p>
  <p id="zTGy">Как генерируется адрес смарт-контракта?</p>
  <p id="7zy2">Адрес смарт-контракта получается из двух значений: адреса пользователя EOA и количества транзакций, отправленных пользователем. Это адрес кошелька пользователя и одноразовый номер.</p>
  <p id="8odz">Учебник по Nonce. Проще говоря, Nonce — это количество транзакций, которые пользователь совершил в данной цепочке блоков. Каждый раз, когда у пользователя есть исходящая транзакция, одноразовый номер увеличивается на единицу. Одноразовый номер уникален для каждого блокчейна, а это означает, что отправка транзакции в Ethereum увеличит одноразовый номер учетной записи в Ethereum, но не в Polygon.</p>
  <p id="oRaF">Обратите внимание, что мы имеем в виду одноразовый номер учетной записи, относящийся к пользователю, а не одноразовый номер блока.</p>
  <p id="sOIK">Как я упоминал в начале статьи, адрес смарт-контракта является детерминированным. Мы можем определить адрес до фактического развертывания смарт-контракта, используя адрес кошелька, с которого пользователь будет развертывать контракт, и их самый последний одноразовый номер + 1.</p>
  <p id="fq0U">Ниже приведен пример кода, использующего ether.js для вычисления адреса перед развертыванием. Проверьте вывод</p>
  <p id="b6eh"><br />const walletAddress = &quot;0xBf7504799c6ED34dbC7D3077e3198f1F5D2B1306&quot;;    const nonce = 0;    let deployedAddress = ethers.utils.getAddress(ethers.utils.getContractAddress({from: walletAddress, nonce}));    console.log(deployedAddress);     //Console will print 0x488f7dab2688771f8d8308b2e65a0977d1b06e51 //verify via Polyscan https://mumbai.polygonscan.com/tx/0x84760a4617c32d2acd90c2c9baf465abbb72a64e26420585a0eca299eea9efef</p>
  <p id="StOi">Наконец, чтобы ответить на вопрос: «Как развернуть смарт-контракт на один и тот же адрес в разных блокчейнах?» ——&gt;——&gt;——&gt;</p>
  <p id="idgI">В нашем кошельке я использую Metamask, мы должны сохранить учетную запись, назовем ее учетной записью развертывания, только для развертывания смарт-контрактов. Мы не должны совершать в нем никаких транзакций, кроме создания смарт-контракта. Отправка транзакций создания смарт-контрактов во всех блокчейнах с одним и тем же одноразовым номером приведет к тому, что везде будет использоваться один и тот же адрес смарт-контракта.</p>
  <p id="Ikxl">Тот же адрес делает смарт-контракт более удобным для разработчиков. Это уменьшает трение при поддержании адресов для разных окружений (основная сеть и тестовая сеть) и блокчейнов (Эфириум, Полигон и т. д.). Это также упрощает социализацию запуска.</p>

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