def SplitUnspentCoin(wallet, args, prompt_passwd=True): """ example ``wallet split Ab8RGQEWetkhVqXjPHeGN9LJdbhaFLyUXz neo 1 100`` this would split the second unspent neo vin into 100 vouts :param wallet: :param args (list): A list of arguments as [Address, asset type, unspent index, divisions] :return: bool """ try: addr = wallet.ToScriptHash(args[0]) asset = get_asset_id(wallet, args[1]) index = int(args[2]) divisions = int(args[3]) except Exception as e: logger.info("Invalid arguments specified: %s " % e) return None try: unspentItem = wallet.FindUnspentCoinsByAsset(asset, from_addr=addr)[index] except Exception as e: logger.info( "Could not find unspent item for asset with index %s %s : %s" % (asset, index, e)) return None outputs = split_to_vouts(asset, addr, unspentItem.Output.Value, divisions) contract_tx = ContractTransaction(outputs=outputs, inputs=[unspentItem.Reference]) ctx = ContractParametersContext(contract_tx) wallet.Sign(ctx) print("Splitting: %s " % json.dumps(contract_tx.ToJson(), indent=4)) if prompt_passwd: passwd = prompt("[Password]> ", is_password=True) if not wallet.ValidatePassword(passwd): print("incorrect password") return None if ctx.Completed: contract_tx.scripts = ctx.GetScripts() relayed = NodeLeader.Instance().Relay(contract_tx) if relayed: wallet.SaveTransaction(contract_tx) print("Relayed Tx: %s " % contract_tx.Hash.ToString()) return contract_tx else: print("Could not relay tx %s " % contract_tx.Hash.ToString()) return None
def _make_tx(self, addr_to): """ process transaction """ output1 = TransactionOutput( AssetId = Blockchain.SystemCoin().Hash, # hash of the Gas transaction Value = Fixed8.FromDecimal(2000), # this is how much gas each request will provide script_hash = addr_to # address to send the Gas to ) output2 = TransactionOutput( AssetId = Blockchain.SystemShare().Hash, # hash of the NEO token transaction Value = Fixed8.FromDecimal(100), # this is how much NEO each request will provide script_hash = addr_to # address to send the NEO tokens too ) contract_tx = ContractTransaction() # creates an instance of the transaction contract_tx.outputs = [output1, output2] # outputs the data from the transaction contract_tx = self.wallet.MakeTransaction(contract_tx) # processes transaction print("tx to json: %s " % json.dumps(contract_tx.ToJson(), indent=4)) context = ContractParametersContext(contract_tx, isMultiSig=False) # getting the contract context (listed above) self.wallet.Sign(context) # signs the contract if context.Completed: contract_tx.scripts = context.GetScripts() # gets the script hashes from the context self.wallet.SaveTransaction(contract_tx) # update the state of the coins in the wallet # print("will send tx: %s " % json.dumps(tx.ToJson(),indent=4)) relayed = NodeLeader.Instance().Relay(contract_tx) # relay the transaction to this instance of the node leader if relayed: # if tx relay was successful, inform the user and return the contract transaction print("Relayed Tx: %s " % contract_tx.Hash.ToString()) return contract_tx else: print("Could not relay tx %s " % contract_tx.Hash.ToString()) else: print("Transaction initiated, but the signature is incomplete") print(json.dumps(context.ToJson(), separators=(',', ':'))) return False return False
def _make_tx(self, addr_to): output1 = TransactionOutput( AssetId = Blockchain.SystemCoin().Hash, Value = Fixed8.FromDecimal(2000), script_hash = addr_to ) output2 = TransactionOutput( AssetId = Blockchain.SystemShare().Hash, Value = Fixed8.FromDecimal(100), script_hash = addr_to ) contract_tx = ContractTransaction() contract_tx.outputs = [output1, output2] contract_tx = self.wallet.MakeTransaction(contract_tx) print("tx to json: %s " % json.dumps(contract_tx.ToJson(), indent=4)) context = ContractParametersContext(contract_tx, isMultiSig=False) self.wallet.Sign(context) if context.Completed: contract_tx.scripts = context.GetScripts() self.wallet.SaveTransaction(contract_tx) # print("will send tx: %s " % json.dumps(tx.ToJson(),indent=4)) relayed = NodeLeader.Instance().Relay(contract_tx) if relayed: print("Relayed Tx: %s " % contract_tx.Hash.ToString()) return contract_tx else: print("Could not relay tx %s " % contract_tx.Hash.ToString()) else: print("Transaction initiated, but the signature is incomplete") print(json.dumps(context.ToJson(), separators=(',', ':'))) return False return False
def construct_send_tx(wallet, arguments): from_address = arguments['from'] to_send = arguments['asset'] address_to = arguments['to'] amount = arguments['amount'] user_tx_attributes = arguments.get('attrs', []) assetId = get_asset_id(wallet, to_send) if assetId is None: raise Exception("Asset id not found") scripthash_to = lookup_addr_str(wallet, address_to) if scripthash_to is None: raise Exception("invalid address") scripthash_from = None if from_address is not None: scripthash_from = lookup_addr_str(wallet, from_address) if type(assetId) is NEP5Token: raise Exception("cannot transfer token in this version") f8amount = Fixed8.TryParse(amount, require_positive=True) if f8amount is None: raise Exception("invalid amount format") if type(assetId) is UInt256 and f8amount.value % pow(10, 8 - Blockchain.Default().GetAssetState(assetId.ToBytes()).Precision) != 0: raise Exception("incorrect amount precision") fee = Fixed8.Zero() output = TransactionOutput(AssetId=assetId, Value=f8amount, script_hash=scripthash_to) tx = ContractTransaction(outputs=[output]) ttx = wallet.MakeTransaction(tx=tx, fee=fee, from_addr=scripthash_from) if ttx is None: raise Exception("no funds") standard_contract = wallet.GetStandardAddress() if scripthash_from is not None: signer_contract = wallet.GetContract(scripthash_from) else: signer_contract = wallet.GetContract(standard_contract) if not signer_contract.IsMultiSigContract: data = standard_contract.Data tx.Attributes = [TransactionAttribute(usage=TransactionAttributeUsage.Script, data=data)] # insert any additional user specified tx attributes tx.Attributes = tx.Attributes + user_tx_attributes context = ContractParametersContext(tx, isMultiSig=signer_contract.IsMultiSigContract) logger.info(context.ToJson()) logger.info('*'*60) logger.info(tx.ToJson()) # import pdb # pdb.set_trace() ms = StreamManager.GetStream() writer = BinaryWriter(ms) tx.Serialize(writer) ms.flush() binary_tx = ms.ToArray() print(tx) return {'context': context.ToJson(), 'tx': binary_tx.decode()}
def SplitUnspentCoin(wallet, asset_id, from_addr, index, divisions, fee=Fixed8.Zero()): """ Split unspent asset vins into several vouts Args: wallet (neo.Wallet): wallet to show unspent coins from. asset_id (UInt256): a bytearray (len 32) representing an asset on the blockchain. from_addr (UInt160): a bytearray (len 20) representing an address. index (int): index of the unspent vin to split divisions (int): number of vouts to create fee (Fixed8): A fee to be attached to the Transaction for network processing purposes. Returns: neo.Core.TX.Transaction.ContractTransaction: contract transaction created """ if wallet is None: print("Please open a wallet.") return unspent_items = wallet.FindUnspentCoinsByAsset(asset_id, from_addr=from_addr) if not unspent_items: print(f"No unspent assets matching the arguments.") return if index < len(unspent_items): unspent_item = unspent_items[index] else: print(f"unspent-items: {unspent_items}") print(f"Could not find unspent item for asset {asset_id} with index {index}") return outputs = split_to_vouts(asset_id, from_addr, unspent_item.Output.Value, divisions) # subtract a fee from the first vout if outputs[0].Value > fee: outputs[0].Value -= fee else: print("Fee could not be subtracted from outputs.") return contract_tx = ContractTransaction(outputs=outputs, inputs=[unspent_item.Reference]) ctx = ContractParametersContext(contract_tx) wallet.Sign(ctx) print("Splitting: %s " % json.dumps(contract_tx.ToJson(), indent=4)) try: passwd = prompt("[Password]> ", is_password=True) except KeyboardInterrupt: print("Splitting cancelled") return if not wallet.ValidatePassword(passwd): print("incorrect password") return if ctx.Completed: contract_tx.scripts = ctx.GetScripts() relayed = NodeLeader.Instance().Relay(contract_tx) if relayed: wallet.SaveTransaction(contract_tx) print("Relayed Tx: %s " % contract_tx.Hash.ToString()) return contract_tx else: print("Could not relay tx %s " % contract_tx.Hash.ToString())
def construct_and_send(prompter, wallet, arguments, prompt_password=True): try: if not wallet: print("please open a wallet") return False if len(arguments) < 3: print("Not enough arguments") return False arguments, from_address = get_from_addr(arguments) arguments, user_tx_attributes = get_tx_attr_from_args(arguments) to_send = get_arg(arguments) address_to = get_arg(arguments, 1) amount = get_arg(arguments, 2) assetId = get_asset_id(wallet, to_send) if assetId is None: print("Asset id not found") return False scripthash_to = lookup_addr_str(wallet, address_to) if scripthash_to is None: print("invalid address") return False scripthash_from = None if from_address is not None: scripthash_from = lookup_addr_str(wallet, from_address) # if this is a token, we will use a different # transfer mechanism if type(assetId) is NEP5Token: return do_token_transfer(assetId, wallet, from_address, address_to, amount_from_string(assetId, amount), prompt_passwd=prompt_password) f8amount = Fixed8.TryParse(amount, require_positive=True) if f8amount is None: print("invalid amount format") return False if type(assetId) is UInt256 and f8amount.value % pow( 10, 8 - Blockchain.Default().GetAssetState( assetId.ToBytes()).Precision) != 0: print("incorrect amount precision") return False fee = Fixed8.Zero() output = TransactionOutput(AssetId=assetId, Value=f8amount, script_hash=scripthash_to) tx = ContractTransaction(outputs=[output]) ttx = wallet.MakeTransaction(tx=tx, change_address=None, fee=fee, from_addr=scripthash_from) if ttx is None: print("insufficient funds") return False if prompt_password: passwd = prompt("[Password]> ", is_password=True) if not wallet.ValidatePassword(passwd): print("incorrect password") return False standard_contract = wallet.GetStandardAddress() if scripthash_from is not None: signer_contract = wallet.GetContract(scripthash_from) else: signer_contract = wallet.GetContract(standard_contract) if not signer_contract.IsMultiSigContract: data = standard_contract.Data tx.Attributes = [ TransactionAttribute(usage=TransactionAttributeUsage.Script, data=data) ] # insert any additional user specified tx attributes tx.Attributes = tx.Attributes + user_tx_attributes context = ContractParametersContext( tx, isMultiSig=signer_contract.IsMultiSigContract) wallet.Sign(context) print(context.ScriptHashes) for s in context.GetScripts(): print(s.ToJson()) print(tx.ToJson()) raise if context.Completed: tx.scripts = context.GetScripts() # print("will send tx: %s " % json.dumps(tx.ToJson(),indent=4)) relayed = NodeLeader.Instance().Relay(tx) if relayed: wallet.SaveTransaction(tx) print("Relayed Tx: %s " % tx.Hash.ToString()) return tx else: print("Could not relay tx %s " % tx.Hash.ToString()) else: print("Transaction initiated, but the signature is incomplete") print(json.dumps(context.ToJson(), separators=(',', ':'))) return False except Exception as e: print("could not send: %s " % e) traceback.print_stack() traceback.print_exc() return False