CashScript SLP

TOKENS

Valid transaction using the FT.cash contract with single OP_RETURN: https://explorer.bitcoin.com/bch/tx/a71eae6cd8864dca5e184f49093f1b0b9cb49572959354f9ad72e5d0c0a3fa8c

Valid transaction using the FT.cash contract with 2 OP_RETURN (SLP AND MEMO): https://explorer.bitcoin.com/bch/tx/9d1893ddedd9f1d041521c3f98508883856c3efde2406980dd3aa7af1c1b19bb

FT.cash

pragma cashscript ^0.6.3;

contract FT(bytes20 owner) {
    // Warning: This method 'reclaim' should only be used in testing.
    // Backdoor to reclaim funds,
    function reclaim(pubkey pk, sig s) {
        require(checkSig(s, pk));
    }

    function createToken(
        pubkey pk,
        sig s,
        bytes20 recipientPkh,
        bytes lokadId,
        bytes tokenType,
        string actionType,
        string symbol,
        string name,
        string documentURI,
        string documentHash,
        bytes decimals,
        bytes baton,
        bytes initialQuantity,
        int minerFee,
        //string memoText
    ) {  
        require(hash160(pk) == owner);
        require(checkSig(s, pk));

        int dust = 546;

        bytes token = new OutputNullData([
            lokadId,
            tokenType,
            bytes(actionType),
            bytes(symbol),
            bytes(name),
            bytes(documentURI),
            bytes(documentHash),
            decimals,
            baton,
            initialQuantity
        ]);

        // bytes memo = new OutputNullData([
        //     0x6d02,
        //     bytes(memoText)
        // ]);

        int changeAmount = int(bytes(tx.value)) - minerFee - dust;
        if (changeAmount >= dust) {
            bytes34 recipient = new OutputP2PKH(bytes8(dust), recipientPkh);
            // Get the change back to the contract i.e Pay to Script Hash which is the current contract.
            bytes32 change = new OutputP2SH(bytes8(changeAmount), hash160(tx.bytecode));
            //require(hash256(token + recipient + change + memo) == tx.hashOutputs);
            require(hash256(token + recipient + change) == tx.hashOutputs);
        } else {
            require(hash256(token) == tx.hashOutputs);
        }

    }
}

Usage

// Check the tokens/genesis.tsx

// import { hexToBin } from '@bitauth/libauth'
const lokadId = '0x534c5000'
...

const lokadIdBin = hexToBin(lokadId.substring(2))
...

const tx = await contract.functions
  .createToken(
    userPk,
    new SignatureTemplate(user),
    userPkh,
    lokadIdBin,
    ...
    minerFee,
  )
  .withOpReturn([
    lokadId,
    ...
    initialQuantity
  ])
  .to(slpRecipient, dust)
  .to(contract.address, change)
  // .withOpReturn([
  //   '0x6d02',
  //   strr,
  // ])
  .withHardcodedFee(minerFee)
  //.build()
  .send();

Valid transactions

NFT1-Group & NFT1-Child contract.

NFT.cash

pragma cashscript ^0.6.0;

contract NFT(bytes20 owner) {
    // Warning: This method 'reclaim' should only be used in testing.
    // Backdoor to reclaim funds,
    function reclaim(pubkey pk, sig s) {
        require(hash160(pk) == owner);
        require(checkSig(s, pk));
    }

    // Warning: This method 'createNFTChild' should only be used in testing.
    // Backdoor to reclaim funds,
    function createNFTChild(pubkey pk, sig s) {
        require(hash160(pk) == owner);
        require(checkSig(s, pk));
    }

    function createNFTGroup(
        pubkey pk,
        sig s,
        bytes20 recipientPkh,
        string actionType,
        string symbol,
        string name,
        string documentURI,
        string documentHash,
        int minerFee,
    ) {  

        require(hash160(pk) == owner);
        require(checkSig(s, pk));

        bytes announcement = new OutputNullData([
            0x534c5000,
            0x81,
            bytes(actionType),
            bytes(symbol),
            bytes(name),
            bytes(documentURI),
            bytes(documentHash),
            0x00,
            0xff, // Trick: Keep this number above the number of transactions you would expect.
            0x0000000000001388
        ]);
        // Calculate leftover money after fee (1000 sats)
        // Add change output if the remainder can be used
        // otherwise donate the remainder to the miner
        // int minerFee = 1000;
        int dust = 546;
        int changeAmount = int(bytes(tx.value)) - dust - minerFee;

        // require(changeAmount > dust);

        if (changeAmount >= minerFee) {
            bytes34 recipient = new OutputP2PKH(bytes8(dust), recipientPkh);
            bytes32 change = new OutputP2SH(bytes8(changeAmount), hash160(tx.bytecode));
            require(hash256(announcement + recipient + change) == tx.hashOutputs);
        } else {
            require(hash256(announcement) == tx.hashOutputs);
        }
    }
}

Meep

https://explorer.bitcoin.com/bch/tx/dc8cbc6486709dea0f23db356549a23d53714a1845172c034fec201cd55c203f

Last updated