def token_history(wallet, db, args): if len(args) < 1: print("Please provide the token symbol of the token you wish consult") return False if not db: print("Unable to fetch history, notification database not enabled") return False token = get_asset_id(wallet, args[0]) if not isinstance(token, NEP5Token): print("The given symbol does not represent a loaded NEP5 token") return False events = db.get_by_contract(token.ScriptHash) addresses = wallet.Addresses print("-----------------------------------------------------------") print("Recent transaction history (last = more recent):") for event in events: if event.Type != 'transfer': continue if event.AddressFrom in addresses: print( f"[{event.AddressFrom}]: Sent {string_from_amount(token, event.Amount)}" f" {args[0]} to {event.AddressTo}") if event.AddressTo in addresses: print( f"[{event.AddressTo}]: Received {string_from_amount(token, event.Amount)}" f" {args[0]} from {event.AddressFrom}") print("-----------------------------------------------------------") return True
def token_mint(wallet, args, prompt_passwd=True): token = get_asset_id(wallet, args[0]) mint_to_addr = args[1] if len(args) < 3: raise Exception("please specify assets to attach") asset_attachments = args[2:] tx, fee, results = token.Mint(wallet, mint_to_addr, asset_attachments) if results[0] is not None: print("\n-----------------------------------------------------------") print("[%s] Will mint tokens to address: %s " % (token.symbol, mint_to_addr)) print("Fee: %s " % (fee.value / Fixed8.D)) print("-------------------------------------------------------------\n") if prompt_passwd: passwd = prompt("[Password]> ", is_password=True) if not wallet.ValidatePassword(passwd): print("incorrect password") return return InvokeWithTokenVerificationScript(wallet, tx, token, fee) else: print("Could not register addresses: %s " % str(results[0])) return False
def parse_send_many_params(self, params): if type(params[0]) is not list: raise JsonRpcError(-32602, "Invalid params") if len(params) not in [1, 2, 3]: raise JsonRpcError(-32602, "Invalid params") output = [] for info in params[0]: asset = get_asset_id(self.wallet, info['asset']) if not type(asset) is UInt256: raise JsonRpcError(-32602, "Invalid params") address = info["address"] try: address = self.wallet.ToScriptHash(address) except Exception: raise JsonRpcError(-32602, "Invalid params") amount = Fixed8.TryParse(info["value"], require_positive=True) if not amount or float(info["value"]) == 0: raise JsonRpcError(-32602, "Invalid params") tx_output = TransactionOutput(AssetId=asset, Value=amount, script_hash=address) output.append(tx_output) contract_tx = ContractTransaction(outputs=output) fee = Fixed8.TryParse(params[1]) if len(params) >= 2 else Fixed8.Zero() if fee < Fixed8.Zero(): raise JsonRpcError(-32602, "Invalid params") change_addr_sh = None if len(params) >= 3: change_addr = params[2] try: change_addr_sh = self.wallet.ToScriptHash(change_addr) except Exception: raise JsonRpcError(-32602, "Invalid params") return contract_tx, fee, change_addr_sh
def token_crowdsale_register(wallet, args, prompt_passwd=True): token = get_asset_id(wallet, args[0]) args, from_addr = get_from_addr(args) if len(args) < 2: raise Exception("Specify addr to register for crowdsale") register_addr = args[1:] tx, fee, results = token.CrowdsaleRegister(wallet, register_addr) if results[0].GetBigInteger() > 0: print("\n-----------------------------------------------------------") print("[%s] Will register addresses for crowdsale: %s " % (token.symbol, register_addr)) print("Fee: %s " % (fee.value / Fixed8.D)) print("-------------------------------------------------------------\n") if prompt_passwd: passwd = prompt("[Password]> ", is_password=True) if not wallet.ValidatePassword(passwd): print("incorrect password") return return InvokeContract(wallet, tx, fee, from_addr) else: print("Could not register addresses: %s " % str(results[0])) return False
def token_approve_allowance(wallet, args, prompt_passwd=True): if len(args) != 4: print("please provide a token symbol, from address, to address, and amount") return False token = get_asset_id(wallet, args[0]) approve_from = args[1] approve_to = args[2] amount = amount_from_string(token, args[3]) tx, fee, results = token.Approve(wallet, approve_from, approve_to, amount) if tx is not None and results is not None and len(results) > 0: if results[0].GetBigInteger() == 1: print("\n-----------------------------------------------------------") print("Approve allowance of %s %s from %s to %s" % (string_from_amount(token, amount), token.symbol, approve_from, approve_to)) print("Transfer fee: %s " % (fee.value / Fixed8.D)) print("-------------------------------------------------------------\n") if prompt_passwd: passwd = prompt("[Password]> ", is_password=True) if not wallet.ValidatePassword(passwd): print("incorrect password") return return InvokeContract(wallet, tx, fee) print("could not transfer tokens") return False
def ShowUnspentCoins(wallet, args): addr = None asset_type = None watch_only = 0 try: for item in args: if len(item) == 34: addr = wallet.ToScriptHash(item) elif len(item) > 1: asset_type = get_asset_id(wallet, item) if item == '--watch': watch_only = 64 except Exception as e: print("Invalid arguments specified") if asset_type: unspents = wallet.FindUnspentCoinsByAsset(asset_type, from_addr=addr, watch_only_val=watch_only) else: unspents = wallet.FindUnspentCoins(from_addr=addr, watch_only_val=watch_only) for unspent in unspents: print('\n-----------------------------------------------') print(json.dumps(unspent.ToJson(), indent=4)) print(unspent.RefToBytes())
def parse_send_from_params(self, params): if len(params) not in [4, 5, 6]: raise JsonRpcError(-32602, "Invalid params") asset_id = get_asset_id(self.wallet, params[0]) if not type(asset_id) is UInt256: raise JsonRpcError(-32602, "Invalid params") address_from = params[1] try: address_from_sh = self.wallet.ToScriptHash(address_from) except Exception: raise JsonRpcError(-32602, "Invalid params") address_to = params[2] try: address_to_sh = self.wallet.ToScriptHash(address_to) except Exception: raise JsonRpcError(-32602, "Invalid params") amount = Fixed8.TryParse(params[3], require_positive=True) if not amount or float(params[3]) == 0: raise JsonRpcError(-32602, "Invalid params") output = TransactionOutput(AssetId=asset_id, Value=amount, script_hash=address_to_sh) contract_tx = ContractTransaction(outputs=[output]) fee = Fixed8.TryParse(params[4]) if len(params) >= 5 else Fixed8.Zero() if fee < Fixed8.Zero(): raise JsonRpcError(-32602, "Invalid params") change_addr_sh = None if len(params) >= 6: change_addr = params[5] try: change_addr_sh = self.wallet.ToScriptHash(change_addr) except Exception: raise JsonRpcError(-32602, "Invalid params") return contract_tx, address_from_sh, fee, change_addr_sh
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 construct_send_basic(wallet, arguments): 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, priority_fee = get_fee(arguments) arguments, user_tx_attributes = get_tx_attr_from_args(arguments) arguments, owners = get_owners_from_params(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: logger.debug("invalid address") return False scripthash_from = None if from_address is not None: scripthash_from = lookup_addr_str(wallet, from_address) if scripthash_from is None: logger.debug("invalid address") return False # 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), tx_attributes=user_tx_attributes) f8amount = get_asset_amount(amount, assetId) if f8amount is False: logger.debug("invalid amount") return False if float(amount) == 0: print("amount cannot be 0") return False fee = Fixed8.Zero() if priority_fee is not None: fee = priority_fee if fee is False: logger.debug("invalid fee") return False output = TransactionOutput(AssetId=assetId, Value=f8amount, script_hash=scripthash_to) contract_tx = ContractTransaction(outputs=[output]) return [contract_tx, scripthash_from, fee, owners, user_tx_attributes]
def token_send(wallet, args, prompt_passwd=True): if len(args) != 4: print("please provide a token symbol, from address, to address, and amount") return False token = get_asset_id(wallet, args[0]) send_from = args[1] send_to = args[2] amount = amount_from_string(token, args[3]) return do_token_transfer(token, wallet, send_from, send_to, amount, prompt_passwd=prompt_passwd)
def Approve_Allowance(self): wallet = self.GetWallet1(recreate=True) approve_from = self.wallet_1_addr approve_to = self.watch_addr_str tokens = self.get_token(wallet) token = get_asset_id(wallet, tokens.symbol) amount = amount_from_string(token, "123") tx, fee, results = token.Approve(wallet, approve_from, approve_to, amount) return tx, fee, results
def construct_contract_withdrawal_request(wallet, arguments, fee=Fixed8.FromDecimal(.001), check_holds=False): if len(arguments) < 4: print("not enough arguments") return False # AG5xbb6QqHSUgDw8cHdyU73R1xy4qD7WEE neo AdMDZGto3xWozB1HSjjVv27RL3zUM8LzpV 20 from_address = get_arg(arguments, 0) to_send = get_arg(arguments, 1) to_address = get_arg(arguments, 2) amount = get_arg(arguments, 3) assetId = get_asset_id(wallet, to_send) f8amount = get_asset_amount(amount, assetId) scripthash_to = wallet.ToScriptHash(to_address) scripthash_from = wallet.ToScriptHash(from_address) withdraw_from_watch_only = get_withdraw_from_watch_only( wallet, scripthash_from) if f8amount is None or scripthash_to is None or withdraw_from_watch_only is None: print("Could not process to or from addr or amount") return False output = TransactionOutput(AssetId=assetId, Value=f8amount, script_hash=scripthash_to) withdraw_tx = InvocationTransaction(outputs=[output]) exclude_vin = None if check_holds: exclude_vin = lookup_contract_holds(wallet, scripthash_from) withdraw_constructed_tx = wallet.MakeTransaction( tx=withdraw_tx, change_address=scripthash_from, fee=fee, from_addr=scripthash_from, use_standard=False, watch_only_val=withdraw_from_watch_only, exclude_vin=exclude_vin) if withdraw_constructed_tx is not None: return withdraw_constructed_tx
def token_send_from(wallet, args, prompt_passwd=True): if len(args) != 4: print( "please provide a token symbol, from address, to address, and amount" ) return False token = get_asset_id(wallet, args[0]) send_from = args[1] send_to = args[2] amount = amount_from_string(token, args[3]) allowance = token_get_allowance(wallet, args[:-1], verbose=False) if allowance and allowance >= amount: tx, fee, results = token.TransferFrom(wallet, send_from, send_to, amount) if tx is not None and results is not None and len(results) > 0: if results[0].GetBigInteger() == 1: if prompt_passwd: print( "\n-----------------------------------------------------------" ) print("Transfer of %s %s from %s to %s" % (string_from_amount(token, amount), token.symbol, send_from, send_to)) print("Transfer fee: %s " % (fee.value / Fixed8.D)) print( "-------------------------------------------------------------\n" ) passwd = prompt("[Password]> ", is_password=True) if not wallet.ValidatePassword(passwd): print("incorrect password") return False return InvokeContract(wallet, tx, fee) print("Requestest transfer from is greater than allowance") return False
def get_balance(self, params): if len(params) != 1: raise JsonRpcError(-400, "Params should contain 1 id.") asset_id = get_asset_id(self.wallet, params[0]) result = {} if type(asset_id) is UInt256: total = Fixed8(0) for c in self.wallet.GetCoins(): if c.Output.AssetId == asset_id and c.State & CoinState.WatchOnly == 0: total += c.Output.Value result['Balance'] = str(total) result["Confirmed"] = str(self.wallet.GetBalance(asset_id).value / Fixed8.D) else: result["Balance"] = str(self.wallet.GetBalance(asset_id)) return result
def token_get_allowance(wallet, args, verbose=False): if len(args) != 3: print("please provide a token symbol, from address, to address") return token = get_asset_id(wallet, args[0]) allowance_from = args[1] allowance_to = args[2] tx, fee, results = token.Allowance(wallet, allowance_from, allowance_to) if tx is not None and results is not None and len(results) > 0: allowance = results[0].GetBigInteger() if verbose: print("%s allowance for %s from %s : %s " % (token.symbol, allowance_to, allowance_from, allowance)) return allowance else: if verbose: print("Could not get allowance for token %s " % token.symbol) return 0
def token_send_from(wallet, args, prompt_passwd=True): if len(args) != 4: print("please provide a token symbol, from address, to address, and amount") return False token = get_asset_id(wallet, args[0]) send_from = args[1] send_to = args[2] amount = amount_from_string(token, args[3]) allowance = token_get_allowance(wallet, args[:-1], verbose=False) if allowance and allowance >= amount: tx, fee, results = token.TransferFrom(wallet, send_from, send_to, amount) if tx is not None and results is not None and len(results) > 0: if results[0].GetBigInteger() == 1: if prompt_passwd: print("\n-----------------------------------------------------------") print("Transfer of %s %s from %s to %s" % ( string_from_amount(token, amount), token.symbol, send_from, send_to)) print("Transfer fee: %s " % (fee.value / Fixed8.D)) print("-------------------------------------------------------------\n") passwd = prompt("[Password]> ", is_password=True) if not wallet.ValidatePassword(passwd): print("incorrect password") return False return InvokeContract(wallet, tx, fee) print("Requested transfer from is greater than allowance") return False
def ShowUnspentCoins(wallet, args): addr = None asset_type = None watch_only = 0 do_count = False try: for item in args: if len(item) == 34: addr = wallet.ToScriptHash(item) elif len(item) > 1: asset_type = get_asset_id(wallet, item) if item == '--watch': watch_only = 64 elif item == '--count': do_count = True except Exception as e: print("Invalid arguments specified") if asset_type: unspents = wallet.FindUnspentCoinsByAsset(asset_type, from_addr=addr, watch_only_val=watch_only) else: unspents = wallet.FindUnspentCoins(from_addr=addr, watch_only_val=watch_only) if do_count: print('\n-----------------------------------------------') print('Total Unspent: %s' % len(unspents)) return unspents for unspent in unspents: print('\n-----------------------------------------------') print(json.dumps(unspent.ToJson(), indent=4)) return unspents
def parse_send_params(self, params): if len(params) not in [3, 4]: raise JsonRpcError(-32602, "Invalid params") asset_id = get_asset_id(self.wallet, params[0]) if not type(asset_id) is UInt256: raise JsonRpcError(-32602, "Invalid params") address_to = params[1] try: address_to_sh = self.wallet.ToScriptHash(address_to) except Exception: raise JsonRpcError(-32602, "Invalid params") amount = Fixed8.TryParse(params[2], require_positive=True) if not amount or float(params[2]) == 0: raise JsonRpcError(-32602, "Invalid params") fee = Fixed8.TryParse(params[3]) if len(params) == 4 else Fixed8.Zero() if fee < Fixed8.Zero(): raise JsonRpcError(-32602, "Invalid params") return asset_id, address_to_sh, amount, fee
def construct_withdrawal_tx(wallet, args): from_address = get_arg(args, 0) assetId = get_asset_id(wallet, get_arg(args, 1)) to_address = get_arg(args, 2) f8amount = get_asset_amount(get_arg(args, 3), assetId) scripthash_to = wallet.ToScriptHash(to_address) scripthash_from = wallet.ToScriptHash(from_address) withdraw_from_watch_only = get_withdraw_from_watch_only( wallet, scripthash_from) if f8amount is None or scripthash_to is None or withdraw_from_watch_only is None: print("Could not process to or from addr or amount") return False requested_vins = get_contract_holds_for_address(wallet, scripthash_from, scripthash_to) use_vins_for_asset = [requested_vins, assetId] output = TransactionOutput(AssetId=assetId, Value=f8amount, script_hash=scripthash_to) withdraw_tx = InvocationTransaction(outputs=[output]) withdraw_constructed_tx = wallet.MakeTransaction( tx=withdraw_tx, change_address=scripthash_from, fee=Fixed8.FromDecimal(.001), from_addr=scripthash_from, use_standard=False, watch_only_val=withdraw_from_watch_only, use_vins_for_asset=use_vins_for_asset) if withdraw_constructed_tx is not None: return withdraw_constructed_tx
def construct_send_many(wallet, arguments): if not wallet: print("please open a wallet") return False if len(arguments) is 0: print("Not enough arguments") return False outgoing = get_arg(arguments, convert_to_int=True) if outgoing is None: print("invalid outgoing number") return False if outgoing < 1: print("outgoing number must be >= 1") return False arguments, from_address = get_from_addr(arguments) arguments, change_address = get_change_addr(arguments) arguments, priority_fee = get_fee(arguments) arguments, owners = get_owners_from_params(arguments) arguments, user_tx_attributes = get_tx_attr_from_args(arguments) output = [] for i in range(outgoing): print('Outgoing Number ', i + 1) to_send = prompt("Asset to send: ") assetId = get_asset_id(wallet, to_send) if assetId is None: print("Asset id not found") return False if type(assetId) is NEP5Token: print('Sendmany does not support NEP5 tokens') return False address_to = prompt("Address to: ") scripthash_to = lookup_addr_str(wallet, address_to) if scripthash_to is None: logger.debug("invalid address") return False amount = prompt("Amount to send: ") f8amount = get_asset_amount(amount, assetId) if f8amount is False: logger.debug("invalid amount") return False if float(amount) == 0: print("amount cannot be 0") return False tx_output = TransactionOutput(AssetId=assetId, Value=f8amount, script_hash=scripthash_to) output.append(tx_output) contract_tx = ContractTransaction(outputs=output) scripthash_from = None if from_address is not None: scripthash_from = lookup_addr_str(wallet, from_address) if scripthash_from is None: logger.debug("invalid address") return False scripthash_change = None if change_address is not None: scripthash_change = lookup_addr_str(wallet, change_address) if scripthash_change is None: logger.debug("invalid address") return False fee = Fixed8.Zero() if priority_fee is not None: fee = priority_fee if fee is False: logger.debug("invalid fee") return False print("sending with fee: %s " % fee.ToString()) return [ contract_tx, scripthash_from, scripthash_change, fee, owners, user_tx_attributes ]
def RequestWithdrawFrom(wallet, asset_id, contract_hash, to_addr, amount, require_password=True): asset_type = asset_id.lower() if asset_type not in ['neo', 'gas']: raise Exception('please specify neo or gas to withdraw') readable_addr = to_addr asset_id = get_asset_id(wallet, asset_type) contract = Blockchain.Default().GetContract(contract_hash) shash = contract.Code.ScriptHash() contract_addr = Crypto.ToAddress(shash) to_addr = parse_param(to_addr, wallet) amount = get_asset_amount(amount, asset_id) if shash not in wallet._watch_only: print("Add withdrawal contract address to your watch only: import watch_addr %s " % contract_addr) return False if amount < Fixed8.Zero(): print("Cannot withdraw negative amount") return False unspents = wallet.FindUnspentCoinsByAssetAndTotal( asset_id=asset_id, amount=amount, from_addr=shash, use_standard=False, watch_only_val=64, reverse=True ) if not unspents or len(unspents) == 0: print("no eligible withdrawal vins") return False balance = GetWithdrawalBalance(wallet, shash, to_addr, asset_type) balance_fixed8 = Fixed8(balance) orig_amount = amount if amount <= balance_fixed8: sb = ScriptBuilder() for uns in unspents: if amount > Fixed8.Zero(): to_spend = amount if to_spend > uns.Output.Value: to_spend = uns.Output.Value amount_bytes = bytearray(to_spend.value.to_bytes(8, 'little')) data = to_addr + amount_bytes data = data + uns.RefToBytes() sb.EmitAppCallWithOperationAndData(shash, 'withdraw_%s' % asset_type, data) amount -= uns.Output.Value tx, fee, results, num_ops = test_invoke(sb.ToArray(), wallet, []) for item in results: if not item.GetBoolean(): print("Error performitng withdrawals") return False if require_password: print("\n---------------------------------------------------------------") print("Will make withdrawal request for %s %s from %s to %s " % (orig_amount.ToString(), asset_type, contract_addr, readable_addr)) print("FEE IS %s " % fee.ToString()) print("GAS IS %s " % tx.Gas.ToString()) print("------------------------------------------------------------------\n") print("Enter your password to complete this request") passwd = prompt("[Password]> ", is_password=True) if not wallet.ValidatePassword(passwd): print("incorrect password") return result = InvokeContract(wallet, tx, fee) return result else: print("insufficient balance") return False
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_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 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 construct_send_many(wallet, arguments): if len(arguments) is 0: print("Please specify the required parameter") return outgoing = get_arg(arguments, convert_to_int=True) if outgoing is None: print("Invalid outgoing number") return if outgoing < 1: print("Outgoing number must be >= 1") return arguments, from_address = get_from_addr(arguments) arguments, change_address = get_change_addr(arguments) arguments, priority_fee = get_fee(arguments) arguments, owners = get_owners_from_params(arguments) arguments, user_tx_attributes = get_tx_attr_from_args(arguments) output = [] for i in range(outgoing): try: print('Outgoing Number ', i + 1) to_send = prompt("Asset to send: ") assetId = get_asset_id(wallet, to_send) if assetId is None: print("Asset id not found") return if type(assetId) is NEP5Token: print('sendmany does not support NEP5 tokens') return address_to = prompt("Address to: ") scripthash_to = lookup_addr_str(wallet, address_to) if scripthash_to is None: logger.debug("invalid destination address") return amount = prompt("Amount to send: ") f8amount = get_asset_amount(amount, assetId) if f8amount is False: logger.debug("invalid amount") return if float(amount) == 0: print("Amount cannot be 0") return tx_output = TransactionOutput(AssetId=assetId, Value=f8amount, script_hash=scripthash_to) output.append(tx_output) except KeyboardInterrupt: print('Transaction cancelled') return contract_tx = ContractTransaction(outputs=output) scripthash_from = None if from_address is not None: scripthash_from = lookup_addr_str(wallet, from_address) if scripthash_from is None: logger.debug("invalid source address") return scripthash_change = None if change_address is not None: scripthash_change = lookup_addr_str(wallet, change_address) if scripthash_change is None: logger.debug("invalid change address") return fee = Fixed8.Zero() if priority_fee is not None: fee = priority_fee if fee is False: logger.debug("invalid fee") return print(f"Sending with fee: {fee.ToString()}") return [ contract_tx, scripthash_from, scripthash_change, fee, owners, user_tx_attributes ]