많이 살수록 커진다고요?NFT「merge.」기술 구조
개막사
개시하다
2021년 12월, 디지털 아티스트'팩'이 제작한 NFC 컬렉션'메르지'48시간 만에 104억이 팔려 매진됐다는 소식이 전해졌다.이 "merge"NFFT의 기술 구조가 흥미롭기 때문에 이번에는 그 구조를 해독해 보겠습니다.
merge. 무엇
참조 소스: Pak의 NFC'메르지'를 합쳐 약 104억엔이 매진됐다.
디지털 아티스트 Pak의 NFC 프로젝트
48시간 만에 약 104억엔이 팔려 매진됐다.이틀 동안 28984명이 참가했다
메르지는'마스(Mass)'로 불리는 NFC를 판매하고,'마스'를 여러 개 구매한 컬렉터가'마스'간'합병'을 할 수 있도록 했다."Mass"를 대량으로 구매하면 NFC 크기를 늘릴 수 있는 메커니즘
이로써 송어의 총량은 어느 정도 총수를 줄였다
수집가들이 2차 시장에서 송어를 구매할 때마다 새로 구입한 송어와 기존 송어는 하나의 NFFT로'합병'된다
https://niftygateway.com/collections/pakmerge
NFC 사이즈 확대?
2차 유통에서 송어를 구매할 때마다 하나의 NFFT로 통합되는 것은 무엇일까?
신경 쓰이는 부분이 많지만 실제 메르지.코치님의 소스 코드가 공개됐기 때문에 제가 바로 가볼게요.
해독하다
신경 쓰이는 곳
우선 마음에 드는 곳을 대충 조사해 보자
"Mass"를 병합할 시기는 언제입니까?
송어를 어떻게 합칩니까?NFFT 사이를 합성할 수 있습니까?어떻게 된 거야?
ERC 721은 NFC를 다른 사람에게 전달할 때
transfer
방법이라고 한다.수신할 때 호출되는 함수 (기본값) 가 존재하지 않습니다.이로써
transfer
방법 내에 합병 처리가 있을 것으로 예상된다.// Merge.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;
// ここがmerge処理
uint256 deadTokenId = _merge(currentTokenId, sentTokenId);
emit Transfer(to, address(0), deadTokenId);
uint256 aliveTokenId = currentTokenId;
if (currentTokenId == deadTokenId) {
aliveTokenId = sentTokenId;
}
delete _owners[deadTokenId];
// ...
메르지 처리 자체가 _merge
방법으로 나뉘어진 것 같아요.// Merge.sol
function _merge(uint256 tokenIdRcvr, uint256 tokenIdSndr) internal returns (uint256 tokenIdDead) {
require(tokenIdRcvr != tokenIdSndr, "Merge: Illegal argument identical tokenId.");
// 既に持っているマスの値
uint256 massRcvr = decodeMass(_values[tokenIdRcvr]);
// 購入した or 送られてきたマスの値
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に全てのマスの大きさが格納されていることがわかる
_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;
}
중요한 부분은 평론으로 쓰여 있다.요점은
_values[tokenIdLarge] += massSmall;
여기입니다.큰 칸의 값에 작은 칸의 값을 더하다.그 후 작은 네모난 칸이 번에게 넘어갔다.
송어의 초기값은?
나는 아까 코드를 보고 송어 자체가 가치가 있다는 것을 알았다.
나는 그 초기값이 1이라고 생각하지만 신중을 기하기 위해 코드를 보자.
우선, NFC 생성 처리로서
Merge.sol
의mint
방법을 읽는다// Merge.sol
// ...
function mint(uint256[] calldata values_) external onlyValidSender {
require(!_mintingFinalized, "Merge: Minting is finalized.");
uint256 index = _nextMintId;
uint256 alphaId = _alphaId;
uint256 alphaMass = _alphaMass;
address omnibus = _omnibus;
uint256 massAdded = 0;
uint256 newlyMintedCount = 0;
uint256 valueIx = 0;
while (valueIx < values_.length) {
if (isSentinelMass(values_[valueIx])) {
// SKIP FLAG SET - DON'T MINT
} else {
newlyMintedCount++;
// _values に値を入れている
// 値はこのメソッドの引数である values_ からとっている
_values[index] = values_[valueIx];
_owners[index] = omnibus;
(/* uint256 class */, uint256 mass) = decodeClassAndMass(values_[valueIx]);
if (alphaMass < mass){
alphaMass = mass;
alphaId = index;
}
massAdded += mass;
emit Transfer(address(0), omnibus, index);
}
// update counters for loop
valueIx++;
index++;
}
// ...
실제 값은 하드코딩을 거친 것이 아니기 때문에 코드에서 읽을 수 없습니다.구조기에서 질량치
getValueOf
를 볼 수 있는 방법이 실현되었다.적정
merge(1)
이 된 한 번도 병합되지 않은 마스의 토큰IDgetValueOf
호출 방법에 따라 수치를 본 곳100000001
이 표시됨에 따라 초기값100000001
이 설정됐다.왜 1000000001?100000000001+100000001 하고 있어요?
계산하는 게 아니라
100000001+100000001
._merge
방법에 이런 처리가 있다고 생각해요.// Merge.sol
// 既に持っているマスの値
uint256 massRcvr = decodeMass(_values[tokenIdRcvr]);
// 購入した or 送られてきたマスの値
uint256 massSndr = decodeMass(_values[tokenIdSndr]);
decodeMass 방법은 다음과 같습니다.// Merge.sol
// ...
uint256 constant private CLASS_MULTIPLIER = 100 * 1000 * 1000; // 100 million
// ...
function decodeMass(uint256 value) public pure returns (uint256 mass) {
mass = value % CLASS_MULTIPLIER; // integer modulo is ‘checked’ in Solidity 0.8.x
ensureValidMass(mass);
}
mass = value % CLASS_MULTIPLIER
100 * 1000 * 1000
-> 100000000
100000001
를 100000000
로 나눈 나머지 수(이 경우1
를 질의 실제값으로 하는 것이다이것은 품질치
オーバーフロー・アンダーフロー対策
이다.자세한 내용은 google 및 SafeMath 참조이러한 디지털 처리에서 알 수 있듯이 계산할 때
1+1
처럼 간단하고 알기 쉬운 디지털 안전 계산만 값100000001
100000002
과 같은 수치로 유지되고 있다.송어의 총량이 어느 정도 줄어드는 총수는 무엇입니까?
총량과 총수는 비슷해 보이지만 뜻은 조금 다르다.
총량
NFTの最大発行枚数
, 총량NFTの最大発行枚数 - burnされた数
은 이해하기 쉬울 것이다.최대 발행 장수는 어떻게 결정합니까?그것은 어디에서 보증을 받습니까?가봐.
mint
처리 방법을 살펴보겠습니다.// Merge.sol
bool public _mintingFinalized;
// ...
function mint(uint256[] calldata values_) external onlyValidSender {
// _mintingFinalizedがtrueの場合、mintができない
require(!_mintingFinalized, "Merge: Minting is finalized.");
/// ...
}
// ...
// _mintingFinalizedをtrueにする。 falseにするメソッドは無い
function finalize() external onlyPak {
thaw();
_mintingFinalized = true;
}
// ...
_mintingFinalized
의 표지의 상태 제어 여부는mint가 최대 발행 장수를 제어하는 것이 아니다._mintingFinalized
는 진짜일 수 있지만 가짜일 수는 없기 때문에 방법을 호출할 때 최대 발행 장수를 결정한다.이로부터 알 수 있듯이 총량은 일정함을 유지한다.
또 합병 후의 시간점 때문에 두 값이 비교적 작은 네모난 칸이 burn에 의해 줄어들기 때문에 총수는 줄어든다.
드로잉 처리는 어떻습니까?
송어를 합쳐 점점 커지는 구조인 것 같다.이게 어떻게 된 일입니까? 오픈sea에 표시된 이미지 데이터를 보겠습니다.
svg 파일인 것 같습니다.NFFT의 이미지 메타데이터 중 실제
finalize()
,png
,jpeg
,mp4
이외에 HTML 파일과 SVG 파일을 저장할 수도 있고base 64 인코딩의 원시 데이터를 URL 대신 저장할 수도 있다.(원시 데이터라면 가스요금이 높아진다. 또 시장 가격에 따라 표시할 수 있느냐 없느냐에 따라 달라진다.)URL은 Opensea의 것입니다. 그러나 이것은 Opensea가svg 파일을 저장한 것이 아니라 Opensea가 저장한 캐시 파일입니다.
실체는 어디에 있습니까?
그거
gif
에 써있어요.svg 데이터는 구조기에서 생성되며 이를 바탕으로 하는 메타데이터입니다.json을 만들어서 베이스 64 인코딩된 물건을 토큰 URI로 돌려줍니다.
이른바 풀 체인인 NFFT의 부분이지만, 여기서 자세한 설명은 길어지기 때문에 생략한다.참고 자료
총결산
최후
프레임에 더 세밀한 통제 처리라고 쓰여 있는데 이번에는 생략하겠습니다.
관심 있는 사람은 아래부터 구조기의 코드를 읽어 보세요.
etc
Solidity 무선 학습에 관한 커뮤니티'solidity-jp'를 만들었습니다!
지금부터 배우고 싶어요/공부하는 중에 일본어 정보가 적어요/낡고 시간이 많이 걸리는 분들, 같이 공부하세요~!!
또 트위터에 솔리시티의 기술 부분을 게시했다.가능하면 팔로우 해주세요!
Reference
이 문제에 관하여(많이 살수록 커진다고요?NFT「merge.」기술 구조), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://zenn.dev/ryo_takahashi/articles/19bdbf09ddafcb텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)