#include "CBValidationFunctions.h"
				
uint64_t CBCalculateBlockReward(uint64_t blockHeight){
	return (50 * CB_ONE_BITCOIN) >> (blockHeight / 210000);
}
bool CBCalculateBlockWork(CBBigInt * work, uint32_t target){
	// Get the base-256 exponent and the mantissa.
	uint8_t zeroBytes = target >> 24;
	target &= 0x00FFFFFF;
	// Allocate CBBigInt data
	work->length = 32;
	CBBigIntAlloc(work, work->length);
	if (NOT work->data)
		return false;
	// Do base-4294967296 long division and adjust for trailing zeros in target.
	uint64_t temp = 0x01000000;
	uint32_t workSeg;
	for (uint8_t x = 0;; x++) {
		workSeg = (uint32_t)(temp / target);
		uint8_t i = 31 - x * 4 - zeroBytes + 4;
		for (uint8_t y = 0; y < 4; y++){
			work->data[i] = workSeg >> ((3 - y) * 8);
			if (NOT i){
				CBBigIntNormalise(work);
				return true;
			}
			i--;
		}
		temp -= workSeg * target;
		temp <<= 32;
	}
}
void CBCalculateMerkleRoot(uint8_t * hashes,uint32_t hashNum){
	uint8_t hash[32];
	for (uint32_t x = 0; hashNum != 1;) {
		if (x == hashNum - 1) {
			uint8_t dup[64];
			memcpy(dup, hashes + x * 32, 32);
			memcpy(dup + 32, hashes + x * 32, 32);
			CBSha256(dup, 64, hash);
		}else
			CBSha256(hashes + x * 32, 64, hash);
		// Double SHA256
		CBSha256(hash, 32, hashes + x * 32/2);
		x += 2;
		if (x >= hashNum) {
			if (x > hashNum)
                // The number of hashes was odd. Increment to even
                hashNum++;
			hashNum /= 2;
			x = 0;
		}
	}
}
uint32_t CBCalculateTarget(uint32_t oldTarget, uint32_t time){
	// Limitations on the factor for retargeting.
	if (time < CB_TARGET_INTERVAL / 4)
		time = CB_TARGET_INTERVAL / 4;
	if (time > CB_TARGET_INTERVAL * 4)
		time = CB_TARGET_INTERVAL * 4;
	// Get number of trailing 0 bytes (Base 256 exponent)
	uint8_t zeroBytes = oldTarget >> 24;
	// Get the three bytes for the target mantissa. Use 8 bytes for overflow. Shift along once for division.
	uint64_t num = (oldTarget & 0x00FFFFFF) << 8;
	// Modify the three bytes
	num *= time;
	num /= CB_TARGET_INTERVAL;
	// Find first byte with data. Check for flow into more or less significant byte.
	if (num & 0xF00000000) {
		// Mantissa overflowed into more significant byte.
		num >>= 16;
		num &= 0x00FFFFFF; // Clear the forth byte for the number of zero bytes.
		zeroBytes++;
	}else if (num & 0xFF000000)
		// Data within same three bytes
		num >>= 8;
	else
		// Data down a byte
		zeroBytes--;
	// Modify in the case of the first byte in the mantissa being over 0x7F... What did you say?... Oh yes, the bitcoin protocol can be dumb in places.
	if (num > 0x007FFFFF) {
		// Add trailing zero by shifting right...
		num >>= 8;
		// Compensate with additional trailing zero byte.
		zeroBytes++;
	}
	// Apply the number of trailing zero bytes into the compact target representation.
	num |= zeroBytes << 24;
	// Check if the target is too high and if it is, make it equal the maximum target.
	if (num > CB_MAX_TARGET)
		num = CB_MAX_TARGET;
	// Return the new target
	return (uint32_t) num;
}
uint32_t CBTransactionGetSigOps(CBTransaction * tx){
	uint32_t sigOps = 0;
	for (uint32_t x = 0; x < tx->inputNum; x++)
		sigOps += CBScriptGetSigOpCount(tx->inputs[x]->scriptObject, false);
	for (uint32_t x = 0; x < tx->outputNum; x++)
		sigOps += CBScriptGetSigOpCount(tx->outputs[x]->scriptObject, false);
	return sigOps;
}
bool CBTransactionIsFinal(CBTransaction * tx, uint64_t time, uint64_t height){
	if (tx->lockTime) {
		if (tx->lockTime < (tx->lockTime < CB_LOCKTIME_THRESHOLD ? (int64_t)height : (int64_t)time))
			return true;
		for (uint32_t x = 0; x < tx->inputNum; x++)
			if (tx->inputs[x]->sequence != CB_TRANSACTION_INPUT_FINAL)
				return false;
	}
	return true;
}
CBPrevOut * CBTransactionValidateBasic(CBTransaction * tx, bool coinbase, uint64_t * outputValue, bool * err){
	*err = false;
	if (NOT tx->inputNum || NOT tx->outputNum)
		return NULL;
	uint32_t length;
	if (CBGetMessage(tx)->bytes) // Already have length
		length = CBGetMessage(tx)->bytes->length;
	else{
		// Calculate length. Worthwhile having a cache? ???
		length = CBTransactionCalculateLength(tx);
	}
	if (length > CB_BLOCK_MAX_SIZE){
		return NULL;
	}
	// Check that outputs do not overflow by ensuring they do not go over 21 million bitcoins. There was once an vulnerability in the C++ client on this where an attacker could overflow very large outputs to equal small inputs.
	*outputValue = 0;
	for (uint32_t x = 0; x < tx->outputNum; x++) {
		if (tx->outputs[x]->value > CB_MAX_MONEY)
			return NULL;
		*outputValue += tx->outputs[x]->value;
		if (*outputValue > CB_MAX_MONEY)
			return NULL;
	}
	if (coinbase){
		// Validate input script for coinbase
		if (tx->inputs[0]->scriptObject->length < 2
			|| tx->inputs[0]->scriptObject->length > 100)
			return NULL;
	}else for (uint32_t x = 0; x < tx->inputNum; x++)
		// Check each input for null previous output hashes.
		if (CBByteArrayIsNull(tx->inputs[x]->prevOut.hash))
			return NULL;
	// Check for duplicate transaction output spends and add them to a list of CBPrevOut structures.
	CBPrevOut * prevOutputs = malloc(sizeof(*prevOutputs) * tx->inputNum);
	if (NOT prevOutputs){
		*err = true;
		return NULL;
	}
	for (uint32_t x = 0; x < tx->inputNum; x++) {
		for (uint32_t y = 0; y < x; y++)
			if (CBByteArrayCompare(prevOutputs[y].hash, tx->inputs[x]->prevOut.hash) == CB_COMPARE_EQUAL
				&& prevOutputs[y].index == tx->inputs[x]->prevOut.index) {
				// Duplicate previous output
				free(prevOutputs);
				return NULL;
			}
		prevOutputs[x] = tx->inputs[x]->prevOut;
	}
	return prevOutputs;
}
bool CBValidateProofOfWork(uint8_t * hash, uint32_t target){
	// Get trailing zero bytes
	uint8_t zeroBytes = target >> 24;
	// Check target is less than or equal to maximum.
	if (target > CB_MAX_TARGET)
		return false;
	// Modify the target to the mantissa (significand).
	target &= 0x00FFFFFF;
	// Check mantissa is below 0x800000.
	if (target > 0x7FFFFF)
		return false;
	// Fail if hash is above target. First check leading bytes to significant part. As the hash is seen as little-endian, do this backwards.
	for (uint8_t x = 0; x < 32 - zeroBytes; x++)
		if (hash[31 - x])
			// A byte leading to the significant part is not zero
			return false;
	// Check significant part
	uint32_t significantPart = hash[zeroBytes - 1] << 16;
	significantPart |= hash[zeroBytes - 2] << 8;
	significantPart |= hash[zeroBytes - 3];
	if (significantPart > target)
		return false;
	return true;
}
			

