상태 변수를 동일한 값으로 설정하는 데 드는 가스 비용

Nov 20 2020

이 사양 에 따르면 상태 변수를 동일한 값으로 설정하면 200 가스가 소모됩니다.

그러나 ganache-core 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();
    }
}

Truffle 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 가스가 드는 것으로 보입니다.

사양의 가스 비용이 이전 EVM 버전 (이스탄불 이전 또는 이와 유사한 것)에 적용되는 것으로 의심됩니다. SLOAD는 200 가스 비용이 들었습니다.

현재 EVM 버전에서는 SLOAD가 800 가스로 변경되었으므로 같은 값의 SSTORE의 경우도 800 가스로 변경되었을 수 있다고 생각합니다.

이 불일치에 대해 아는 사람이 있습니까?

답변

2 MrClottom Nov 20 2020 at 21:32

변경되지 않는이 비용은 EIP-2200 및 EIP-1884에서 제안한대로 가스로 SSTORE변경되었습니다 (어딘가에서 찾을 수 없음). 이전 버전과의 호환성을 위해 값이 있다고 가정합니다 . 사양에서 검색하면 및 값을 찾을 수 있습니다. 새 노드가 모든 트랜잭션을 동기화하고 확인할 때 이전 합의 규칙을 이해할 수 있어야하므로 여기에 포함 된 것 같습니다. 개인적으로 리팩토링되지 않은 오래된 코드 일 수도 있습니다. 저는 geth 코드베이스에 너무 익숙하지 않습니다.800200SloadGasEIP1884SloadGasEIP1884

앞으로 가스 비용과 같은 낮은 수준의 세부 정보를 확인하고 디버깅하기 위해 remix 웹 IDE 를 권장합니다 . Remix에는 내가 아는 최고의 디버거가있어 모든 작업 코드를 개별적으로 실행할 수 있습니다.