Payment Covenant

The covenant where the user payment gets sent to. This dynamic covenant can handle up to 8 distribution covenant script hashes during distribution. This covenant also handles the sending of revenue BCH to PurelyPeer’s revenue address. The PAY_COV ’s contract script is generated dynamically depending on how many DIST_COV it will carry.

PARAMETERS

NameData TypeDescription
pkpubkeyPurelyPeer’s public key. This is used in ensuring that only PurelyPeer server can call the functions of this covenant.
revenueCollectorPKHbytes20PurelyPeer’s revenue collector’s public key hash. Everytime a quest is funded, a percentage of the quest atmount goes to PurelyPeer as revenue.
questFunderPKHbytes20The quest funder’s public key hash, where the refunded amount gets sent to.
questAmountintThe quest amount funded by the quest funder.
scriptHash1,scriptHash2,….scriptHashNbytes32The script hashes of this covenant’s children DIST_COVs. This parameter is dynamic depending on how many distribution covenants a PAY_COV has, meaning if the PAY_COV has 3 DIST_COVs , it will have three (3) of this parameter in its constructor —- scriptHash1, scriptHash2, scriptHash3 The maximum value of N here is 8, since the contract can only hold up to 8 DIST_COV script hashes at the time.

FUNCTIONS

  • refund = used to refund the funds to the quest funder in case of a server or network error during distribution. The amount refunded is the original quest amount subtracted by the transaction fee (dust).

Parameters:

NameTypeDescription
ssigPurelyPeer’s signature used to secure the contract, such that only PurelyPeer server can execute this function.

fund

The main function to distribute the funds to the distribution covenants (DIST_COVs) and to the PurelyPeer revenue address.

Parameters:

NameData TypeDescription
ssigPurelyPeer’s signature used to secure the contract, such that only PurelyPeer server can execute this function.
amountintThe BCH amount sent to the DIST_COV (distCovScriptHash)
distCovScriptHashbytes32The DIST_COV script hash where the funds will be distributed.
isRevenueboolA flag to determine if the PAY_COV is sending to the revenue address of PurelyPeer.

CONTRACT SCRIPT : pragma cashscript ^0.8.0;

contract PaymentCovenant (
    pubkey pk,
    bytes20 revenueCollectorPKH,
    bytes20 questFunderPKH,
    int questAmount,
    bytes32 scriptHash1,
    bytes32 scriptHash2,
    bytes32 scriptHash3,
    ...
    bytes32 scriptHashN,
) {
    function refund (sig s) {
        require(checkSig(s, pk));

        int fee = 1000;
        int refundedAmount = questAmount - fee;
        require(tx.outputs[0].value == refundedAmount);

        bytes25 questFunder = new LockingBytecodeP2PKH(questFunderPKH);
        require(tx.outputs[0].lockingBytecode == questFunder);
    }

    function fund (
        sig s,
        int amount,
        bytes32 distCovScriptHash,
        bool isRevenue
    ) {
        require(checkSig(s, pk));

        if (isRevenue) {
            require(tx.outputs[0].value == amount);

            bytes25 revenueCollector = new LockingBytecodeP2PKH(revenueCollectorPKH);
            bool sendToRevenueCollector = tx.outputs[0].lockingBytecode == revenueCollector;
            require(sendToRevenueCollector);
        } else {
            require(
                            distCovScriptHash == scriptHash1 ||
                            distCovScriptHash == scriptHash2 ||
                            distCovScriptHash == scriptHash3 ||
                            ...
                            distCovScriptHash == scriptHashN ||
                        );

            bytes35 distCov = new LockingBytecodeP2SH32(distCovScriptHash);
            require(tx.outputs[0].lockingBytecode == distCov);

            int minerFee = 1100;
            int currentValue = tx.inputs[this.activeInputIndex].value;
            int change = currentValue - amount - minerFee;

            require(tx.outputs[0].value == amount);

            bytes changeBytecode = tx.inputs[this.activeInputIndex].lockingBytecode;
            require(tx.outputs[1].lockingBytecode == changeBytecode);
            require(tx.outputs[1].value == change);
        }
    }
}