Solidityにおいてマッピングで存在チェックする方法について解説します。
結論:マッピングには存在チェックするメソッドはない
まず結論から言うと、Solidityのマッピング(mapping)には、existsのような値を存在チェックするメソッドが備わっておりません。
そのため、初期値と比較することで存在チェックを行うなど、代替策をとる必要があります。
代替策:初期値と比較し存在チェックを行う
Solidityのマッピングでは、キーが存在しない場合、空(null)にはならず型に応じた初期値が返されます。
この性質を利用し、マッピングの存在チェックを行います。
データ型 | デフォルト値 |
---|---|
uint, int | 0 |
bool | false |
address | address(0)(0x0000000000000000000000000000000000000000) |
bytes | 0x |
string | ""(空文字) |
上表がデータ型ごとの初期値となるため、これと比較することで、存在チェックを行います。
以下は実際のサンプルコードとなります。
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;
contract TestContract {
mapping (address => uint) private uintMapping; // uint
mapping (address => bool) private boolMapping; // bool
mapping (address => address) private addressMapping; // address
mapping (address => bytes) private bytesMapping; // bytes
mapping (address => string) private stringMapping; // string
function isExistUint() public view returns(string memory) {
if (uintMapping[msg.sender] == 0) {
return "Not Exitst";
}
return "Exist";
}
function isExistBool() public view returns(string memory) {
if (boolMapping[msg.sender] == false) {
return "Not Exitst";
}
return "Exist";
}
function isExistAddress() public view returns(string memory) {
if (addressMapping[msg.sender] == address(0)) {
return "Not Exitst";
}
return "Exist";
}
function isExistBytes() public view returns(string memory) {
if (keccak256(bytesMapping[msg.sender]) == keccak256(hex"")) {
return "Not Exitst";
}
return "Exist";
}
function isExistString() public view returns(string memory) {
if (keccak256(abi.encodePacked(uintMapping[msg.sender])) == keccak256(abi.encodePacked(""))) {
return "Not Exitst";
}
return "Exist";
}
}
厳密性には欠ける方法ですが代替策として紹介させて頂きました。Solidityのビルトインメソッド(標準で備わっているメソッド)に無い場合は、処理を自作するか外部ライブラリを使用するようにしましょう。