状態変数を同じ値に設定するためのガスコスト

Nov 20 2020

この仕様によれば、状態変数を同じ値に設定すると、200ガスが消費されます。

ただし、ガナッシュコアv2.10.2でテストを行ったところ、結果は800ガスに近くなりました。

堅実契約:

pragma solidity 0.6.12;

contract MyContract {
    uint256 public gasUsed;
    uint256 public storageSlot;
    function func(uint256 x) public {
        storageSlot = x;
        uint256 gasLeft = gasleft();
        storageSlot = x;
        gasUsed = gasLeft - gasleft();
    }
}

トリュフ5.xテスト:

const MyContract = artifacts.require("MyContract");

contract("MyContract", () => {
    it("test", async () => {
        const myContract = await MyContract.new();
        for (let x = 0; x < 10; x++) {
            await myContract.func(x);
            const gasUsed = await myContract.gasUsed();
            console.log(gasUsed.toString());
        }
    });
});

反復ごとに出力は816でgasleft()あり、契約関数の最後の行の操作に16ガスかかると仮定すると、同じ値を格納すると800ガスかかるように見えます。

仕様のガスコストは、SLOADが200ガスを消費していた古いEVMバージョン(以前のイスタンブールなど)に適用されると思われます。

現在のEVMバージョンではSLOADが800ガスに変更されているので、同じ値のSSTOREの場合も800ガスに変更された可能性があると思います。

誰かがこの不一致について何か考えを持っていますか?

回答

2 MrClottom Nov 20 2020 at 21:32

この不変のコストは、EIP-2200とEIP-1884によって提案されたSSTOREように800ガスに変更されました(これは何らかの理由でどこにも見つかりません)。下位互換性のために値があると思います。仕様を検索すると、との値が見つかります。新しいノードがすべてのトランザクションを同期して検証するときは、古いコンセンサスルールも理解できる必要があります。これが、ノードがそこに含まれている理由である可能性があります。個人的には、リファクタリングされていない古いコードである可能性もあります。私は、gethコードベースにあまり詳しくありません。200SloadGasEIP1884SloadGasEIP1884

将来的には、ガスコストなどの低レベルの詳細をチェックおよびデバッグするために、リミックスWebIDEをお勧めします。Remixには、私が知っている中で最高のデバッガーがあり、すべてのオペコードの実行を個別に実行できます。