Yul+简介—一个以太坊的全新低级语言 (Introducing:Yul+ — A new low-level language for Ethereum)

Today, Fuel Labs introduces Yul+, which adds various QoL features to Yul, a low-level intermediate language for the Ethereum Virtual Machine.

今天,Fuel实验室推出了 Yul+,它为以太坊虚拟机的低级中继语言 Yul 添加了各种 QoL 功能。

Introducing: Yul+ — A new low-level language for Ethereum
Fuel Labs Inc. introduces Yul+ a new low-level language for Ethereum.
Fuel实验室为以太坊引入了一种新的低级语言 Yul+。


Yul is an incredible little language written by the Solidity Developers as a compilation target for further optimizations. It features a simplistic and functional low-level grammar. It allows the developer to get much closer to raw EVM than Solidity, and with that comes the promise to drastically improved gas usage.

Yul 是 Solidity 开发人员编写的一种难以置信的小语言,它也作为进一步优化的编译目标。它具有简单而实用的低级语法。与 Solidity 相比,它允许开发人员更接近原始 EVM,并承诺大幅改进 gas 使用。

Fuel Labs has implemented itsinitial open-beta optimistic rollup contract largely with Yul, but we noticed that with the addition of even a tiny number of basic language additions, our code could become more legible and efficient.

Fuel实验室 已在很大程度上,在 Yul 实施了其最初公开测试版的乐观汇总合约,但我们注意到,即使添加少量的基本语言,我们的代码也可能会变得更多清晰有效。

Yul+ can be looked at as an experimental upgrade to Yul, and Yul might aim to integrate some of its features natively at a later time.

Yul+ 可以看作是对 Yul 的实验性升级,以后Yul 可能会在本地集成它的一些功能。

一些 Yul 基础知识 (Some Yul Basics)

A basic Yul contract with a constructor and runtime

带有构造函数和运行时的基本 Yul 合约

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

Handling calldata 处理调用数据

// copy calldata to memory
// this copies 36 bytes of transaction calldata to memory position 0

calldatacopy(0, 0, 36)

Managing memory 管理内存

// 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)

Hashing 哈希化

// hash memory position 0 to 0+32, assign result to someHash

let someHash := keccak256(0, 32)

State storage 状态存储

// 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, conditions, loops, and switches

函数,条件,循环和开关语句

// 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+ Features)

  • All existing Yul language features
    所有现有的 Yul 语言功能

  • Enums (enum)
    枚举(enum

  • Constants (const)
    常量 (const)

  • Ethereum standard ABI signature generation (*sig”function …”)
    以太坊标准 ABI 签名生成(sig”function ...”

  • Booleans (truefalse)
    布尔值 (true, false)

  • Safe math by default (i.e. over/under flow protection for addition, subtraction, multiplication)
    默认情况下安全数学(即加法、减法、乘法的溢出/下溢保护)

  • Injected methods (mslice and require)
    注入方法(mslicerequire

  • Memory structures (mstruct)
    内存结构(mstruct

用法 (Usage)

Enums, constants, and Booleans

枚举,常量和布尔值

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

Ethereum standard ABI signature generation for method sigs and topics:

以太坊标准 ABI 签名生成(方法标志和主题)

// 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)”

All maths are now safe by default, which can be disabled in the compiler if desired.

现在默认情况下所有数学都是安全的,如果需要,可以在编译器中禁用它。

let someVar := add(3, sub(4, 2))

// will compile to this, with safeAdd, safeSub methods injected

let someVar := safeAdd(3, safeSub(4, 2))

We add for convenience a memory slice mslice and require if true

为方便起见,我们添加了一个内存切片,如果 mslicerequire 为真

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

Lastly, we enable memory structures. These are used to describe already-existing structures in memory, such as calldata, hash data, or any data with structure written to memory.

最后,我们启用内存结构。它用于描述内存中已经存在的结构,例如调用数据、哈希数据或任何具有写入内存的结构的数据。

It offers a wide range of positioning, offset, hashing, indexing, and organizational features to better handle memory with neat efficient pre-made functions injected on-demand. We still keep to using a functional notation of injected functions, which doesn’t break existing Yul grammer style.

它提供了广泛的定位、偏移、散列/哈希化、索引和组织功能,进而通过按需注入的简洁高效的预制功能来更好地处理内存。我们仍然继续使用注入函数的函数表示法,这不会破坏现有的 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)

案例:Yul+ SimpleStore合约 (Example: Yul+ SimpleStore Contract)

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)
         }
      }
   }
}

在您的浏览器上尝试它!(Try it Now in Your Browser!)

Yul+ - Low-Level Ethereum Devepment

Yul+ - 低级以太坊开发

Fuel is a trustless scalable Ethereum side-chain implimentation which can quadratically scale to 2 million TPS.

Fuel 是一种去信任的可扩展以太坊侧链实现,可以扩展至 200 万 TPS。

总结 (Wrapping Up)

In conclusion, the Fuel Labs team hopes to expand the possibilities for the Ethereum Virtual Machine by creating more low-level alternatives which we use everyday to build high-performance optimistic rollup scalability for the ecosystem.

总之,Fuel Labs 团队希望通过创建更多低级替代方案来扩展以太坊虚拟机的可能性,我们每天都使用这些替代方案,来为生态系统构建高性能的乐观汇总扩展。

In the meantime, for more info and to keep up to date with our work:

同时,想了解更多信息并及时了解我们的工作,欢迎访问:

Website: https://fuel.sh

Twitter: https://twitter.com/FuelLabs_

GitHub: https://github.com/FuelLabs/yulp

Gitcoin: https://gitcoin.co/grants/199/fuel-labs

赞赏