❤️ 0 Likes · ⚡ 0 Tips
{
"txid": "0c8d63c1127f3bd836dcca8e79a65a560c08fd9cf6c11692f2005803b18a2ed0",
"block_height": 801387,
"time": null,
"app": "pow.co",
"type": "post",
"map_content": "# Buyable / Sellable Scrypt Objects\n### A simple pattern to \"mixin\" to any stateful smart object you want to be sellable\n\nIf a smart contract has an owner property and can be \"ownable\", what makes it \"sellable\"?\n\nAny contract that adds an owner property may also add a price property that indicates that the object becomes \"sellable\". It must then implement a buy() method which assigns the owner to the new owner's address only if the price is paid. It will also need a setPrice(signature: Signature) method allowing the owner to set the price. Perhaps setting the price to 0 would disallow sales, or perhaps there is another prop called buyable and a method called setBuyable(buyable: boolean) which would allow the user to list it for sale any time.\n\n```\n\nimport {\n method,\n prop,\n SmartContract,\n hash256,\n hash160,\n assert,\n ByteString,\n SigHash,\n PubKey,\n PubKeyHash,\n Sig\n} from 'scrypt-ts'\n\nexport class Sellable extends SmartContract {\n\n @prop(true)\n pubKeyHash: PubKeyHash\n\n @prop(true)\n price: bigint\n\n @prop(true)\n buyable: boolean\n\n constructor(pubKeyHash: PubKeyHash) {\n super(...arguments)\n this.pubKeyHash = pubKeyHash\n this.matureTime = matureTime\n }\n\n @method()\n public setBuyable(buyable: boolean, sig: Signature) {\n this.buyable = buyable;\n }\n\n @method()\n public setPrice(price: bigint, sig: Signature) {\n this.price = price;\n }\n\n @method()\n public buy(pubKeyHash: PubKeyHash) {\n\n assert(this.buyable)\n\n // Ensure exact payment of the price to the current owner's address\n const paymoutOutput = Utils.buildPublicKeyHashOutput(this.pubKeyHash, this.price)\n assert(hash256(paymoutOutput) == this.ctx.hashOutputs, 'invalid output for payment to seller')\n\n // Ensure the smart object's state remains entirely intact during the sale\n const stateOutput = this.buildStateOutput(amount)\n assert(this.ctx.hashOutputs == hash256(stateOutput), \"Output hashes don't match\")\n\n // \"transfer\" ownership by assigning a new owner\n this.pubKeyHash = pubKeyHash\n }\n\n}\n```",
"media_type": "text/markdown",
"filename": "|",
"author": "1Fma6nUd4xG6GWp9JJYjZyCM2hSWBcGd2X",
"display_name": null,
"channel": null,
"parent_txid": null,
"ref_txid": null,
"tags": null,
"reply_count": 0,
"like_count": 0,
"timestamp": "2023-07-19T19:52:54.000Z",
"media_url": null,
"aip_verified": true,
"thread_root_tx": null,
"engagement_score": 0,
"token_ref": null,
"token_type": null,
"kind": null,
"lat": null,
"lng": null,
"category": null,
"locked_sats": "0",
"pow_bits": 0,
"has_access": true,
"ui_name": "1Fma6n\u2026Gd2X",
"ui_display_name": "1Fma6n\u2026Gd2X",
"ui_handle": null,
"ui_display_raw": null,
"ui_signer": "1Fma6n\u2026Gd2X",
"ref_ui_name": "unknown",
"ref_ui_signer": "unknown"
}