Back
Contributors

NOTICE: cbitcoin 1.0 is discontinued and will not be released past the alpha-4 version. Please refer to the master branch on github for the latest cbitcoin 2.0 code in development.

If you wish to be listed on this page please send an email to cbitcoin@thelibertyportal.com

Business Sponsors

Donate $1000 or more to have your business logo and website link listed. Upto 10 business sponsors allowed. Subject to availablity.

Development Contributors

To be listed here you need to contribute to the development. Please see the github respository.

Matthew Mitchell (Project Leader) - 1D5A1q5d192j5gYuWiP3CSE5fcaaZxe6E9
Christian von Roques
Andrew Miller <amiller@dappervision.com>
linuxdoctor - 1KB3RsW8H7TFV9awpt6MiXsjDqLD15oax3

Gold Donors

Donate $500 or more to have your personal or business name and an optional website link listed. Upto 20 gold donors allowed. Subject to availablity.

Silver Donors

Donate $150 or more to have your personal or business name and an optional website link listed. Upto 30 silver donors allowed. Subject to availablity.

Jud Stephenson

Bronze Donors

Donate $50 or more to have your personal or business name and an optional website link listed. Upto 40 bronze donors allowed. Subject to availablity.

Jose A Arellano - TeamVinh.com International

Other Donors

Donate $15 or more to have your name listed. Unlimited availablity.

K. Darien Freeheart
Patrick Levell