def tx_outputs(self, pubkey, outputs, overheads): """ Get outputs to generate a transaction with a given amount of money :param str pubkey: The target pubkey of the transaction :param list outputs: The amount to send :param list inputs: The inputs used to send the given amount of money :param list overheads: The overheads used to send the given amount of money :return: The list of outputs to use in the transaction document """ total = [] outputs_bases = set(o[1] for o in outputs) for base in outputs_bases: output_sum = 0 for o in outputs: if o[1] == base: output_sum += o[0] total.append(OutputSource(output_sum, base, output.Condition.token(output.SIG.token(pubkey)))) overheads_bases = set(o[1] for o in overheads) for base in overheads_bases: overheads_sum = 0 for o in overheads: if o[1] == base: overheads_sum += o[0] total.append(OutputSource(overheads_sum, base, output.Condition.token(output.SIG.token(self.pubkey)))) return total
def test_output_available(self): """ Only tests for single condition without operators """ # SIG pubkey = "GB8iMAzq1DNmFe3ZxFTBQkGhq4fszTg1gZvx3XCkZXYH" sig_condition = SIG.token(pubkey).compose() condition = OutputSource.condition_from_text(sig_condition) self.assertTrue(output_available(condition, eq, pubkey)) self.assertFalse(output_available(condition, ne, pubkey)) # XHX sha_hash = "309BC5E644F797F53E5A2065EAF38A173437F2E6" xhx_condition = XHX.token(sha_hash).compose() condition = OutputSource.condition_from_text(xhx_condition) self.assertTrue(output_available(condition, eq, sha_hash)) self.assertFalse(output_available(condition, ne, sha_hash)) # CSV time = 1654300 csv_condition = CSV.token(time).compose() condition = OutputSource.condition_from_text(csv_condition) self.assertTrue(output_available(condition, ge, time)) self.assertFalse(output_available(condition, lt, time)) # CLTV timestamp = 2594024 cltv_condition = CLTV.token(timestamp).compose() condition = OutputSource.condition_from_text(cltv_condition) self.assertTrue(output_available(condition, ge, timestamp)) self.assertFalse(output_available(condition, lt, timestamp))
def get_transaction_document(current_block: dict, source: dict, from_pubkey: str, to_pubkey: str) -> Transaction: """ Return a Transaction document :param current_block: Current block infos :param source: Source to send :param from_pubkey: Public key of the issuer :param to_pubkey: Public key of the receiver :return: Transaction """ # list of inputs (sources) inputs = [ InputSource( amount=source["amount"], base=source["base"], source=source["type"], origin_id=source["identifier"], index=source["noffset"], ) ] # list of issuers of the inputs issuers = [from_pubkey] # list of unlocks of the inputs unlocks = [ Unlock( # inputs[index] index=0, # unlock inputs[index] if signatures[0] is from public key of issuers[0] parameters=[SIGParameter(0)], ) ] # lists of outputs outputs = [ OutputSource( amount=source["amount"], base=source["base"], condition="SIG({0})".format(to_pubkey), ) ] transaction = Transaction( version=TRANSACTION_VERSION, currency=current_block["currency"], blockstamp=BlockUID(current_block["number"], current_block["hash"]), locktime=0, issuers=issuers, inputs=inputs, unlocks=unlocks, outputs=outputs, comment="", signatures=[], ) return transaction
def get_transaction_document(current_block, source, from_pubkey, to_pubkey): """ Return a Transaction document :param dict current_block: Current block infos :param dict source: Source to send :param str from_pubkey: Public key of the issuer :param str to_pubkey: Public key of the receiver :return: Transaction """ # list of inputs (sources) inputs = [ InputSource(amount=source['amount'], base=source['base'], source=source['type'], origin_id=source['identifier'], index=source['noffset']) ] # list of issuers of the inputs issuers = [from_pubkey] # list of unlocks of the inputs unlocks = [ Unlock( # inputs[index] index=0, # unlock inputs[index] if signatures[0] is from public key of issuers[0] parameters=[SIGParameter(0)]) ] # lists of outputs outputs = [ OutputSource( amount=source['amount'], base=source['base'], # only the receiver of the output can use it as input in another transaction conditions=Condition.token(SIG.token(to_pubkey))) ] transaction = Transaction(version=TRANSACTION_VERSION, currency=current_block['currency'], blockstamp=BlockUID(current_block['number'], current_block['hash']), locktime=0, issuers=issuers, inputs=inputs, unlocks=unlocks, outputs=outputs, comment='', signatures=None) return transaction
def generate_output(listoutput, unitbase, rest, recipient_address): while rest > 0: outputAmount = truncBase(rest, unitbase) rest -= outputAmount if outputAmount > 0: outputAmount = int(outputAmount / math.pow(10, unitbase)) listoutput.append( OutputSource( amount=str(outputAmount), base=unitbase, condition="SIG({0})".format(recipient_address), )) unitbase = unitbase - 1
def test_transaction_document_generation(self): transaction = Transaction( version=10, currency="gtest", blockstamp=BlockUID( 8979, "000041DF0CCA173F09B5FBA48F619D4BC934F12ADF1D0B798639EB2149C4A8CC" ), locktime=0, issuers=list("8kXygUHh1vLjmcRzXVM86t38EL8dfFJgfBeHmkaWLamu"), inputs=[InputSource.from_inline(input_source_str)], unlocks=[Unlock(index=0, parameters=[SIGParameter(0)])], outputs=[OutputSource.from_inline(output_source_str)], comment="", signatures=[], ) self.assertTrue(transaction.time is None) self.assertTrue(transaction.currency == "gtest") self.assertTrue(transaction.inputs[0].amount == 30)
def test_transaction_equality(self): t1 = Transaction.from_signed_raw(tx_raw) t2 = Transaction.from_signed_raw(tx_raw) self.assertTrue(t1 == t2) t2.signatures = ["NSTN"] self.assertFalse(t1 == t2) t2 = Transaction.from_signed_raw(tx_raw) t2.issuers = ["NSTRNRST"] self.assertFalse(t1 == t2) t2 = Transaction.from_signed_raw(tx_raw) t2.time = 123 self.assertFalse(t1 == t2) t2 = Transaction.from_signed_raw(tx_raw) t2.inputs = [InputSource.from_inline(input_source_str)] self.assertFalse(t1 == t2) t2 = Transaction.from_signed_raw(tx_raw) t2.outputs = [OutputSource.from_inline(output_source_str)] self.assertFalse(t1 == t2)
def test_outputsource_inline_condition(self): o = OutputSource.from_inline(output_source_str) self.assertEqual(o.inline_condition(), output_source_str.split(":")[2])
def test_outputsource_from_inline(self): o = OutputSource.from_inline(output_source_str) self.assertEqual(o.inline(), output_source_str)
def test_outputsource_inline_condition(self): output_source_str = "460:0:SIG(8kXygUHh1vLjmcRzXVM86t38EL8dfFJgfBeHmkaWLamu)" o = OutputSource.from_inline(output_source_str) self.assertEqual(o.inline_condition(), output_source_str.split(":")[2])
InputSource( 257, 0, "T", "16F1CF9C9B89BB8C34A945F56073AB3C3ACFD858D5FA420047BA7AED1575D1FE", 1, ), ], unlocks=[ Unlock(index=0, parameters=[SIGParameter(0)]), Unlock(index=1, parameters=[SIGParameter(0)]), ], outputs=[ OutputSource( amount=str(1000), base=0, condition="SIG(DBM6F5ChMJzpmkUdL5zD9UXKExmZGfQ1AgPDQy4MxSBw)", ), OutputSource( amount=str(4000), base=0, condition="SIG(4szFkvQ5tzzhwcfUtZD32hdoG2ZzhvG3ZtfR61yjnxdw)", ), OutputSource( amount=str(5000), base=0, condition="SIG(BFb5yv8z1fowR6Z8mBXTALy5z7gHfMU976WtXhmRsUMh)", ), ], comment="Test comment", signatures=[],