diff --git a/README.md b/README.md index 3630a3f..d50fbee 100644 --- a/README.md +++ b/README.md @@ -4,11 +4,11 @@ Bitcoin Cash is an ideal blockchain with incredible throughput capacity, ability There is a huge demand for Software Engineers and Developers who work on the Bitcoin Cash Ecosystem. This open-source organization consists of many small and medium-sized projects which use but are not limited to various node implementations\(BCHD\), libraries, languages\(Javascript, Go, Cashscript, and Python\), and cutting-edge technologies like gRPC and Docker. I hope that this organization will act as the go-to place for the new developer\(s\) to experiment and build something that can help grow the ecosystem. -{% page-ref page="cashweb.md" %} +{% page-ref page="explorer.md" %} -{% page-ref page="pokemon-nft-demo.md" %} +{% page-ref page="cashscript-slp.md" %} -{% page-ref page="protos-2.md" %} +{% page-ref page="protos.md" %} {% page-ref page="configs/bchdnode.md" %} diff --git a/SUMMARY.md b/SUMMARY.md index f174ae2..eab85c0 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -1,9 +1,9 @@ # Table of contents * [Introduction](README.md) -* [Explorer](cashweb.md) -* [Pokemon NFT Demo](pokemon-nft-demo.md) -* [Protos](protos-2.md) +* [Explorer](explorer.md) +* [CashScript SLP](cashscript-slp.md) +* [Protos](protos.md) * [CODE\_OF\_CONDUCT](code_of_conduct.md) * [CONTRIBUTING](contributing.md) diff --git a/cashscript-slp.md b/cashscript-slp.md new file mode 100644 index 0000000..a1ab3a1 --- /dev/null +++ b/cashscript-slp.md @@ -0,0 +1,196 @@ +# CashScript SLP + +## TOKENS + +Valid transaction using the FT.cash contract with single OP\_RETURN: [https://explorer.bitcoin.com/bch/tx/a71eae6cd8864dca5e184f49093f1b0b9cb49572959354f9ad72e5d0c0a3fa8c](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](https://explorer.bitcoin.com/bch/tx/9d1893ddedd9f1d041521c3f98508883856c3efde2406980dd3aa7af1c1b19bb) + +### FT.cash + +```javascript +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 + +```javascript +// 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: [https://explorer.bitcoin.com/bch/tx/110426292c63fe0db0932b4dc1c49594127e9b2e1a6d66a3e5696a830de9f3dd](https://explorer.bitcoin.com/bch/tx/110426292c63fe0db0932b4dc1c49594127e9b2e1a6d66a3e5696a830de9f3dd) + * Genesis: 5000 +* NFT1-Child: [https://explorer.bitcoin.com/bch/tx/546c0ca35ac4612a5ed800acc27b7c67888c874717fd1e385c07a9790240701b](https://explorer.bitcoin.com/bch/tx/546c0ca35ac4612a5ed800acc27b7c67888c874717fd1e385c07a9790240701b) + * Genesis: 1 + * Document URI: \(hex to utf8\)456c656374726963204d6f75736520302e346d20362e306b67 = Electric Mouse 0.4m 6.0kg + * Document hash: 4335393041313135313339423742383046324543323237334431364436353744 = C590A115139B7B80F2EC2273D16D657D + +## NFT1-Group & NFT1-Child contract. + +### NFT.cash + +```javascript +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](https://explorer.bitcoin.com/bch/tx/dc8cbc6486709dea0f23db356549a23d53714a1845172c034fec201cd55c203f) + +![meep](https://user-images.githubusercontent.com/7335120/122131100-4b411d80-ce56-11eb-9b28-f35dfd2d553d.png) + diff --git a/cashweb.md b/explorer.md similarity index 100% rename from cashweb.md rename to explorer.md diff --git a/pokemon-nft-demo.md b/pokemon-nft-demo.md deleted file mode 100644 index 46bfa66..0000000 --- a/pokemon-nft-demo.md +++ /dev/null @@ -1,116 +0,0 @@ ---- -description: "Pokemon NFT demo and experiment. \U0001FA99" ---- - -# Pokemon NFT Demo - -### Valid transactions - -* NFT1-Group: [https://explorer.bitcoin.com/bch/tx/110426292c63fe0db0932b4dc1c49594127e9b2e1a6d66a3e5696a830de9f3dd](https://explorer.bitcoin.com/bch/tx/110426292c63fe0db0932b4dc1c49594127e9b2e1a6d66a3e5696a830de9f3dd) - * Genesis: 5000 -* NFT1-Child: [https://explorer.bitcoin.com/bch/tx/546c0ca35ac4612a5ed800acc27b7c67888c874717fd1e385c07a9790240701b](https://explorer.bitcoin.com/bch/tx/546c0ca35ac4612a5ed800acc27b7c67888c874717fd1e385c07a9790240701b) - * Genesis: 1 - * Document URI: \(hex to ****utf8\) 456c656374726963204d6f75736520302e346d20362e306b67 = Electric Mouse 0.4m 6.0kg - * Document hash: 4335393041313135313339423742383046324543323237334431364436353744 = C590A115139B7B80F2EC2273D16D657D - -### NFT1-Group & NFT1-Child contract. - -```javascript -pragma cashscript ^0.6.0; - -contract Pokemon(bytes20 owner) { - // Require pk to match stored owner and signature to match - function reclaim(pubkey pk, sig s) { - require(hash160(pk) == owner); - require(checkSig(s, pk)); - } - - function createNFTChild(pubkey pk, sig s) { - require(hash160(pk) == owner); - require(checkSig(s, pk)); - } - - /** - * Can only be called by the creater of the contract. - */ - 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 - ]); - - int dust = 546; - int changeAmount = int(bytes(tx.value)) - dust - minerFee; - - 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); - } - } -} -``` - -### **Usage** - -```javascript -const tx = await contract.functions - .createNFTGroup( - alicePk, - new SignatureTemplate(alice), - alicePkh, - actionType, - symbol, - name, - documentURI, - documentHash, - minerFee - ) - .withOpReturn([ - lokadId, - tokenType, - actionType, - symbol, - name, - documentURI, - documentHash, - decimals, - baton, - initialQuantity - ]) - .withHardcodedFee(minerFee) - .to(slpRecipient, dust) - .to(contract.address, change) - .send(); -``` - -### **Meep Debugging** - -\*\*\*\*[https://explorer.bitcoin.com/bch/tx/dc8cbc6486709dea0f23db356549a23d53714a1845172c034fec201cd55c203f](https://explorer.bitcoin.com/bch/tx/dc8cbc6486709dea0f23db356549a23d53714a1845172c034fec201cd55c203f) - -## - diff --git a/protos-2.md b/protos.md similarity index 100% rename from protos-2.md rename to protos.md