【Solidity Yul Assembly】1.1 | Types

  • 0xE
  • 更新于 2024-09-13 11:47
  • 阅读 564

在 Yul 中没有多种类型的概念,或者说只有一种类型——u256,也可以理解为 bytes32。

这是我在登链的第一篇文章,未来我准备把一些之前学习过程中记录的笔记,慢慢的整理发布出来。我不喜欢写同质化的文章,未来我会尽量发布些市面上缺少的内容,并且即使是同一个主题,也尽量会加入自己的一些想法。

刨根问底探链上真相,品味坎坷悟Web3人生。

在本系列文章中,我们将深入探讨 Solidity 的内联汇编(Yul)。你可能会问:“我学会 Solidity 不就能写大部分合约了吗?为什么还需要学习内联汇编?”的确,大部分合约的编写完全可以通过 Solidity 完成。但内联汇编是 Solidity 的一个重要补充,它让你更深入地理解底层操作和合约优化。

起初,我也曾对内联汇编感到困惑,尽管我曾尝试过,但很快就忘记了。中文资料少且零散,这使得学习内联汇编变得更加困难。后来,找到了 Jeffrey Scholz 较为系统的讲解 Yul 的课程,此系列文章为我当时的学习笔记整理而来。学习 Yul 让我对存储、内存、栈、合约调用以及 ABI 编码有了更深入的理解。

即使你未来可能不会直接编写内联汇编代码,但掌握这些知识对编写更高效的 Solidity 合约是非常有帮助的。希望这系列文章能帮助你更好地理解内联汇编的基础及其在合约中的应用。

好了,接下来开始 1.1 的内容:Types.

在 Yul 中没有多种类型的概念,或者说只有一种类型——u256,也可以理解为 bytes32。 首先,让我们看看如何在 Yul 中实现一个函数,以下是个简单的读函数:

function getNumber() external pure returns (uint256) {
    return 42;
}

在 Yul 中,这段代码可以这样写:

function getNumber() external pure returns (uint256) {
    uint256 x;

    assembly {
        x := 42
    }

    return x;
}

在 assembly 代码块中,就是我们的 Yul 代码,是没有分号结尾的。

接下来我们来看一个与字符串相关的例子:

function demoString() external pure returns (string memory){
    string memory myString = "";

    assembly {
        myString := "hello world"
    }

    return myString;
}

如果按照之前的例子,乍一看,似乎没有问题,但是这段代码是错误的,这是因为 string memory myString 是存储在内存中的,而 Yul 中的赋值语句 myString := "hello world" 是把一个字面量赋值给一个栈上的指针,这是不对的。如果你刚开始接触,可能不能理解,没事,先留个印象,学习到后面就理解了。

正确的写法如下:

function demoString() external pure returns (bytes32){
    bytes32 myString = "";

    assembly {
        myString := "hello world"
    }

    return myString;
}

这个函数返回的是 "hello world" 对应的 bytes32。值得注意的是,bytes32 总是存储在栈上。

如果我们想把这个 bytes32 转化为字符串,可以这样写:

function demoString() external pure returns (string memory){
    bytes32 myString = "";

    assembly {
        myString := "hello world"
    }

    return string(abi.encode(myString));
}

但如果字面量超过了 32 字节,编译器会报错。后续我们会探讨如何处理这种情况。

在 Yul 中,相同的数据会以 256 位(u256)形式存储,而 Solidity 则会根据不同的类型解释和操作,例如:

function representation() external pure returns(bool) {
    bool x;

    assembly {
        x := 1
    }
    return x;  // return true
}
function representation() external pure returns(address) {
    address x;

    assembly {
        x := 1
    }
    return x;  // return 0x0000000000000000000000000000000000000001
}

总结: Yul 中没有多种数据类型的概念,所有数据在栈上都是以 256 位(u256)形式存储的。不同于 Solidity 的丰富类型体系,Yul 只操作这一种基础类型。Solidity 则根据具体的上下文和定义,去解释这些数据。

关于作者 0xE: Twitter Telegram

点赞 1
收藏 1
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
0xE
0xE
0x59f6...a17e
17年进入币圈,做过FHE,联盟链,现在是智能合约开发者。 刨根问底探链上真相,品味坎坷悟Web3人生。