def construct_tx(): assetId=get_asset_id(asset_type) scripthash_to=ToScriptHash(address_to) scripthash_from=ToScriptHash(address_from) f8amount_change = Fixed8.TryParse(change, require_positive=True) f8amount = Fixed8.TryParse(amount, require_positive=True) preHash=UInt256(data=binascii.unhexlify(hex_reverse(input_txid))) input_0=TransactionInput(prevHash=preHash,prevIndex=preIndex) output_0 = TransactionOutput(AssetId=assetId, Value=f8amount_change, script_hash=scripthash_from) output_1 = TransactionOutput(AssetId=assetId, Value=f8amount, script_hash=scripthash_to) data=hex_reverse(scripthash_from.ToString()) tx = ContractTransaction(outputs=[output_0,output_1],inputs=[input_0]) tx.Attributes=[TransactionAttribute(usage=TransactionAttributeUsage.Script, data=bytearray.fromhex(data))] return tx
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_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