import "node_modules/scrypt-ord/src/contracts/ordinal.scrypt";import "../node_modules/scrypt-ts-lib/artifacts/merklePath.scrypt";import "../node_modules/scrypt-ts-lib/artifacts/blockchain.scrypt";import "txParserBTC.scrypt"; struct __scrypt_ts_Change { int amount; Ripemd160 address;} contract WithdrawBTC { @state bytes id; const int max; const int dec; const bytes sym; int amt; PubKey adminPubKey; Ripemd160 refundAddr; Sha256[2] hashes; 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, Sha256[2] hashes, PubKey adminPubKey, Ripemd160 refundAddr, int amt) { this.max = max; this.dec = dec; this.id = id; this.sym = sym; require(this.max <= 18446744073709551615); require(this.dec <= 18); this.hashes = hashes; this.adminPubKey = adminPubKey; this.refundAddr = refundAddr; this.amt = amt; } function buildStateOutputFT(int amt) : bytes { if(this.isGenesis()) { this.initId(); } bytes stateScript = WithdrawBTC.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 = WithdrawBTC.buildTransferScript(address, id, amt); return Utils.buildOutput(transferScript, 1); } static function buildTransferScript(Ripemd160 address, bytes id, int amt) : bytes { return (WithdrawBTC.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; } public function burn(Sig adminSig, bytes rawTx, 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)); TxParserBTC txParser = new TxParserBTC(rawTx); BTCResult result = txParser.parse(5, 5, this.hashes); require(this.amt == result.amt); require(Blockchain.verifyBlockHeader(bh)); require(Blockchain.txInBlock(Sha256(result.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 = WithdrawBTC.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'';} }