def test_various_methods(self): self.assertEqual(Fixed8.FD(), Fixed8(100000000)) self.assertEqual(Fixed8.FD(), Fixed8.One()) sat = Fixed8.Satoshi() self.assertEqual(sat, Fixed8(1)) self.assertEqual(sat.value, 1) negsat = Fixed8.NegativeSatoshi() self.assertEqual(negsat, Fixed8(-1)) self.assertEqual(negsat.value, -1) zero = Fixed8.Zero() self.assertEqual(zero, Fixed8(0)) self.assertEqual(zero.value, 0) decimal = 1.2 f8 = Fixed8.FromDecimal(decimal) self.assertEqual(f8.value, f8.GetData()) f8 = Fixed8.TryParse(123.123) f8 = Fixed8.TryParse(123) self.assertEqual(f8.Size(), 8) zero = Fixed8.TryParse(0) self.assertEqual(zero, Fixed8(0)) # with self.assertRaises(Exception): self.assertEqual(Fixed8.TryParse("foo"), None) self.assertEqual(Fixed8.TryParse(-1, require_positive=True), None)
def SystemFee(self): """ Get the system fee. Returns: Fixed8: """ return self.Gas // Fixed8.FD()
def split_to_vouts(asset, addr, input_val, divisions): divisor = Fixed8(divisions) new_amounts = input_val / divisor outputs = [] total = Fixed8.Zero() if asset == Blockchain.Default().SystemShare().Hash: if new_amounts % Fixed8.FD() > Fixed8.Zero(): new_amounts = new_amounts.Ceil() while total < input_val: if total + new_amounts < input_val: outputs.append(TransactionOutput(asset, new_amounts, addr)) total += new_amounts else: diff = input_val - total outputs.append(TransactionOutput(asset, diff, addr)) total += diff return outputs
def MakeTransaction(self, tx, change_address=None, fee=Fixed8(0), from_addr=None, use_standard=False, watch_only_val=0, exclude_vin=None, use_vins_for_asset=None): """ This method is used to to calculate the necessary TransactionInputs (CoinReferences) and TransactionOutputs to be used when creating a transaction that involves an exchange of system assets, ( NEO, Gas, etc ). Args: tx (Transaction): The Transaction to be used. change_address (UInt160): The address any change for the transaction should be returned to. fee (Fixed8): A fee to be attached to the Transaction for network processing purposes. from_addr (UInt160): If present, all CoinReferences selected will only come from this address. use_standard (bool): If true, only CoinReferences from standard addresses ( not contracts that are smart contracts ) will be used. watch_only_val (int): 0 or CoinState.WATCH_ONLY, if present only choose coins that are in a WatchOnly address. exclude_vin (list): A list of CoinReferences to NOT use in the making of this tx. use_vins_for_asset (list): A list of CoinReferences to use. Returns: tx: (Transaction) Returns the transaction with oupdated inputs and outputs. """ tx.ResetReferences() tx.ResetHashData() if not tx.outputs: tx.outputs = [] if not tx.inputs: tx.inputs = [] fee = fee + (tx.SystemFee() * Fixed8.FD()) paytotal = {} if tx.Type != int.from_bytes(TransactionType.IssueTransaction, 'little'): for key, group in groupby(tx.outputs, lambda x: x.AssetId): sum = Fixed8(0) for item in group: sum = sum + item.Value paytotal[key] = sum else: paytotal = {} if fee > Fixed8.Zero(): if Blockchain.SystemCoin().Hash in paytotal.keys(): paytotal[Blockchain.SystemCoin().Hash] = paytotal[Blockchain.SystemCoin().Hash] + fee else: paytotal[Blockchain.SystemCoin().Hash] = fee paycoins = {} self._vin_exclude = exclude_vin # import pdb # pdb.set_trace() for assetId, amount in paytotal.items(): if use_vins_for_asset is not None and len(use_vins_for_asset) > 0 and use_vins_for_asset[1] == assetId: paycoins[assetId] = self.FindCoinsByVins(use_vins_for_asset[0]) else: paycoins[assetId] = self.FindUnspentCoinsByAssetAndTotal( assetId, amount, from_addr=from_addr, use_standard=use_standard, watch_only_val=watch_only_val) self._vin_exclude = None for key, unspents in paycoins.items(): if unspents is None: if not self.IsSynced: logger.warning("Wait for your wallet to be synced before doing " "transactions. To check enter 'wallet' and look at " "'percent_synced', it should be 100. Also the blockchain " "should be up to the latest blocks (see Progress). Issuing " "'wallet rebuild' restarts the syncing process.") return None else: logger.error("insufficient funds for asset id: %s " % key) return None input_sums = {} for assetId, unspents in paycoins.items(): sum = Fixed8(0) for coin in unspents: sum = sum + coin.Output.Value input_sums[assetId] = sum if not change_address: change_address = self.GetChangeAddress(from_addr=from_addr) new_outputs = [] for assetId, sum in input_sums.items(): if sum > paytotal[assetId]: difference = sum - paytotal[assetId] output = TransactionOutput(AssetId=assetId, Value=difference, script_hash=change_address) new_outputs.append(output) inputs = [] for item in paycoins.values(): for ref in item: inputs.append(ref.Reference) tx.inputs = inputs tx.outputs = tx.outputs + new_outputs return tx