"Marge"とは?
pak氏というデジタルアーテイストが作成したNFTのプロジェクトです。
普通のNFTと違って面白い特徴は、NFT同士が合体(結合=マージ)するという点です!
そう結合すると言われてもイメージがしづらいですよね(笑)
具体的には、MargeのNFTを1つ所持していて2つ目を入手したときに、2つのNFTが結合するようにコントラクトが組まれています。そして、結合する度に表示される白い点が大きくなっていきます。
NFTの点の大きさが、それぞれ若干異なるのがわかりますでしょうか?(笑)
タイトル「m(数字)」の数字が大きいほど、白い点が大きく、結合回数が多いということみたいですね。
スマートコントラクト
ethscanのリンクは以下です。
https://etherscan.io/address/0xc3f8a0f5841abff777d3eefa5047e8d413a1c9ab#code
では、実際のコードを見ていきます。
結合
結合は以下のfunction _marge
によって行われているようです。
結合と言っても、具体的にここで行っている処理は、2つのNFTの白い点の大きさの比較、結合後の大きさを決定するといった内容です。
//Marge.sol
function _merge(uint256 tokenIdRcvr, uint256 tokenIdSndr) internal returns (uint256 tokenIdDead) {
require(tokenIdRcvr != tokenIdSndr, "Merge: Illegal argument identical tokenId.");
uint256 massRcvr = decodeMass(_values[tokenIdRcvr]);
uint256 massSndr = decodeMass(_values[tokenIdSndr]);
uint256 massSmall = massRcvr;
uint256 massLarge = massSndr;
uint256 tokenIdSmall = tokenIdRcvr;
uint256 tokenIdLarge = tokenIdSndr;
if (massRcvr >= massSndr) {
massSmall = massSndr;
massLarge = massRcvr;
tokenIdSmall = tokenIdSndr;
tokenIdLarge = tokenIdRcvr;
}
_values[tokenIdLarge] += massSmall;
uint256 combinedMass = massLarge + massSmall;
if(combinedMass > _alphaMass) {
_alphaId = tokenIdLarge;
_alphaMass = combinedMass;
emit AlphaMassUpdate(_alphaId, combinedMass);
}
_mergeCount[tokenIdLarge]++;
delete _values[tokenIdSmall];
_countToken -= 1;
emit MassUpdate(tokenIdSmall, tokenIdLarge, combinedMass);
return tokenIdSmall;
}
転送
function _marge
をどこで呼び出しているかしているかというと、NFTを転送するfunction _transfer
のようです。
既にMargeを持っている人に転送されると、先ほどの_marge
によって白い点が小さい方のNFTはdeadTokenId
はaddress(0)に転送、つまりバーンされるようです。
//marge.sol
function _transfer(address owner, address from, address to, uint256 tokenId) internal notFrozen {
require(owner == from, "ERC721: transfer of token that is not own");
require(to != address(0), "ERC721: transfer to the zero address");
require(!_blacklistAddress[to], "Merge: transfer attempt to blacklist address");
//---略---
} else {
uint256 sentTokenId = tokenId;
// compute token merge, returning the dead token
uint256 deadTokenId = _merge(currentTokenId, sentTokenId);
// logically, the token has already been transferred to `to`
// so log the burning of the dead token id as originating ‘from’ `to`
emit Transfer(to, address(0), deadTokenId);
// thus inferring the alive token
uint256 aliveTokenId = currentTokenId;
if (currentTokenId == deadTokenId) {
aliveTokenId = sentTokenId;
}
白い点の大きさ
先ほどの_marge
の中に以下のようなコードがあります。
_values[tokenIdLarge] += massSmall;
_values[]
の中に保管されているようですね。このコードのもっと前に
// Mapping token ID to mass value.
mapping (uint256 => uint256) private _values;
mappingで定義されていました。(やっとmappingの使い方がわかってきました汗)
おわりに
NFTは単純なアートだけでなく、スマートコントラクトによってさまざまな機能を持たせることが出来て夢いっぱいですね。
Twitterを探索していたらフルオンチェーンやフェニックスNFTなるものまで、いっぱい面白いNFTのプロジェクトが見つかるので、今後も勉強がてら紹介していきたいと思います。
ご覧いただきありがとうございました。