Beispiel #1
0
function ProcessScriptTests($inputSource)
{
    echo "CoinSpark Script Tests Output\n\n";
    while (true) {
        $inputLines = GetNextInputLines($inputSource, 4);
        if (!isset($inputLines)) {
            break;
        }
        list($countInputs, $countOutputs, $scriptPubKeyHex) = $inputLines;
        $metadata = CoinSparkScriptToMetadata($scriptPubKeyHex, true);
        if (!isset($metadata)) {
            die("Could not decode script metadata: {$scriptPubKeyHex}\n");
        }
        //	Read in the different types of metadata
        $genesis = new CoinSparkGenesis();
        $hasGenesis = $genesis->decode($metadata);
        $paymentRef = new CoinSparkPaymentRef();
        $hasPaymentRef = $paymentRef->decode($metadata);
        $transfers = new CoinSparkTransferList();
        $hasTransfers = $transfers->decode($metadata, $countInputs, $countOutputs);
        $message = new CoinSparkMessage();
        $hasMessage = $message->decode($metadata, $countOutputs);
        //	Output the toString()s
        if ($hasGenesis) {
            echo $genesis->toString();
        }
        if ($hasPaymentRef) {
            echo $paymentRef->toString();
        }
        if ($hasTransfers) {
            echo $transfers->toString();
        }
        if ($hasMessage) {
            echo $message->toString();
        }
        //	Re-encode
        $testMetadata = '';
        $testMetadataMaxLen = strlen($metadata);
        $nextMetadataMaxLen = $testMetadataMaxLen;
        $encodeOrder = array('genesis', 'paymentRef', 'transfers', 'message');
        foreach ($encodeOrder as $encodeField) {
            $triedNextMetadata = false;
            switch ($encodeField) {
                case 'genesis':
                    if ($hasGenesis) {
                        $nextMetadata = $genesis->encode($nextMetadataMaxLen);
                        $triedNextMetadata = true;
                    }
                    break;
                case 'paymentRef':
                    if ($hasPaymentRef) {
                        $nextMetadata = $paymentRef->encode($nextMetadataMaxLen);
                        $triedNextMetadata = true;
                    }
                    break;
                case 'transfers':
                    if ($hasTransfers) {
                        $nextMetadata = $transfers->encode($countInputs, $countOutputs, $nextMetadataMaxLen);
                        $triedNextMetadata = true;
                    }
                    break;
                case 'message':
                    if ($hasMessage) {
                        $nextMetadata = $message->encode($countOutputs, $nextMetadataMaxLen);
                        $triedNextMetadata = true;
                    }
                    break;
            }
            if ($triedNextMetadata) {
                if (!isset($nextMetadata)) {
                    die("Failed to reencode {$encodeField} metadata!\n");
                }
                if (strlen($testMetadata)) {
                    $testMetadata = CoinSparkMetadataAppend($testMetadata, $testMetadataMaxLen, $nextMetadata);
                    if (!isset($testMetadata)) {
                        die("Insufficient space to append {$encodeField} metadata!\n");
                    }
                } else {
                    $testMetadata = $nextMetadata;
                }
                $nextMetadataMaxLen = CoinSparkMetadataMaxAppendLen($testMetadata, $testMetadataMaxLen);
            }
        }
        //	Test other library functions while we are here
        if ($hasGenesis) {
            if (!$genesis->match($genesis, true)) {
                die("Failed to match genesis to itself!\n");
            }
            if ($genesis->calcHashLen(strlen($metadata)) != $genesis->assetHashLen) {
                // assumes that metadata only contains genesis
                die("Failed to calculate matching asset hash length!\n");
            }
            $testGenesis = new CoinSparkGenesis();
            $testGenesis->decode($metadata);
            $rounding = rand(0, 2) - 1;
            $testGenesis->setQty(0, 0);
            $testGenesis->setQty($genesis->getQty(), $rounding);
            $testGenesis->setChargeFlat(0, 0);
            $testGenesis->setChargeFlat($genesis->getChargeFlat(), $rounding);
            if (!$genesis->match($testGenesis, false)) {
                die("Mismatch on genesis rounding!\n");
            }
        }
        if ($hasPaymentRef) {
            if (!$paymentRef->match($paymentRef)) {
                die("Failed to match paymentRef to itself!\n");
            }
        }
        if ($hasTransfers) {
            if (!$transfers->match($transfers, true)) {
                die("Failed to strictly match transfers to itself!\n");
            }
            if (!$transfers->match($transfers, false)) {
                die("Failed to leniently match transfers to itself!\n");
            }
        }
        if ($hasMessage) {
            if (!$message->match($message, true)) {
                die("Failed to strictly match message to itself!\n");
            }
            if (!$message->match($message, false)) {
                die("Failed to leniently match message to itself!\n");
            }
            $messageEncode = $message->encode($countOutputs, strlen($metadata));
            // encode on its own to check calcHashLen()
            if ($message->calcHashLen($countOutputs, strlen($messageEncode)) != $message->hashLen) {
                die("Failed to calculate matching message hash length!\n");
            }
        }
        //	Compare to the original
        $encoded = CoinSparkMetadataToScript($testMetadata, true);
        if ($encoded != $scriptPubKeyHex) {
            die("Encode metadata mismatch: {$encoded} should be {$scriptPubKeyHex}\n");
        }
        $checkMetadata = CoinSparkScriptToMetadata(CoinSparkMetadataToScript($testMetadata, false), false);
        if ($checkMetadata != $testMetadata) {
            die("Binary metadata to/from script mismatch!\n");
        }
    }
}
Beispiel #2
0
/**
 * Extracts first OP_RETURN metadata (not necessarily CoinSpark data) from an array of bitcoin tx output scripts.
 *
 * @param array $scriptPubKeys Array of output scripts as raw binary data or hexadecimal.
 * @param boolean $scriptsAreHex True to interpret each element of $scriptPubKeys as a hex string, false as raw binary.
 *
 * @return string|null First raw binary embedded metadata if found, null if none found.
 */
function CoinSparkScriptsToMetadata($scriptPubKeys, $scriptsAreHex)
{
    foreach ($scriptPubKeys as $scriptPubKey) {
        if (!CoinSparkScriptIsRegular($scriptPubKey, $scriptsAreHex)) {
            return CoinSparkScriptToMetadata($scriptPubKey, $scriptsAreHex);
        }
    }
    return null;
}