Skip to main content

介绍, Yul+ - 以太坊的新低级语言

· 6 min read
fuel

今天,Fuel Labs 介绍了 Yul+,它为 Yul 增加了各种 QoL 功能,Yul 是 Ethereum 虚拟机的一种低级中间语言。

Fuel wiki Labs

Yul 是由 Solidity 开发者编写的一种不可思议的小众语言,作为进一步优化的编译目标。它的特点是一个简单而实用的低级语法。它允许开发者比 Solidity 更接近原始的 EVM,并由此带来了对 Gas 使用的大幅改善的承诺。

Fuel Labs 已经在很大程度上用 Yul 实现了其最初的开放性测试的 OP 合约,但我们注意到,即使增加极少的基本语言,我们的代码也会变得更加清晰和高效。

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 语言功能
  • 枚举
  • 常量
  • 以太坊标准 ABI 签名生成 ( sig"function …" )
  • 布尔值(真,假)
  • 默认情况下的安全数学(即加法、减法、乘法的溢出保护)
  • 注入的方法(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 签名生成方法 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)

示例:Yul+ SimpleStore 合约

  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 Devepment

总结

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