견고성의 메모리, CallData 및 스토리지 : 차이점 이해
:::경고
부인 성명:
- 이 기사의 코드는 교육 목적만을위한 것입니다.
:::
이해하기가 어렵다면 storage
,,, memory
또는 calldata
당신은 혼자가 아닙니다. 이것은 대부분의 초보자 개발자들이 파악하기 위해 고군분투하고 있으며, 경험이 풍부한 견고성 개발자조차도 여전히 완전히 이해하지 못합니다.
이 ‘특별한 단어’는 무엇입니까? 그들은 Solidity Smart 계약에서 주요 데이터 위치를 지정하는 단어입니다. Solidity의 데이터 위치는 데이터를 저장할 수있는 위치와 이더 리움 블록 체인에서 어떻게 액세스 할 수 있는지 설명합니다. 다른 데이터 위치에는 다음이 포함됩니다.
- 스택
- 암호
- 로그
이 기사에서는 각 주요 데이터 위치 옵션과 각각을 사용할 위치의 차이점을 학습합니다.
첫째, 스토리지 란 무엇입니까?
저장
스토리지는 스마트 계약의 상태 변수를 보유하는 데이터 위치입니다. 상태 변수는 블록 체인에 영구적으로 사는 데이터입니다. 각 스마트 계약에는 자체 저장 공간 (2^256 32 바이트 슬롯의 배열)이 있으며 상태 변수는 자동으로 할당됩니다. storage
.
아래 코드 스 니펫은 스토리지에 저장된 상태 변수의 간단한 구현과 그 getter 및 setter 기능을 보여줍니다. \ n
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.26;
contract Storage {
/////////////////////////////
// STATE VARIABLES //////////
/////////////////////////////
uint256 public s_storedData; // s_storedData is a storage variable, s_ denotes a storage variable
/////////////////////////////
// SETTER FUNCTION //////////
/////////////////////////////
function set(uint256 x) public {
s_storedData = x; // This value is saved permanently on-chain
}
/////////////////////////////
// GETTER FUNCTION //////////
/////////////////////////////
function getStoredData() public view returns(uint256) {
return s_storedData;
}
}
위의 코드에서s_storedData
set () 함수가 실행 된 후에 블록 체인에 남아 있습니다.
더 중요한 것은 Storage는 명시 적으로 지정되지 않은 주요 데이터 위치 옵션 중 하나입니다. 함수 외부에서 선언 된 모든 변수는 스토리지 변수로 암시 적으로 변환됩니다.
사용 사례
그만큼 Bank
위의 계약은 이름에서 알 수 있듯이 간단한 은행 역할을합니다. 그만큼 balances
매핑이 저장됩니다 storage
이는 기능 호출에 대한 값을 기억한다는 것을 의미합니다.
예를 들어, 앨리스가 전화하는 경우 deposit(100)
그녀의 균형은 저장됩니다 storage
에서 balances
매핑. 반대로, 그녀가 전화하면 withdraw(60)
그녀는 받는다 60
그리고 매핑 업데이트 40
.
메모리
스토리지와 달리 메모리는 임시 기능 스코프 데이터 위치입니다. 함수-스코프는 변수가 계약 수준이 아닌 함수 호출 중에 만 존재하며 이후에 지워집니다. 또한, memory
읽기 쓰기 액세스를 허용합니다. 이것은 변수가 함수 내에서 수정되었음을 의미합니다. Solidity는 함수 내부 (로컬 변수) 또는 표시된 매개 변수에 메모리를 할당합니다. memory
.
시연하려면 :
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.26;
contract Memory {
function multiply(uint256 a, uint256 b) public pure returns (uint256) {
uint256 result = a * b; // 'result' is stored in memory
return result; // 'result' does NOT persist after the function ends
}
}
위의 코드에서 견고성은 암시 적으로 저장합니다 result
기능 실행 후에도 지속되지 않는 메모리에서.
사용 사례
아래 코드는 두 개의 문자열 입력을 연결합니다. string memory first
,,, string memory second
함수 동안 존재합니다 combineStrings
실행.
함수 매개 변수에 대한 메모
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.26;
contract Memory {
function multiply(uint256 memory a, uint256 memory b) public pure returns (uint256) {
uint256 result = a * b;
return result;
}
}
함수 매개 변수의 경우 지정할 수 없습니다 memory
키워드 uint
,,, bool
,,, address
그리고 enum
계약의 스택에 직접 저장된 변수는 명시적인 키워드가 없습니다.
반면, 참조 유형은 strings
,,, bytes
,,, arrays
,,, structs
그리고 mapping
당신은 memory
내부 및 개인 기능의 경우 calldata
외부 및 공공 기능의 경우 (아래에 자세히 설명).
부름
이전 섹션에서 가볍게 다루었습니다. calldata
또 다른 임시 데이터 위치이지만 예약되어 있습니다 external
함수 매개 변수. 또한,와는 달리 memory
,,, calldata
수정할 수 없습니다. 이것이 의미하는 바를 설명하려면 아래 코드를 살펴 보겠습니다.
\
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.26;
contract Example {
function tryChangeCalldata(uint[] calldata nums) external pure returns (uint[] calldata) {
nums[0] = 999; // ❌ ERROR — "calldata is read-only"
return nums;
}
}
위의 오류 메시지는 CallData가 읽기 전용임을 보여줍니다. 수정합니다 calldata
변수는 먼저로드되어야합니다 memory
.
아래의 조정 된 코드는 지금 수정되었습니다. 아래 코드는 IT가로드되어 작동합니다. nums
변수 memory
그것을 수정하기 전에 if
차단하다.
\
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.26;
contract Example {
function tryChangeCalldata(uint[] calldata nums)
external
pure
returns (uint[] memory)
{
// Copy from calldata to memory
uint[] memory numsCopy = new uint[](nums.length);
for (uint i = 0; i < nums.length; i++) {
numsCopy[i] = nums[i];
}
// Now modify the copy
if (numsCopy.length > 0) {
numsCopy[0] = 999;
}
return numsCopy;
}
}
\
데이터 위치가 중요한 이유
적절한 데이터 위치를 사용하는 것은 계약이 저장, 액세스 및 데이터 지불 방식에 직접적인 영향을 미치므로 중요합니다. 차이는 스마트 계약의 비용, 행동 및 보안에 큰 영향을 줄 수 있습니다. 방법은 다음과 같습니다.
가스 비용
- 스토리지에 데이터를 작성하는 것이 가장 비쌉니다.
- 메모리의 가스 비용은 저장보다 온화합니다.
- CallData는 가장 저렴한 데이터 위치입니다.
지속성과 일시성
- Storage에 기록 된 모든 데이터는 onchain에 살고 있습니다. 즉, 데이터가 영구적이라는 것을 의미합니다.
- 메모리는 기능의 수명주기 동안 만 지속됩니다.
- CallData는 좋아합니다
memory
데이터 처리 할 때만 변경할 수 없습니다.
돌연변이
- 스토리지 데이터를 수정할 수 있습니다.
- 스토리지와 유사하게 메모리를 수정할 수 있지만 함수의 컨텍스트 내에서만 수정할 수 있습니다.
- CallData는 읽기 전용입니다.
안전
- 실수 나 해킹이 블록 체인의 상태를 영구적으로 변경할 수 있기 때문에 스토리지는 위험한 위치가 될 수 있습니다.
- 변경 사항은 일시적이므로 메모리는 더 안전한 옵션입니다.
- CallData는 입력을 전달하는 데 가장 안전합니다
external
기능.
마무리
앞에서 언급 한 바와 같이, 적절한 데이터 위치를 사용하는 것은 계약의 기능에 필수적입니다. 이 기사를 소개 할 때 언급 된 다른 유형의 데이터 위치에 대해 더 자세히 조사하도록 간청합니다.
행복한 해킹 !!
Post Comment