探讨 Huff :对比Solidity、Yul和原始EVM能力——第二部分

本文是Huff技术深入探讨系列的第二部分,对比了Huff、Solidity和Yul的特性及gas消耗,并完成了ERC20合约的实现,包括approve、allowance和transferFrom宏。此外,文章还介绍了使用Foundry进行测试和部署的工作流程,并通过架构图展示了合约的结构组成。

引言

第 1 部分:精通 Huff:从零开始构建 Gas 优化的智能合约 中,我们探索了 Huff 的语法、结构和初始用例。现在,在 第 2 部分 中,我们将 Huff 与 SolidityYul 进行比较,完成我们的 ERC20 合约实现,并检查开发和测试工作流程。

Solidity vs. Yul vs. Huff

Gas 比较 (ERC20 transfer)

  • Solidity: ~22,000–25,000 gas
  • Yul: ~20,000–22,000 gas
  • Huff: ~21,000–22,000 gas (可能还有进一步优化)

完成 ERC20 合约

Approve Macro

##define constant APPROVAL_EVENT = 0x8C5BE1E5EBEC7D5BD14F71427D1E84F3DD0314C0F7B2291E5B200AC8C7C3B925
##define constant ALLOWANCE_SLOT = 0x03

##define macro APPROVE() = takes(0) returns(0) {
    UTILS__NOT_PAYABLE<throw_error>()
    0x04 calldataload ADDRESS_MASK()
    caller
    [APPROVAL_EVENT]
    0x20 0x00
    0x24 calldataload
    dup1
    caller 0x00 mstore
    [ALLOWANCE_SLOT] 0x20 mstore
    0x40 0x00 sha3
    0x20 mstore
    dup7 0x00 mstore
    0x40 0x00 sha3
    sstore
    0x00 mstore log3
    0x01 0x00 mstore
    0x20 0x00 return
}

Allowance Macro

##define macro ALLOWANCE() = takes(0) returns(0) {
    UTILS__NOT_PAYABLE<throw_error>()
    0x04 calldataload ADDRESS_MASK()
    0x00 mstore
    [ALLOWANCE_SLOT] 0x20 mstore
    0x40 0x00 sha3
    0x20 mstore
    0x24 calldataload ADDRESS_MASK()
    0x00 mstore
    0x40 0x00 sha3
    sload
    0x00 mstore
    0x20 0x00 return
}

TransferFrom Macros

Initialization Macro

##define macro TRANSFER_FROM_INIT() = takes(0) returns(6) {
    0x24 calldataload ADDRESS_MASK()
    0x04 calldataload ADDRESS_MASK()
    [TRANSFER_EVENT]
    0x20 0x00
    0x44 calldataload
}

Allowance Subtraction Macro

##define macro TRANSFER_SUB_ALLOWANCE() = takes(8) returns(9) {
    dup7 0x00 mstore
    [ALLOWANCE_SLOT] 0x20 mstore
    0x40 0x00 sha3
    0x20 mstore
    caller 0x00 mstore
    0x40 0x00 sha3
    dup1 sload
    dup5 dup2 sub
    dup6 swap3 sstore
    lt
}

Final TransferFrom Macro

##define macro TRANSFER_FROM() = takes(0) returns(0) {
    TRANSFER_FROM_INIT()
    TRANSFER_GIVE_TO()
    TRANSFER_TAKE_FROM<dup6>()
    TRANSFER_SUB_ALLOWANCE()
    callvalue or or or throw_error jumpi
    0x00 mstore log3
    0x01 0x00 mstore
    0x20 0x00 return
}

测试和部署

使用 Foundry 进行测试

import "foundry-huff/HuffDeployer.sol";
import "forge-std/Test.sol";

contract TestHuff is Test {
    function testTransfer() public {
        address token = HuffDeployer.deploy("ERC20");
        (bool success,) = token.call(abi.encodeWithSignature("transfer(address,uint256)", address(this), 100));
        assertTrue(success);
    }
}

Native Huff Testing

##include "TestHelpers.huff"

##define test TEST_TRANSFER() = {
    // 测试逻辑
}

Deployment Script

import "foundry-huff/HuffDeployer.sol";
import "forge-std/Script.sol";

contract Deploy is Script {
    function run() public returns (address) {
        return HuffDeployer.broadcast("ERC20");
    }
}

架构图

结论

在本系列的这一部分中,我们将 Huff 与 Solidity 和 Yul 进行了比较,实现了 approveallowancetransferFrom 宏,并介绍了使用 Foundry 的测试和部署工作流程。

🚀 继续第 3 部分

  • 原文链接: medium.com/@ankitacode11...
  • 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
ankitacode11
ankitacode11
江湖只有他的大名,没有他的介绍。