import "cat721Proto.scrypt";import "nftParallelClosedMinterProto.scrypt";import "../utils/stateUtils.scrypt";import "../utils/backtrace.scrypt";import "../utils/sigHashUtils.scrypt";import "../utils/txUtil.scrypt"; contract NftParallelClosedMinter { bytes issuerAddress; bytes genesisOutpoint; int max; constructor(bytes ownerAddress, bytes genesisOutpoint, int max) { this.issuerAddress = ownerAddress; this.genesisOutpoint = genesisOutpoint; this.max = max; } public function mint(bytes[5] curTxoStateHashes, CAT721State nftMint, bytes issuerPubKeyPrefix, PubKey issuerPubKey, Sig issuerSig, bytes minterSatoshis, bytes nftSatoshis, NftParallelClosedMinterState preState, PreTxStatesInfo preTxStatesInfo, BacktraceInfo backtraceInfo, SHPreimage shPreimage, PrevoutsCtx prevoutsCtx, bytes[6] spentScripts, ChangeInfo changeInfo) { require(checkSig(SigHashUtils.checkSHPreimage(shPreimage), SigHashUtils.Gx)); SigHashUtils.checkPrevoutsCtx(prevoutsCtx, shPreimage.hashPrevouts, shPreimage.inputIndex); SigHashUtils.checkSpentScriptsCtx(spentScripts, shPreimage.hashSpentScripts); StateUtils.verifyPreStateHash(preTxStatesInfo, NftParallelClosedMinterProto.stateHash(preState), backtraceInfo.preTx.outputScriptList[0], prevoutsCtx.outputIndexVal); require(prevoutsCtx.inputIndexVal == 0); bytes preScript = spentScripts[(prevoutsCtx.inputIndexVal)]; Backtrace.verifyUnique(prevoutsCtx.spentTxhash, backtraceInfo, this.genesisOutpoint, preScript); bytes prevOutpoint = backtraceInfo.preTxInput.txhash + backtraceInfo.preTxInput.outputIndex; if(prevOutpoint == this.genesisOutpoint) { require(preTxStatesInfo.txoStateHashes[1] == b''); require(preTxStatesInfo.txoStateHashes[2] == b''); require(preTxStatesInfo.txoStateHashes[3] == b''); require(preTxStatesInfo.txoStateHashes[4] == b''); } bytes hashString = b''; bytes minterOutput = b''; int stateNumber = 0; int nextLocalId1 = preState.nextLocalId + preState.nextLocalId + 1; int nextLocalId2 = preState.nextLocalId + preState.nextLocalId + 2; if(nextLocalId1 < this.max) { minterOutput += TxUtil.buildOutput(preScript, minterSatoshis); hashString += hash160(NftParallelClosedMinterProto.stateHash({preState.nftScript, nextLocalId1})); stateNumber += 1; } if(nextLocalId2 < this.max) { minterOutput += TxUtil.buildOutput(preScript, minterSatoshis); hashString += hash160(NftParallelClosedMinterProto.stateHash({preState.nftScript, nextLocalId2})); stateNumber += 1; } require(nftMint.localId == preState.nextLocalId); hashString += hash160(CAT721Proto.stateHash(nftMint)); bytes nftOutput = TxUtil.buildOutput(preState.nftScript, nftSatoshis); stateNumber += 1; bytes stateOutput = StateUtils.getCurrentStateOutput(hashString, stateNumber, curTxoStateHashes); bytes changeOutput = TxUtil.getChangeOutput(changeInfo); Sha256 hashOutputs = sha256(stateOutput + minterOutput + nftOutput + changeOutput); require(hashOutputs == shPreimage.hashOutputs); require(this.issuerAddress == hash160(issuerPubKeyPrefix + issuerPubKey)); require(checkSig(issuerSig, issuerPubKey)); } }