import "cat721Proto.scrypt";import "../utils/stateUtils.scrypt";import "../utils/backtrace.scrypt";import "../utils/sigHashUtils.scrypt";import "nftGuardProto.scrypt";import "../utils/txProof.scrypt"; struct NftUnlockArgs { bool isUserSpend; bytes userPubKeyPrefix; PubKey userPubKey; Sig userSig; int contractInputIndex; } struct NftGuardInfo { XrayedTxIdPreimg3 tx; int inputIndexVal; bytes outputIndex; NftGuardConstState guardState; } contract CAT721 { bytes minterScript; bytes guardScript; public function unlock(NftUnlockArgs nftUnlockArgs, CAT721State preState, PreTxStatesInfo preTxStatesInfo, NftGuardInfo guardInfo, BacktraceInfo backtraceInfo, SHPreimage shPreimage, PrevoutsCtx prevoutsCtx, bytes[6] spentScriptsCtx) { require(checkSig(SigHashUtils.checkSHPreimage(shPreimage), SigHashUtils.Gx)); SigHashUtils.checkPrevoutsCtx(prevoutsCtx, shPreimage.hashPrevouts, shPreimage.inputIndex); SigHashUtils.checkSpentScriptsCtx(spentScriptsCtx, shPreimage.hashSpentScripts); StateUtils.verifyPreStateHash(preTxStatesInfo, CAT721Proto.stateHash(preState), backtraceInfo.preTx.outputScriptList[0], prevoutsCtx.outputIndexVal); bytes preScript = spentScriptsCtx[(prevoutsCtx.inputIndexVal)]; Backtrace.verifyToken(prevoutsCtx.spentTxhash, backtraceInfo, this.minterScript, preScript); this.valitateNftGuard(guardInfo, preScript, preState, prevoutsCtx.inputIndexVal, prevoutsCtx.prevouts, spentScriptsCtx); if(nftUnlockArgs.isUserSpend) { require(hash160(nftUnlockArgs.userPubKeyPrefix + nftUnlockArgs.userPubKey) == preState.ownerAddr); require(checkSig(nftUnlockArgs.userSig, nftUnlockArgs.userPubKey)); } else { require(preState.ownerAddr == hash160(spentScriptsCtx[(nftUnlockArgs.contractInputIndex)])); } require(true); } function valitateNftGuard(NftGuardInfo guardInfo, bytes preScript, CAT721State preState, int inputIndexVal, bytes[6] prevouts, bytes[6] spentScripts) : bool { bytes guardHashRoot = NftGuardProto.stateHash(guardInfo.guardState); require(StateUtils.getStateScript(guardHashRoot, 1) == guardInfo.tx.outputScriptList[0]); require(guardInfo.guardState.collectionScript == preScript); require(preState.localId >= 0); require(guardInfo.guardState.localIdArray[(inputIndexVal)] == preState.localId); bytes guardTxid = TxProof.getTxIdFromPreimg3(guardInfo.tx); require(prevouts[(guardInfo.inputIndexVal)] == guardTxid + guardInfo.outputIndex); require(spentScripts[(guardInfo.inputIndexVal)] == this.guardScript); return true; } }