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 _generate_tx(self): wallet = self.GetWallet1() output = TransactionOutput(AssetId=Blockchain.SystemShare().Hash, Value=Fixed8.One(), script_hash=LeaderTestCase.wallet_1_script_hash) contract_tx = ContractTransaction(outputs=[output]) wallet.MakeTransaction(contract_tx) ctx = ContractParametersContext(contract_tx) wallet.Sign(ctx) contract_tx.scripts = ctx.GetScripts() return contract_tx
def test_9_send_neo_tx(self): wallet = self.GetWallet1() tx = ContractTransaction() tx.outputs = [TransactionOutput(Blockchain.SystemShare().Hash, Fixed8.FromDecimal(10.0), self.import_watch_addr)] tx = wallet.MakeTransaction(tx) cpc = ContractParametersContext(tx) wallet.Sign(cpc) tx.scripts = cpc.GetScripts() result = NodeLeader.Instance().Relay(tx) self.assertEqual(result, True)
def _generate_tx(self, amount): wallet = self.GetWallet1() output = TransactionOutput( AssetId=Blockchain.SystemShare().Hash, Value=amount, script_hash=LeaderTestCase.wallet_1_script_hash) contract_tx = ContractTransaction(outputs=[output]) try: wallet.MakeTransaction(contract_tx) except ValueError: pass ctx = ContractParametersContext(contract_tx) wallet.Sign(ctx) contract_tx.scripts = ctx.GetScripts() return contract_tx
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 test_9_send_neo_tx(self): with patch('neo.Network.node.NeoNode.relay', return_value=self.async_return(True)): wallet = self.GetWallet1() tx = ContractTransaction() tx.outputs = [TransactionOutput(Blockchain.SystemShare().Hash, Fixed8.FromDecimal(10.0), self.import_watch_addr)] try: tx = wallet.MakeTransaction(tx) except (ValueError): pass cpc = ContractParametersContext(tx) wallet.Sign(cpc) tx.scripts = cpc.GetScripts() nodemgr = NodeManager() # we need at least 1 node for relay to be mocked nodemgr.nodes = [NeoNode(object, object)] result = nodemgr.relay(tx) self.assertEqual(result, True)
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) arguments, owners = get_owners_from_params(arguments) arguments, priority_fee = get_fee(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, tx_attributes=user_tx_attributes) 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() if priority_fee is not None: fee = priority_fee print("sending with fee: %s " % fee.ToString()) 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 and owners is None: 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 if owners: owners = list(owners) for owner in owners: tx.Attributes.append( TransactionAttribute(usage=TransactionAttributeUsage.Script, data=owner)) context = ContractParametersContext(tx, isMultiSig=signer_contract.IsMultiSigContract) wallet.Sign(context) if owners: owners = list(owners) gather_signatures(context, tx, owners) 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
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 example1(): neo_asset_id = Blockchain.GetSystemShare().Hash gas_asset_id = Blockchain.GetSystemCoin().Hash source_address = "AJQ6FoaSXDFzA6wLnyZ1nFN7SGSN2oNTc3" source_script_hash = address_to_scripthash(source_address) destination_address = "Ad9A1xPbuA5YBFr1XPznDwBwQzdckAjCev" destination_script_hash = address_to_scripthash(destination_address) # Let's start with building a ContractTransaction # The constructor already sets the correct `Type` and `Version` fields, so we do not have to worry about that contract_tx = ContractTransaction() # the ContractTransaction type has no special data, so we do not have to do anything there # Next we can add Attributes if we want. Again the various types are described in point 4. of the main link above # We will add a simple "description" contract_tx.Attributes.append( TransactionAttribute(usage=TransactionAttributeUsage.Description, data="My raw contract transaction description")) # The next field we will set are the inputs. The inputs neo-python expects are of the type ``CoinReference`` # To create these inputs we will need the usual `PrevHash` and `PrevIndex` values. # You can get the required data by using e.g. the neoscan.io API: https://api.neoscan.io/docs/index.html#api-v1-get-3 # The `PrevHash` field equals to neoscan's `balance.unspent[index].txid` key, and `PrevIndex` comes from `balance.unspent[index].n` # It is up to the transaction creator to make sure that the sum of all input ``value`` fields is equal to or bigger than the amount that's intended to be send # The below values are taken from data out of the `neo-test1-w.wallet` fixture wallet (a wallet neo-python uses for internal testing) input1 = CoinReference(prev_hash=UInt256(data=binascii.unhexlify( '949354ea0a8b57dfee1e257a1aedd1e0eea2e5837de145e8da9c0f101bfccc8e')), prev_index=1) contract_tx.inputs = [input1] # Next we will create the outputs. # The above input has a value of 50. We will create 2 outputs. # 1 output for sending 3 NEO to a specific destination address send_to_destination_output = TransactionOutput( AssetId=neo_asset_id, Value=Fixed8.FromDecimal(3), script_hash=destination_script_hash) # and a second output for sending the change back to ourselves return_change_output = TransactionOutput(AssetId=neo_asset_id, Value=Fixed8.FromDecimal(47), script_hash=source_script_hash) contract_tx.outputs = [send_to_destination_output, return_change_output] # at this point we've build our unsigned transaction and it's time to sign it before we get the raw output that we can send to the network via RPC # we need to create a Wallet instance for helping us with signing wallet = UserWallet.Create('path', to_aes_key('mypassword'), generate_default_key=False) # if you have a WIF use the following # this WIF comes from the `neo-test1-w.wallet` fixture wallet private_key = KeyPair.PrivateKeyFromWIF( "Ky94Rq8rb1z8UzTthYmy1ApbZa9xsKTvQCiuGUZJZbaDJZdkvLRV") # if you have a NEP2 encrypted key use the following instead # private_key = KeyPair.PrivateKeyFromNEP2("NEP2 key string", "password string") # we add the key to our wallet wallet.CreateKey(private_key) # and now we're ready to sign context = ContractParametersContext(contract_tx) wallet.Sign(context) contract_tx.scripts = context.GetScripts() print(contract_tx.Hash.ToString()) raw_tx = contract_tx.ToArray()
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) 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
def construct_and_send(prompter, wallet, arguments): try: if not wallet: print("please open a wallet") return if len(arguments) < 3: print("Not enough arguments") return to_send = get_arg(arguments) address_to = get_arg(arguments, 1) amount = get_arg(arguments, 2) address_from = get_arg(arguments, 3) assetId = None if to_send.lower() == 'neo': assetId = Blockchain.Default().SystemShare().Hash elif to_send.lower() == 'gas': assetId = Blockchain.Default().SystemCoin().Hash elif Blockchain.Default().GetAssetState(to_send): assetId = Blockchain.Default().GetAssetState(to_send).AssetId scripthash = wallet.ToScriptHash(address_to) if scripthash is None: print("invalid address") return f8amount = Fixed8.TryParse(amount) if f8amount is None: print("invalid amount format") return if f8amount.value % pow(10, 8 - Blockchain.Default().GetAssetState(assetId.ToBytes()).Precision) != 0: print("incorrect amount precision") return fee = Fixed8.Zero() if get_arg(arguments, 3): fee = Fixed8.TryParse(get_arg(arguments, 3)) output = TransactionOutput(AssetId=assetId, Value=f8amount, script_hash=scripthash) tx = ContractTransaction(outputs=[output]) ttx = wallet.MakeTransaction(tx=tx, change_address=None, fee=fee) if ttx is None: print("insufficient funds") return passwd = prompt("[Password]> ", completer=prompter.completer, is_password=True, history=prompter.history, get_bottom_toolbar_tokens=prompter.get_bottom_toolbar, style=prompter.token_style) if not wallet.ValidatePassword(passwd): print("incorrect password") return context = ContractParametersContext(tx) wallet.Sign(context) if context.Completed: tx.scripts = context.GetScripts() wallet.SaveTransaction(tx) relayed = NodeLeader.Instance().Relay(tx) if relayed: print("Relayed Tx: %s " % tx.Hash.ToString()) else: print("Could not relay tx %s " % tx.Hash.ToString()) else: print("Could not sign transaction") return except Exception as e: print("could not send: %s " % e) traceback.print_stack() traceback.print_exc()