import "../types/structs.scrypt"; import "stdUtils.scrypt"; import "txUtils.scrypt"; library _opcat_labs_scrypt_ts_opcat_4_0_0__rs__ContextUtils { static const PrivKey privKey = PrivKey(0x26f00fe2340a84335ebdf30f57e9bb58487117b29355718f5e46bf5168d7df97); static const PubKey pubKey = PubKey(b'02ba79df5f8ae7604a9830f03c7933028186aede0675a16f025dc4f8be8eec0382'); static const int invK = 0xc8ffdbaa05d93aa4ede79ec58f06a72562048b775a3507c2bf44bde4f007c40a; static const int r = 0x1008ce7480da41702918d1ec8e6849ba32b4d65b1e40dc669c31a1e6306b266c; static const bytes rBigEndian = b'1008ce7480da41702918d1ec8e6849ba32b4d65b1e40dc669c31a1e6306b266c'; static function normalize(int k, int modulus) : int { int res = k % modulus; return (res < 0) ? res + modulus : res; } static function sign(int h, PrivKey privKey, int inverseK, int r, bytes rBigEndian, bytes sigHashType) : Sig { int s = inverseK * (h + r * privKey); s = _opcat_labs_scrypt_ts_opcat_4_0_0__rs__ContextUtils.normalize(s, 115792089237316195423570985008687907852837564279074904382605163141518161494337); if(s > 115792089237316195423570985008687907852837564279074904382605163141518161494337 / 2) { s = 115792089237316195423570985008687907852837564279074904382605163141518161494337 - s; } int rlen = (len(rBigEndian)); int slen = len(pack(s)); bytes sBigEndian = reverseBytes(num2bin(s, 32), (32))[32 - slen : len(reverseBytes(num2bin(s, 32), (32)))]; int l = 4 + rlen + (slen); bytes rb = b'30' + pack(l) + b'02' + pack(rlen) + rBigEndian + b'02' + pack(slen) + sBigEndian + sigHashType; return Sig(rb); } static function fromBEUnsigned(bytes b) : int { return unpack(reverseBytes(b, 32) + b'00'); } static function checkSHPreimage(_opcat_labs_scrypt_ts_opcat_4_0_0__rs__SHPreimage shPreimage, bytes sigHashType) : Sig { SigHashPreimage preimage = _opcat_labs_scrypt_ts_opcat_4_0_0__rs__ContextUtils.serializeSHPreimage(shPreimage); bytes h = hash256(preimage); Sig sig = _opcat_labs_scrypt_ts_opcat_4_0_0__rs__ContextUtils.sign(_opcat_labs_scrypt_ts_opcat_4_0_0__rs__ContextUtils.fromBEUnsigned(h), _opcat_labs_scrypt_ts_opcat_4_0_0__rs__ContextUtils.privKey, 90914631784428570546048907090666684794265392153046400654824470772421497439242, 7252565254521500021189571868467740368187828957595681190666767817830690399852, _opcat_labs_scrypt_ts_opcat_4_0_0__rs__ContextUtils.rBigEndian, sigHashType); return sig; } static function serializeSHPreimage(_opcat_labs_scrypt_ts_opcat_4_0_0__rs__SHPreimage shPreimage) : SigHashPreimage { require(len(shPreimage.nVersion) == 4); require(len(shPreimage.hashPrevouts) == 32); require(shPreimage.inputIndex >= 0); require(len(shPreimage.outpoint) == 36); require(len(shPreimage.spentScriptHash) == 32); require(len(shPreimage.spentDataHash) == 32); require(shPreimage.value >= 0); require(len(shPreimage.nSequence) == 4); require(len(shPreimage.hashSpentAmounts) == 32); require(len(shPreimage.hashSpentScriptHashes) == 32); require(len(shPreimage.hashSpentDataHashes) == 32); require(len(shPreimage.hashSequences) == 32); require(len(shPreimage.hashOutputs) == 32); require(shPreimage.nLockTime >= 0); require(shPreimage.sigHashType == 1 || shPreimage.sigHashType == 2 || shPreimage.sigHashType == 3 || shPreimage.sigHashType == 0x81 || shPreimage.sigHashType == 0x82 || shPreimage.sigHashType == 0x83); bytes preimage = shPreimage.nVersion + shPreimage.hashPrevouts + _opcat_labs_scrypt_ts_opcat_4_0_0__rs__StdUtils.toLEUnsigned(shPreimage.inputIndex, 4) + shPreimage.outpoint + shPreimage.spentScriptHash + shPreimage.spentDataHash + _opcat_labs_scrypt_ts_opcat_4_0_0__rs__TxUtils.satoshisToByteString(shPreimage.value) + shPreimage.nSequence + shPreimage.hashSpentAmounts + shPreimage.hashSpentScriptHashes + shPreimage.hashSpentDataHashes + shPreimage.hashSequences + shPreimage.hashOutputs + _opcat_labs_scrypt_ts_opcat_4_0_0__rs__StdUtils.toLEUnsigned(shPreimage.nLockTime, 4) + num2bin(shPreimage.sigHashType, 4); return SigHashPreimage(preimage); } static function getOutpoint(_opcat_labs_scrypt_ts_opcat_4_0_0__rs__SHPreimage shPreimage) : _opcat_labs_scrypt_ts_opcat_4_0_0__rs__Outpoint { return {shPreimage.outpoint[0 : 32], _opcat_labs_scrypt_ts_opcat_4_0_0__rs__StdUtils.byteStringToUInt32(shPreimage.outpoint[32 : 36])}; } static function checkPrevouts(bytes prevouts, bytes t_hashPrevouts, int t_inputIndex, int t_inputCount) : _opcat_labs_scrypt_ts_opcat_4_0_0__rs__Outpoint { require(hash256(prevouts) == t_hashPrevouts); require(t_inputIndex < t_inputCount); require(t_inputCount == _opcat_labs_scrypt_ts_opcat_4_0_0__rs__StdUtils.checkLenDivisibleBy(prevouts, 36)); bytes b = prevouts[t_inputIndex * 36 : (t_inputIndex + 1) * 36]; return {b[0 : 32], _opcat_labs_scrypt_ts_opcat_4_0_0__rs__StdUtils.byteStringToUInt32(b[32 : 36])}; } static function checkSpentScripts(bytes spentScriptHashes, bytes t_hashSpentScripts, int t_inputCount) : bool { require(hash256(spentScriptHashes) == t_hashSpentScripts); require(t_inputCount == _opcat_labs_scrypt_ts_opcat_4_0_0__rs__StdUtils.checkLenDivisibleBy(spentScriptHashes, 32)); return true; } static function checkSpentAmounts(bytes spentAmounts, bytes hashSpentAmounts) : int { require(hash256(spentAmounts) == hashSpentAmounts); return _opcat_labs_scrypt_ts_opcat_4_0_0__rs__StdUtils.checkLenDivisibleBy(spentAmounts, 8); } static function checkSpentDataHashes(bytes spentDataHashes, bytes hashSpentDataHashes, int inputCount) : bool { require(hash256(spentDataHashes) == hashSpentDataHashes); require(inputCount == _opcat_labs_scrypt_ts_opcat_4_0_0__rs__StdUtils.checkLenDivisibleBy(spentDataHashes, 32)); return true; } static function getSpentScriptHash(bytes spentScriptHashes, int inputIndex) : bytes { return spentScriptHashes[inputIndex * 32 : (inputIndex + 1) * 32]; } static function getSpentAmount(bytes spentAmounts, int inputIndex) : int { return _opcat_labs_scrypt_ts_opcat_4_0_0__rs__StdUtils.fromLEUnsigned(spentAmounts[inputIndex * 8 : (inputIndex + 1) * 8]); } static function getSpentDataHash(bytes spentDataHashes, int inputIndex) : bytes { return spentDataHashes[inputIndex * 32 : (inputIndex + 1) * 32]; } static function checknLockTime(_opcat_labs_scrypt_ts_opcat_4_0_0__rs__SHPreimage shPreimage, int nlockTime) : bool { int nSequence = _opcat_labs_scrypt_ts_opcat_4_0_0__rs__StdUtils.fromLEUnsigned(shPreimage.nSequence); return (nSequence < 4294967295 && (nlockTime < 500000000 ? shPreimage.nLockTime < 500000000 : true) && shPreimage.nLockTime >= nlockTime); } }