在竞争激烈的以太坊开发领域,每一 gas 单位都至关重要,Huff 是一种将智能合约优化推向极限的工具,因此脱颖而出。Huff 最初由 Aztec Protocol 团队开发,用于优化他们的 Weierstrudel 椭圆曲线库。Huff 是一种基于宏的低级语言,专为编写高效的 EVM 字节码而设计。它提供对 EVM 操作码的直接访问,使开发人员能够无与伦比地控制执行和性能。
然而,这种强大功能伴随着陡峭的学习曲线、极少的抽象和几乎没有内置的安全性。Huff 并不适合胆小的人 —— 它适用于那些愿意深入研究 EVM 内部结构以获得最大效率的开发人员。
这个分为三个部分的文章系列探讨了 Huff 的语法、优点和实际应用。在第 1 部分中,我们讨论:
transfer
和 SumArray 谜题之类的用例Huff 是一种 EVM 的特定领域语言,完全专注于 gas 效率。 它去除了高级的便利,暴露了以太坊执行环境的本质。
尽管 Huff 存在难度,但它在对性能至关重要的场景中表现出色:
Huff 的核心围绕以下内容构建:
常量使用 #define constant
将原始值注入到字节码中:
##define constant BALANCE_SLOT = 0x00
宏是构建逻辑的主要方式。它们显式定义输入 / 输出堆栈大小并使用原始操作码。
示例:安全加法
##define macro MATH__ADD() = takes(2) returns(1) {
// 堆栈:a, b
dup2 add
dup1 swap2 gt
[OVERFLOW_ERROR] jumpi
}
Huff 不使用 Solidity 风格的选择器。相反,你可以使用 calldataload
和 jumpi
手动路由函数:
##define macro MAIN() = takes(0) returns(0) {
0x00 calldataload
0xe0 shr
dup1 0xa9059cbb eq transfer jumpi
0x00 0x00 revert
}
让我们在纯 Huff 中构建一个简单的 transfer(address,uint256)
。
##define constant BALANCE_SLOT = 0x00
##define constant TRANSFER_SIGNATURE = 0xa9059cbb
##define constant TRANSFER_EVENT = 0xDDF252AD...
##define macro ADDRESS_MASK() = takes(1) returns(1) {
0x000000000000000000000000ffffffffffffffffffffffffffffffffffffffff and
}
##define macro TRANSFER_INIT() = takes(0) returns(6) {
0x04 calldataload ADDRESS_MASK() // recipient
caller // sender
[TRANSFER_EVENT] // event signature
0x20 0x00 // memory layout
0x24 calldataload // amount
}
##define macro TRANSFER_GIVE_TO() = takes(6) returns(7) {
dup6 0x00 mstore
0x40 0x00 sha3
dup1 sload
dup3 add
dup1 dup4 gt
swap2 sstore
}
##define macro TRANSFER_TAKE_FROM() = takes(7) returns(8) {
caller 0x00 mstore
0x40 0x00 sha3
dup1 sload
dup4 dup2 sub
dup5 swap3 sstore
lt
}
##define macro TRANSFER() = takes(0) returns(0) {
TRANSFER_INIT()
TRANSFER_GIVE_TO()
TRANSFER_TAKE_FROM()
callvalue or or throw_error jumpi
0x00 mstore log3
0x01 0x00 mstore
0x20 0x00 return
}
##define macro MAIN() = takes(0) returns(0) {
0x00 calldataload 0xe0 shr
dup1 [TRANSFER_SIGNATURE] eq transfer jumpi
0x00 0x00 revert
transfer:
TRANSFER()
throw_error:
0x00 0x00 revert
}
Transfer
事件SumArray 谜题从 calldata 中获取 uint256[]
并返回它们的总和。
##define macro SUM_ARRAY() = takes(0) returns(0) {
0x44 calldatasize sub
push0
push0
loopBegin:
dup3 dup2 0x20 mul lt iszero end jumpi
dup1 0x20 mul 0x44 add calldataload
dup3 add
swap2 pop
0x01 add
loopBegin jump
end:
pop
push0 mstore
0x20 push0 return
}
##define macro MAIN() = takes(0) returns(0) {
0x00 calldataload 0xe0 shr
dup1 0x1e2aea06 eq sumArray jumpi
0x00 0x00 revert
sumArray:
SUM_ARRAY()
}
.huff
文件huffc contracts/MyContract.huff --bytecode
forge script
部署在第 1 部分中,我们探讨了是什么让 Huff 成为一种独特而强大的语言,适用于专注于 Gas 优化的 EVM 开发人员。我们介绍了语法、宏系统和两个工作示例:ERC20.transfer()
和 SumArray
。
原文链接:https://medium.com/@ankitacode11/mastering-huff-building-gas-optimized-smart-contracts-from-scratch-part-1-6276104ccac5 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
登链社区是一个 Web3 开发者社区,通过构建高质量技术内容平台和线下空间,助力开发者成为更好的 Web3 Builder。
【免责声明】市场有风险,投资需谨慎。本文不构成投资建议,用户应考虑本文中的任何意见、观点或结论是否符合其特定状况。据此投资,责任自负。