Solidity

憤怒中的 Solidity 不可變等價物

  • August 3, 2022

在 Huff 語言中,我可以使用constant關鍵字指定一個常量變數。(怒氣沖衝的文件)

#define constant NUM = 0x420
#define constant HELLO_WORLD = 0x48656c6c6f2c20576f726c6421
#define constant FREE_STORAGE = FREE_STORAGE_POINTER()

我將如何設置在建構子中定義的類似solidity 的不可變變數?

uint256 internal immutable myVal;

不幸的是,Huff 沒有內置的不可變變數實現,儘管核心團隊正在考慮是否應該實現它(這樣的特性的熊案例是它會違背 Huff 保持盡可能低級別的最初目標添加進一步的抽象)。

您仍然可以自己實現不可變變數,但在添加功能之前,您需要手動完成。

不可變對象基本上只是附加到合約字節碼末尾的數據片段。Solidity 編譯器不會在您需要時從狀態中讀取數據,而是只會codecopy為您節省大量氣體。

您可以使用 foundry-huff 的deploy_with_args函式將數據附加到 Huff 合約字節碼的末尾。完成後,您可以通過執行以下操作從合約字節碼中讀取數據。請注意,此範例假定您的數據長度為 32 個字節,並且您將其儲存在記憶體中的位置 0 處。

0x20               // 32, represents size of data
dup1 codesize sub  // offset of data in bytecode
0x00               // offset in memory
codecopy           // copy the data

概括

你不能在 huff 中使用like 關鍵字,相反,你的框架或工具應該在執行時immutable換掉你的變數。constant您可以使用像 Foundry 這樣的框架或使用 huff 編譯器來完成它。

鑄造範例

在憤怒的AddressGetter契約中:

#define constant MY_ADDRESS = 0x0000000000000000000000000000000000000000

在您的可靠性腳本/測試中

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.15;

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

contract AddressGetterTest is Test {
 AddressGetter public addressGetter;

 function setUp() public {
   address addressToSwapIn = 0x514910771af9ca656af840dff83e8264ecf986ca;

   addressGetter = AddressGetter(HuffDeployer.config().with_addr_constant("MY_ADDRESS", addressToSwapIn).deploy("AddressGetter"))
 }
}

interface AddressGetter {
   function getAddress() external view returns (address);
}

赫夫克

huffc AddressGetter --constants <CONSTANTS>...

更多關於不可變的資訊。

詳細解答

Huff 不支持immutable,因為它有點高級抽象。他們堅定地這樣

…在合約創建期間,為不可變的值保留了一個專用的記憶體區域。然後,建構子程式碼可以將不可變對象的預期值儲存在該記憶體區域中。在建構子之後執行並返回合約執行時程式碼的創建程式碼的編譯器生成部分將讀回不可變對象的值並將它們插入到執行時字節碼中的所有實例中。

solidity 中的不可變變數儲存在合約的執行時字節碼中,但是它們的值在編譯時是未知的。PUSH32 <value>為了解決這個問題,solidity 編譯器添加了佔位符,這些佔位符在合約的建構子中定義的不可變項被替換。然後在建構子中更改執行時字節碼,在執行時填充這些佔位符。這與變數的行為有很大不同,constant變數在編譯時具有已知值,並且可以在部署之前直接內聯。

因此,huff 選擇的是在編譯時間之前使用添加到編譯器的參數交換常量。

引用自:https://ethereum.stackexchange.com/questions/132944