import "node_modules/scrypt-ord/src/contracts/ordinal.scrypt";import "oracleMsg.scrypt";import "../node_modules/scrypt-ts-lib/artifacts/rabinSignature.scrypt";import "../node_modules/scrypt-ts-lib/artifacts/merklePath.scrypt";import "../node_modules/scrypt-ts-lib/artifacts/blockchain.scrypt"; struct __scrypt_ts_Change { int amount; Ripemd160 address;} contract WithdrawBRC20 { @state bytes id; const int max; const int dec; const bytes sym; int amt; Ripemd160 recipientAddr; int oraclePubKey; PubKey adminPubKey; Ripemd160 refundAddr; bytes __scrypt_ts_ctx_hashoutputs; bytes __scrypt_ts_ctx_outpoint_txid; int __scrypt_ts_ctx_outpoint_outputindex; __scrypt_ts_Change __scrypt_ts_change; constructor(bytes id, bytes sym, int max, int dec, Ripemd160 recipientAddr, Ripemd160 refundAddr, PubKey adminPubKey, int oraclePubKey, int amt) { this.max = max; this.dec = dec; this.id = id; this.sym = sym; require(this.max <= 18446744073709551615); require(this.dec <= 18); this.recipientAddr = recipientAddr; this.refundAddr = refundAddr; this.adminPubKey = adminPubKey; this.oraclePubKey = oraclePubKey; this.amt = amt; } function buildStateOutputFT(int amt) : bytes { if(this.isGenesis()) { this.initId(); } bytes stateScript = WithdrawBRC20.createTransferInsciption(this.id, amt) + Ordinal.removeInsciption(this.getStateScript()); return Utils.buildOutput(stateScript, 1); } function isGenesis() : bool { return this.id == b''; } static function buildTransferOutput(Ripemd160 address, bytes id, int amt) : bytes { bytes transferScript = WithdrawBRC20.buildTransferScript(address, id, amt); return Utils.buildOutput(transferScript, 1); } static function buildTransferScript(Ripemd160 address, bytes id, int amt) : bytes { return (WithdrawBRC20.createTransferInsciption(id, amt) + Utils.buildPublicKeyHashScript(address)); } static function createTransferInsciption(bytes id, int amt) : bytes { bytes amtByteString = Ordinal.int2Str(amt); bytes transferJSON = "{\"p\":\"bsv-20\",\"op\":\"transfer\",\"id\":\"" + id + "\",\"amt\":\"" + amtByteString + "\"}"; return Ordinal.createInsciption(transferJSON, "application/bsv-20"); } function initId() : bool { this.id = Ordinal.txId2str(this.__scrypt_ts_ctx_outpoint_txid) + "_" + Ordinal.int2Str(this.__scrypt_ts_ctx_outpoint_outputindex); return true; } static function parseMsg(bytes msg) : OracleMsg { bytes msgType = msg[0 : 1]; require(msgType == b'02'); bytes txid = msg[1 : 33]; bytes tokenId = msg[33 : 99]; Ripemd160 recipient = Ripemd160(msg[99 : 119]); int amt = Utils.fromLEUnsigned(msg[119 : len(msg)]); return {msgType, txid, tokenId, recipient, amt}; } public function burn(Sig adminSig, bytes msg, RabinSig sig, Node[32] merkleProof, BlockHeader bh, SigHashPreimage __scrypt_ts_txPreimage, int __scrypt_ts_changeAmount, Ripemd160 __scrypt_ts_changeAddress) { require(Tx.checkPreimageSigHashType(__scrypt_ts_txPreimage, SigHashType(b'41'))); this.__scrypt_ts_ctx_hashoutputs = SigHash.hashOutputs(__scrypt_ts_txPreimage); this.__scrypt_ts_ctx_outpoint_outputindex = unpack(SigHash.outpoint(__scrypt_ts_txPreimage)[32 :]); this.__scrypt_ts_ctx_outpoint_txid = SigHash.outpoint(__scrypt_ts_txPreimage)[0:32]; this.__scrypt_ts_change = {__scrypt_ts_changeAmount, __scrypt_ts_changeAddress}; require(checkSig(adminSig, this.adminPubKey)); require(RabinVerifier.verifySig(msg, sig, this.oraclePubKey)); OracleMsg oracleMsg = WithdrawBRC20.parseMsg(msg); require(this.amt == oracleMsg.amt); require(this.recipientAddr == oracleMsg.recipient); require(oracleMsg.tokenId == this.id); require(Blockchain.verifyBlockHeader(bh)); require(Blockchain.txInBlock(Sha256(oracleMsg.txid), bh, merkleProof, 32)); bytes outputs = this.buildChangeOutput(); require(hash256(outputs) == this.__scrypt_ts_ctx_hashoutputs); } public function cancel(Sig adminSig, SigHashPreimage __scrypt_ts_txPreimage, int __scrypt_ts_changeAmount, Ripemd160 __scrypt_ts_changeAddress) { require(Tx.checkPreimageSigHashType(__scrypt_ts_txPreimage, SigHashType(b'41'))); this.__scrypt_ts_ctx_hashoutputs = SigHash.hashOutputs(__scrypt_ts_txPreimage); this.__scrypt_ts_ctx_outpoint_outputindex = unpack(SigHash.outpoint(__scrypt_ts_txPreimage)[32 :]); this.__scrypt_ts_ctx_outpoint_txid = SigHash.outpoint(__scrypt_ts_txPreimage)[0:32]; this.__scrypt_ts_change = {__scrypt_ts_changeAmount, __scrypt_ts_changeAddress}; require(checkSig(adminSig, this.adminPubKey)); bytes outputs = WithdrawBRC20.buildTransferOutput(this.refundAddr, this.id, this.amt); outputs += this.buildChangeOutput(); require(hash256(outputs) == this.__scrypt_ts_ctx_hashoutputs); } function buildStateOutput(int amount) : bytes { return Utils.buildOutput(this.getStateScript(), amount);} function buildChangeOutput() : bytes { return this.__scrypt_ts_change.amount > 0 ? Utils.buildOutput(Utils.buildPublicKeyHashScript(this.__scrypt_ts_change.address), this.__scrypt_ts_change.amount) : b'';} }