mirror of
https://github.com/Permissionless-Software-Foundation/psffpp-payments.git
synced 2026-09-21 16:52:04 -07:00
55 lines
1.9 KiB
Plaintext
55 lines
1.9 KiB
Plaintext
pragma cashscript ^0.13.0;
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
// ShareContract — one instance per node (M=3, K=2)
|
|
//
|
|
// Holds one node's monthly share UTXO until K-of-M operators approve claim.
|
|
//
|
|
// Operation: claim
|
|
// inputs:
|
|
// 0 ShareContract [BCH] (this share UTXO)
|
|
// 1? feePayer [BCH] (optional P2PKH fee input)
|
|
// outputs:
|
|
// 0 nodePayout [BCH] (P2PKH to this node's nodePkh)
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
contract ShareContract(
|
|
pubkey node0,
|
|
pubkey node1,
|
|
pubkey node2,
|
|
bytes20 nodePkh
|
|
) {
|
|
function claim(sig s0, sig s1, sig s2) {
|
|
// CRITICAL: limit outputs first
|
|
require(tx.outputs.length == 1, "claim: expected exactly 1 output");
|
|
|
|
// K-of-M (K=2): empty sig (0x) returns false; never pass invalid non-empty sigs (NULLFAIL)
|
|
int validCount = 0;
|
|
if (checkSig(s0, node0)) {
|
|
validCount = validCount + 1;
|
|
}
|
|
if (checkSig(s1, node1)) {
|
|
validCount = validCount + 1;
|
|
}
|
|
if (checkSig(s2, node2)) {
|
|
validCount = validCount + 1;
|
|
}
|
|
require(validCount >= 2, "claim: need at least 2-of-3 signatures");
|
|
|
|
// Terminating spend to this node's payout address (no self-replication)
|
|
require(
|
|
tx.outputs[0].lockingBytecode == new LockingBytecodeP2PKH(nodePkh),
|
|
"claim: output must pay nodePkh"
|
|
);
|
|
require(tx.outputs[0].tokenCategory == 0x, "claim: output must be pure BCH");
|
|
|
|
// Value conservation (fee = inputs - output)
|
|
int inSum = 0;
|
|
for (int i = 0; i < tx.inputs.length; i = i + 1) {
|
|
inSum = inSum + tx.inputs[i].value;
|
|
}
|
|
require(tx.outputs[0].value <= inSum, "claim: value not conserved");
|
|
require(tx.outputs[0].value > 0, "claim: zero payout");
|
|
}
|
|
}
|