# Представляем: Yul+, новый низкоуровневый язык для Ethereum

By [klif](https://paragraph.com/@klifentro) · 2022-11-30

---

> Сегодня Fuel Labs представляет Yul+, добавляет различные функции QoL к Yul, низкоуровневому промежуточному языку для виртуальной машины Ethereum (EVM).

Yul — невероятно маленький язык, написанный разработчиками Solidity в качестве цели компиляции для дальнейшей оптимизации. У него упрощенная и функциональная низкоуровневая грамматика. Это позволяет разработчику приблизиться к необработанной EVM, чем Solidity, и вместе с этим обещает значительно улучшить использование газа.

[Компания Fuel Labs](https://github.com/fuellabs) реализовала свой первоначальный контракт optimistic rollup на открытом бета-тестирования с основой Yul+, но мы заметили, что с добавлением даже небольшого количества базовых языковых дополнений, наш код может стать более разборчивым и эффективным.

> Yul+ можно рассматривать как экспериментальное обновление для Yul, и Yul может попытаться интегрировать некоторые из его функций позже.

Некоторые основы Yul
--------------------

**Базовый контракт Yul с конструктором и выполнением по времени:**

    object "EmptyContract" {
      code {
    
        // Your constructor code
    
        datacopy(0, dataoffset("Runtime"), datasize("Runtime"))
        return(0, datasize("Runtime"))
      }
      object "Runtime" {
        code {
    
           // Your runtime code
    
        }
      }
    }
    

**Обработка вызова данных:**

    // copy calldata to memory
    // this copies 36 bytes of transaction calldata to memory position 0
    
    calldatacopy(0, 0, 36)
    

**Управление памятью:**

    // store and read memory
    // store 0xaa at memory position 100
    
    mstore(100, 0xaa)
    
    // load 32 byte chunk from memory position 100 and assign to someVar
    
    let someVar := mload(100)
    

**Хеширование:**

    // hash memory position 0 to 0+32, assign result to someHash
    
    let someHash := keccak256(0, 32)
    

**Хранилище состояния:**

    // store value 0xaa in state storage slot 3
    
    sstore(3, 0xaa)
    
    // get value from state storage 3 and assign to someVar
    
    let someVar := sload(3)
    

**Функции, условия, циклы и переключатели:**

    // Functions and conditions
    
    function someMethod(someVar, someOther) -> someResult {
       if eq(someVar, someOther) {
          someResult := 0x45
       }
    }
    
    // Loops
    
    for { let i := 0 } lt(i, 100) { i := add(i, 1) } {
       // some loop code
    }
    
    // Switches
    
    switch someVar
    case 0 {
       // when someVar == 0
    }
    
    case 1 {
       // when someVar == 1
    }
    
    default {
       // default
    }
    

Особенности Yul+
----------------

*   _Все существующие функции языка Yul;_
    
*   Перечисления (**enum**);
    
*   Константы (**const**);
    
*   Генерация стандартной подписи ABI Ethereum (**функция sig**);
    
*   Логические значения (**истина**, **ложь**);
    
*   Безопасная математика по умолчанию (т. е. защита от переполнения/недостатка потока для сложения, вычитания, умножения);
    
*   Внедряемые методы (**mslice** и **require**);
    
*   Структуры памяти (**mstruct**);
    

### Применение:

**Перечисления, константы и логические значения:**

    enum Colors (
       Red, // 0
       Blue, // 1
       Green // 2
    )
    
    // Constant someConst will equal 1
    
    const someColor := Colors.Blue
    
    // Constant someBool will equal 0x1
    
    const someBool := true
    

**Генерация стандартного ABI-подписи на Ethereum для методов sigs и тем:**

    // someVar will equal 4 byte method signature 0x6057361d
    
    let someVar := sig”function store(uint256 val)”
    
    // someTopic will equal 32 byte topic hash 0x69404ebde4a368ae324ed310becfefc3edfe9e5ebca74464e37ffffd8309a3c1
    
    let someTopic := topic”event Store(uint256 val)”
    

**Все математические операции теперь безопасны по умолчанию, при желании можно отключить в компиляторе:**

    let someVar := add(3, sub(4, 2))
    
    // will compile to this, with safeAdd, safeSub methods injected
    
    let someVar := safeAdd(3, safeSub(4, 2))
    

**Добавляем для удобства часть памяти _mslice_ и _требуем,_ если правда:**

    mstore(300, 0xaabbccdd) // note, mstore left pads zeros by 28 bytes
    
    let someVal := mslice(328, 3) // will return 0xaabbcc
    
    require(gt(someVal, 0)) // someVal > 0 or revert(0, 0) nicely
    

Наконец, мы включаем структуры памяти. Они используются для описания уже существующих структур в памяти, таких как вызов данных, хэш-данные или любые данные со структурой, записанные в память.

Он предлагает широкий спектр функций позиционирования, смещения, хэширования, индексирования и организации для лучшего управления памятью с помощью аккуратных и эффективных готовых функций, внедряемых по запросу. Мы по-прежнему продолжаем использовать функциональную нотацию внедряемых функций, которая не нарушает существующий стиль грамматики Yul.

    // Let’s assume we assign some calldata to memory position 0
    
    // this describes an abstract memory construction:
    
    mstruct SomeCalldata(
       signature: 4,
       value: 32,
    )
    
    let methodSig := SomeCalldata.signature(0) // slices out sig
    let someVal := SomeCalldata.value(0) // slices out value
    
    // we also get some nice indexing and offset features
    
    SomeCalldata.value.position(0) // equals 4 (i.e. 0 + 4)
    
    // Index ordering values as well
    
    SomeCalldata.signature.index() // equals 0
    
    SomeCalldata.value.index() // equal 1
    
    // Keccak hashing
    
    SomeCalldata.value.keccak256(0) // equals 32 byte hash of value
    
    // Calculate entire size of calldata structure
    
    SomeCalldata.size(0) // equals 36 (i.e. 4 + 32)
    

### Пример: Контракт SimpleStore на Yul+

    object “SimpleStore” {
       code {
          datacopy(0, dataoffset(“Runtime”), datasize(“Runtime”))
          return(0, datasize(“Runtime”))
       }
       object “Runtime” {
          code {
             calldatacopy(0, 0, 36) // copy calldata into memory
    
             mstruct Calldata( // mstruct describes calldata
                sig: 4,
                val: 32
             )
    
             switch Calldata.sig(0) // get signature at positive zero
    
             case sig”function store(uint256 val)” { // store method
                sstore(0, Calldata.val(0))
             }
    
             case sig”function get() returns (uint256)” { // get method
                mstore(100, sload(0))
    
                return (100, 32)
             }
          }
       }
    }
    

### Попробуйте сейчас в своем браузере!

[Yul+ - Low-Level Ethereum DevepmentFuel is a trustless scalable Ethereum side-chain implimentation which can quadratically scale to 2 million TPS.yulp.fuel.sh](https://yulp.fuel.sh/)

Подведение итогов
-----------------

В заключение, команда Fuel Labs надеется расширить возможности виртуальной машины Ethereum, создав более низкоуровневые альтернативы, которые мы используем каждый день для создания высокопроизводительной optimistic rollup для масштабирования экосистемы.

> А пока, чтобы получить дополнительную информацию и быть в курсе наших работ:

[Сайт](https://fuel.sh/) | [Twitter](https://twitter.com/FuelLabs_) | [GitHub](https://github.com/FuelLabs/yulp) | [Gitcoin](https://gitcoin.co/grants/199/fuel-labs)

---

*Originally published on [klif](https://paragraph.com/@klifentro/yul-ethereum)*
