arrow-left

Only this pageAll pages
gitbookPowered by GitBook
1 of 8

cashkit

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Configs

Loading...

CashScript SLP

hashtag
TOKENS

Valid transaction using the FT.cash contract with single OP_RETURN: https://explorer.bitcoin.com/bch/tx/a71eae6cd8864dca5e184f49093f1b0b9cb49572959354f9ad72e5d0c0a3fa8carrow-up-right

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

hashtag
FT.cash

hashtag
Usage

hashtag
Valid transactions

  • NFT1-Group:

    • Genesis: 5000

  • NFT1-Child:

hashtag
NFT1-Group & NFT1-Child contract.

hashtag
NFT.cash

hashtag
Meep

Genesis: 1

  • Document URI: (hex to utf8)456c656374726963204d6f75736520302e346d20362e306b67 = Electric Mouse 0.4m 6.0kg

  • Document hash: 4335393041313135313339423742383046324543323237334431364436353744 = C590A115139B7B80F2EC2273D16D657D

  • https://explorer.bitcoin.com/bch/tx/110426292c63fe0db0932b4dc1c49594127e9b2e1a6d66a3e5696a830de9f3ddarrow-up-right
    https://explorer.bitcoin.com/bch/tx/546c0ca35ac4612a5ed800acc27b7c67888c874717fd1e385c07a9790240701barrow-up-right
    https://explorer.bitcoin.com/bch/tx/dc8cbc6486709dea0f23db356549a23d53714a1845172c034fec201cd55c203farrow-up-right
    meep

    Introduction

    Bitcoin Cash is an ideal blockchain with incredible throughput capacity, ability to scale, low transaction fees, 0-confirmation, and soon an EVM compatible side chain and much more. It’s a gem waiting to be discovered by the many.

    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.

    Explorerchevron-rightCashScript SLPchevron-rightProtoschevron-rightNode Configschevron-right

    hashtag
    Donations

    bitcoincash:qre3vyl5amlua9a80fg9ta3ck806fvqvly9frxe6n4

    hashtag
    Contribution

    Feel free to open an issue on and let's discuss.

    hashtag
    License

    MIT

    CONTRIBUTING

    Contributions are welcome! Open an issue on .

    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);
            }
    
        }
    }
    // 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();
    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);
            }
        }
    }
    herearrow-up-right
    herearrow-up-right
    qrcode

    CODE_OF_CONDUCT

    Please be nice to everyone.

    Protos

    All Protos used by Cashkit. ⚙️

    Thisarrow-up-right repo contains all proto files and generated code used by the cashkit org.

    https://github.com/cashkit/protos/tree/main/bchrpcarrow-up-right

    #!/bin/bash
    
    export PATH="$PATH:$(go env GOPATH)/bin"
    
    protoc --go_out=. --go_opt=paths=source_relative --go-grpc_out=. --go-grpc_opt=paths=source_relative bchrpc/bchrpc.proto
    protoc --go_out=. --go_opt=paths=source_relative --go-grpc_out=. --go-grpc_opt=paths=source_relative kitrpc/kitrpc.proto

    Explorer

    React + gRPC + bchd = 💚

    arrow-up-right

    This project is under development. Stuff can break.

    hashtag
    Live Transactions

    hashtag
    Blocks

    hashtag
    Development

    • Runing Envoy + React + Tests in a single terminal

      • cd cashweb/

      • docker-compose build

    hashtag
    Commands (Others)

    • Recreate proto files: ./src/protos/genproto.sh

    hashtag
    What do you get?

    • React

    • gPRC, Web gRPC

    • Typescript

    hashtag
    Why Envoy?

    After doing a lot of research and figuring out many ways to interact with gRPC server through web client. I ended up following this approach:

    • With Envoy (Current approach).

    hashtag
    Testing

    • Snapshot Testing

    hashtag
    What else?

    :information_source: Eventually this project will have:

    • Ability to interact with a local bchd node(private). :white_check_mark:

    • Ability to subscribe to custom events via cashserver(private). :white_check_mark:

    • Docker and Docker-Compose :white_check_mark:

    :speaker: Private repositories will be made public in coming week(s).

    hashtag
    Donations

    bitcoincash:qre3vyl5amlua9a80fg9ta3ck806fvqvly9frxe6n4

    hashtag
    License

    MIT

    docker-compose up

  • Running separatly [3 terminals]

    • React app:

      • npm install

      • npm start

        or

      • docker build -f Dockerfile.dev -t webclient .

      • docker run -p 3000:3000 -v /app/node_modules -v $(pwd):/app webclient

    • Tests: npm run test

    • Envoy:

      • cd envoy/

      • docker build -t envoy .

  • Go to the browser at localhost:3000arrow-up-right

  • Hooks
  • Lazy loading, Code splitting

  • Error boundaries

  • Hot Reload

  • Components.

    • Memoized Components. (Prevents unnecessary rerendering)

    • Components: They are dumb, they only display the data provided. It may contain some conditional operators and are easy to memoize.

    • Containers: They are smart components the are aware of the props. (Props could be directly from the parent or from the store.) These smart components can make calls to business logic code or update the app state.

  • Views: These components contain containers and are also aware of the app state.

  • Redux: Consists of Actions, Reducers, Sagas and other business logic.

  • Utils: Consists of helper functions.

  • Protos: Used to connect to gRPC Server and act as a connection client.

  • Managers:

    • gRPC Manager. inspired from grpc-bchrpc-browserarrow-up-right

  • Docker/Docker Compose: Containerises the application.

    • Hot reload via shared volumes in development mode.

  • Envoy: Envoy translates the HTTP/ 1.1 calls produced by the client into HTTP/ 2 calls that can be handled by the services.

  • Node interaction: Live Transactions, Fetch Transaction details, Fetch Block details

  • Scripts:

    • genproto.sh

  • Testing: Snapshot testing of Components.

  • Protos for interactions with cashserver.
  • Fetch SLP token data and more interactions.

  • Block Subscription.

  • Create a wallet and submit transactions.

  • Fetch address information.

  • Play a game via scanning a QR code [Separate module].

  • Kubernetes configs + docs.

  • Travis/circle CI configs + docs.

  • more...

  • grpc/grpc-webarrow-up-right
    qrcode

    Node Configs

    BCHD Node Configs

    hashtag
    Configs

    Mac

    Executable

    Config path

    Executable path

    hashtag
    bchwallet config

    File: bchwallet.conf

    hashtag
    bchctl config

    File: bchctl.conf

    hashtag
    bchd config

    File: bchd.conf

    hashtag
    Certificates.

    hashtag
    Auto Generation

    • Post running the bchd on your local machine, you should be able to find the certificate and key that are generated by bchd. You can use that for local development purposes.

    See Sample bchd config: rpccert=~/.bchd/rpc.cert rpckey=~/.bchd/rpc.key

    hashtag
    Custom generation

    Output files

    • ca.key: Certificate Authority private key file (this shouldn't be shared in real-life)

    • ca.crt: Certificate Authority trust certificate (this should be shared with users in real-life)

    • server.key

    certs.cnf

    : Server private key, password protected (this shouldn't be shared)
  • server.csr: Server certificate signing request (this should be shared with the CA owner)

  • server.crt: Server certificate signed by the CA (this would be sent back by the CA owner) - keep on server

  • server.pem: Conversion of server.key into a format gRPC likes (this shouldn't be shared)

  • Bchd/

    /Users/user-name/Library/Application Support/Bchd/bchd.conf

    /Users/user-name/go/bin/bchd

    Bchwallet/

    /Users/user-name/Library/Application Support/Bchwallet/bchwallet.conf

    /Users/user-name/go/bin/bchwallet

    Bchctl/

    /Users/user-name/Library/Application Support/Bchctl/bchctl.conf

    /Users/user-name/go/bin/bchctl

    https://github.com/gcash/bchd/blob/master/sample-bchd.confarrow-up-right
    username=<your-rpc-user-name>
    password=<your-rpc-password>
    bchdusername=<your-rpc-user-name>
    bchdpassword=<your-rpc-password>
    rpccert=./rpc.crt # See certificates.md
    rpckey=./rpc.key # See certificates.md
    rpcuser=<your-rpc-user-name>
    rpcpass=<your-rpc-password>
    rpccert=./rpc.crt # See certificates.md
    [Application Options]
    rpcuser=<your-rpc-user-name>
    rpcpass=<your-rpc-password>
    rpclisten=:8334
    rpccert=./rpc.crt
    rpckey=./rpc.key
    grpclisten=[::]:8335
    prunedepth=300
    txindex=1
    addrindex=1
    debuglevel=info
    #!/bin/bash
    
    # Changes these CN's to match your hosts in your environment if needed.
    SERVER_CN=localhost
    # Step 1: Generate Certificate Authority + Trust Certificate (ca.crt)
    openssl genrsa -passout pass:1111 -des3 -out ca.key 4096
    openssl req -passin pass:1111 -new -x509 -days 3650 -key ca.key -out ca.crt -subj "/CN=${SERVER_CN}"
    
    # Step 2: Generate the Server Private Key (server.key)
    openssl genrsa -passout pass:1111 -des3 -out server.key 4096
    
    # Step 3: Get a certificate signing request from the CA (server.csr)
    openssl req -passin pass:1111 -new -key server.key -out server.csr -subj "/CN=${SERVER_CN}" -config certs.cnf
    
    # Step 4: Sign the certificate with the CA we created (it's called self signing) - server.crt
    openssl x509 -req -passin pass:1111 -days 3650 -in server.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out server.crt -extensions req_ext -extfile certs.cnf
    
    # Step 5: Convert the server certificate to .pem format (server.pem) - usable by gRPC
    openssl pkcs8 -topk8 -nocrypt -passin pass:1111 -in server.key -out server.pem
    
    # Addon: Generating unencrypted key for bchd server
    # openssl rsa -in server.pem -out key.unencrypted.pem -passin pass:1111
    [ req ]
    default_bits = 4096
    distinguished_name = dn
    req_extensions = req_ext
    prompt = no
    
    [ dn ]
    CN = localhost
    
    [ req_ext ]
    subjectAltName = @alt_names
    
    [alt_names]
    DNS.1 = localhost
    DNS.2 = 127.0.0.1

    docker run -p 8080:8080 envoy

    License: MIT