https://docs.soliditylang.org/en/v0.8.21/080-breaking-changes.html
Solidity 0.8.0의 변경점에 대해 번역을 진행하고 Hardhat, Ethers.js, Typescript를 통해 이해하기 쉽도록 작성하였습니다.
컴파일러가 사용자에게 알리지 않고 기존 코드의 동작이 변경되는 변경사항이 나열되어 있습니다.
시리즈로 작성하겠습니다.
**unchecked{…}**
를 사용하면 이전 wapping 동작을 사용할 수 있습니다. Overflow 검사는 매우 일반적이므로 가스 비용이 약간 증가하더라도 코드의 가독성을 높이기 위해 기본값으로 설정했습니다.// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract Arithmetic {
function add(uint256 a, uint256 b) public pure returns (uint256) {
return a + b;
}
function subtract(uint256 a, uint256 b) public pure returns (uint256) {
return a - b;
}
function uncheckedAdd(uint256 a, uint256 b) public pure returns (uint256) {
unchecked {
return a + b;
}
}
function uncheckedSubtract(
uint256 a,
uint256 b
) public pure returns (uint256) {
unchecked {
return a - b;
}
}
}
Solidty 0.8.0 버전에서는 overflow, underflow 발생 시 revert됩니다.
describe('add', () => {
it('overflow로 인해 revert된다.', async () => {
const { Arithmetic } = await loadFixture(DeployContract);
await expect(Arithmetic.add(ethers.MaxUint256, ethers.MaxUint256)).to.be
.reverted;
});
});
describe('sub', () => {
it('underflow로 인해 revert된다.', async () => {
const { Arithmetic } = await loadFixture(DeployContract);
await expect(Arithmetic.subtract(0, 1)).to.be.reverted;
});
});
하지만 unchecked
키워드를 사용하면 이전 버전 처럼 동작하도록 할 수 있습니다.
describe('uncheckedAdd', () => {
it('uncheckedAdd', async () => {
// Wrapping behavior
const { Arithmetic } = await loadFixture(DeployContract);
const result = await Arithmetic.uncheckedAdd(ethers.MaxUint256, 2);
expect(result).to.equal(1);
});
});
describe('uncheckedSubtract', () => {
it('uncheckedSubtract', async () => {
// Wrapping behavior
const { Arithmetic } = await loadFixture(DeployContract);
const result = await Arithmetic.uncheckedSubtract(0, 1);
expect(result).to.equal(ethers.MaxUint256);
});
});
unchecked
키워드를 사용한 함수의 경우 이전처럼 underflow, overflow 발생 시 결과를 그대로 보여줍니다.