def do_send_created_tx(self): passwd = self._gathered_passwords[0] tx = self._wallet_send_tx self._wallet_send_tx = None self._gathered_passwords = None self._gather_password_action = None if not self.Wallet.ValidatePassword(passwd): print("incorrect password") return try: context = ContractParametersContext(tx) self.Wallet.Sign(context) if context.Completed: tx.scripts = context.GetScripts() self.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()) except Exception as e: print("could not sign %s " % e) traceback.print_stack() traceback.print_exc()
def send_to_address(self, params): asset, address, amount, fee = self.parse_send_params(params) standard_contract = self.wallet.GetStandardAddress() signer_contract = self.wallet.GetContract(standard_contract) output = TransactionOutput(AssetId=asset, Value=amount, script_hash=address) contract_tx = ContractTransaction(outputs=[output]) tx = self.wallet.MakeTransaction(tx=contract_tx, change_address=None, fee=fee) if tx is None: raise JsonRpcError(-300, "Insufficient funds") data = standard_contract.Data tx.Attributes = [ TransactionAttribute(usage=TransactionAttributeUsage.Script, data=data) ] context = ContractParametersContext( tx, isMultiSig=signer_contract.IsMultiSigContract) self.wallet.Sign(context) if context.Completed: tx.scripts = context.GetScripts() NodeLeader.Instance().Relay(tx) return tx.ToJson() else: return context.ToJson()
def InvokeContract(wallet, tx): wallet_tx = wallet.MakeTransaction(tx=tx) if wallet_tx: context = ContractParametersContext(wallet_tx) wallet.Sign(context) if context.Completed: tx.scripts = context.GetScripts() wallet.SaveTransaction(wallet_tx) relayed = NodeLeader.Instance().Relay(wallet_tx) if relayed: print("Relayed Tx: %s " % tx.Hash.ToString()) return True else: print("Could not relay tx %s " % tx.Hash.ToString()) else: print("Incomplete signature") else: print("Insufficient funds") return False
def InvokeWithTokenVerificationScript(wallet, tx, token, fee=Fixed8.Zero()): wallet_tx = wallet.MakeTransaction(tx=tx, fee=fee, use_standard=True) if wallet_tx: token_contract_state = Blockchain.Default().GetContract( token.ScriptHash.ToString()) print("token contract %s " % token_contract_state) tx.Attributes = [ TransactionAttribute(usage=TransactionAttributeUsage.Script, data=token.ScriptHash.Data) ] reedeem_script = token_contract_state.Code.Script.hex() # there has to be at least 1 param, and the first # one needs to be a signature param param_list = bytearray(b'\x00\x00') verification_contract = Contract.Create( reedeem_script, param_list, wallet.GetDefaultContract().PublicKeyHash) context = ContractParametersContext(wallet_tx) wallet.Sign(context) context.Add(verification_contract, 0, 0) if context.Completed: wallet_tx.scripts = context.GetScripts() relayed = False # print("full wallet tx: %s " % json.dumps(wallet_tx.ToJson(), indent=4)) # toarray = Helper.ToArray(wallet_tx) # print("to arary %s " % toarray) relayed = NodeLeader.Instance().Relay(wallet_tx) if relayed: print("Relayed Tx: %s " % wallet_tx.Hash.ToString()) # if it was relayed, we save tx wallet.SaveTransaction(wallet_tx) return wallet_tx else: print("Could not relay tx %s " % wallet_tx.Hash.ToString()) else: print("Incomplete signature") else: print("Insufficient funds") return False
def runRawTransaction(operation, args): invocation_tx = InvocationTransaction() smartcontract_scripthash = UInt160.ParseString(CONTRACT_HASH) sb = ScriptBuilder() sb.EmitAppCallWithOperationAndArgs( smartcontract_scripthash, operation, args) invocation_tx.Script = binascii.unhexlify(sb.ToArray()) wallet = UserWallet.Create( 'neo-privnet.wallet', to_aes_key('coz'), generate_default_key=False) private_key = KeyPair.PrivateKeyFromWIF( "KxDgvEKzgSBPPfuVfw67oPQBSjidEiqTHURKSDL1R7yGaGYAeYnr") wallet.CreateKey(private_key) context = ContractParametersContext(invocation_tx) wallet.Sign(context) invocation_tx.scripts = context.GetScripts() raw_tx = invocation_tx.ToArray() payload = {"jsonrpc": "2.0", "id": 1, "method": "sendrawtransaction", "params": [raw_tx.decode("ascii")]} res = requests.post( "http://neo-nodes:30333/testNeoConnection", json=payload) print("received POST result") print(res.status_code) result = res.text print(result) return result
def process_transaction(self, contract_tx, fee=None, address_from=None, change_addr=None): standard_contract = self.wallet.GetStandardAddress() signer_contract = self.wallet.GetContract(standard_contract) tx = self.wallet.MakeTransaction(tx=contract_tx, change_address=change_addr, fee=fee, from_addr=address_from) if tx is None: raise JsonRpcError(-300, "Insufficient funds") data = standard_contract.Data tx.Attributes = [ TransactionAttribute(usage=TransactionAttributeUsage.Script, data=data) ] context = ContractParametersContext( tx, isMultiSig=signer_contract.IsMultiSigContract) self.wallet.Sign(context) if context.Completed: tx.scripts = context.GetScripts() NodeLeader.Instance().Relay(tx) return tx.ToJson() else: return context.ToJson()
def InvokeWithdrawTx(wallet, tx, contract_hash): # print("withdraw tx 1 %s " % json.dumps(tx.ToJson(), indent=4)) requestor_contract = wallet.GetDefaultContract() tx.Attributes = [ TransactionAttribute(usage=TransactionAttributeUsage.Script, data=Crypto.ToScriptHash( requestor_contract.Script).Data) ] withdraw_contract_state = Blockchain.Default().GetContract( contract_hash.encode('utf-8')) withdraw_verification = None if withdraw_contract_state is not None: reedeem_script = withdraw_contract_state.Code.Script.hex() # there has to be at least 1 param, and the first # one needs to be a signature param param_list = bytearray(b'\x00') # if there's more than one param # we set the first parameter to be the signature param if len(withdraw_contract_state.Code.ParameterList) > 1: param_list = bytearray(withdraw_contract_state.Code.ParameterList) param_list[0] = 0 verification_contract = Contract.Create( reedeem_script, param_list, requestor_contract.PublicKeyHash) address = verification_contract.Address withdraw_verification = verification_contract context = ContractParametersContext(tx) wallet.Sign(context) context.Add(withdraw_verification, 0, 0) if context.Completed: tx.scripts = context.GetScripts() print("withdraw tx %s " % json.dumps(tx.ToJson(), indent=4)) wallet.SaveTransaction(tx) relayed = NodeLeader.Instance().Relay(tx) if relayed: print("Relayed Withdrawal Tx: %s " % tx.Hash.ToString()) return True else: print("Could not relay witdrawal tx %s " % tx.Hash.ToString()) else: print("Incomplete signature")
def create_raw_sc_method_call_tx( source_address, source_address_wif, smartcontract_scripthash, smartcontract_method, smartcontract_method_args, ): source_script_hash = address_to_scripthash(source_address) # start by creating a base InvocationTransaction # the inputs, outputs and Type do not have to be set anymore. invocation_tx = InvocationTransaction() # often times smart contract developers use the function ``CheckWitness`` to determine if the transaction is signed by somebody eligible of calling a certain method # in order to pass that check you want to add the corresponding script_hash as a transaction attribute (this is generally the script_hash of the public key you use for signing) # Note that for public functions like the NEP-5 'getBalance' and alike this would not be needed, but it doesn't hurt either invocation_tx.Attributes.append( TransactionAttribute(usage=TransactionAttributeUsage.Script, data=source_script_hash)) smartcontract_scripthash = UInt160.ParseString(smartcontract_scripthash) # next we need to build a 'script' that gets executed against the smart contract. # this is basically the script that calls the entry point of the contract with the necessary parameters sb = ScriptBuilder() # call the method on the contract (assumes contract address is a NEP-5 token) sb.EmitAppCallWithOperationAndArgs( smartcontract_scripthash, smartcontract_method, smartcontract_method_args, ) invocation_tx.Script = binascii.unhexlify(sb.ToArray()) # 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(source_address_wif) # 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(invocation_tx) wallet.Sign(context) invocation_tx.scripts = context.GetScripts() raw_tx = invocation_tx.ToArray() print(raw_tx) return raw_tx.decode()
def InvokeWithTokenVerificationScript(wallet, tx, token, fee=Fixed8.Zero(), invoke_attrs=None): try: wallet_tx = wallet.MakeTransaction(tx=tx, fee=fee, use_standard=True) except ValueError: print("Insufficient funds") return False if wallet_tx: token_contract_state = Blockchain.Default().GetContract(token.ScriptHash.ToString()) print("token contract %s " % token_contract_state) tx.Attributes = [ TransactionAttribute(usage=TransactionAttributeUsage.Script, data=token.ScriptHash.Data) ] if invoke_attrs: tx.Attributes += invoke_attrs reedeem_script = token_contract_state.Code.Script.hex() # there has to be at least 1 param, and the first # one needs to be a signature param param_list = bytearray(b'\x00\x00') verification_contract = Contract.Create(reedeem_script, param_list, wallet.GetDefaultContract().PublicKeyHash) context = ContractParametersContext(wallet_tx) wallet.Sign(context) context.Add(verification_contract, 0, 0) if context.Completed: wallet_tx.scripts = context.GetScripts() nodemgr = NodeManager() relayed = nodemgr.relay(wallet_tx) if relayed: print("Relayed Tx: %s " % wallet_tx.Hash.ToString()) # if it was relayed, we save tx wallet.SaveTransaction(wallet_tx) return wallet_tx else: print("Could not relay tx %s " % wallet_tx.Hash.ToString()) else: print("Incomplete signature") else: print("Insufficient funds") return False
def InvokeContract(wallet, tx, fee=Fixed8.Zero(), from_addr=None, owners=None): if from_addr is not None: from_addr = PromptUtils.lookup_addr_str(wallet, from_addr) try: wallet_tx = wallet.MakeTransaction(tx=tx, fee=fee, use_standard=True, from_addr=from_addr) except ValueError: print("Insufficient funds") return False except TXFeeError as e: print(e) return False if wallet_tx: if owners: for owner in list(owners): wallet_tx.Attributes.append( TransactionAttribute( usage=TransactionAttributeUsage.Script, data=owner)) wallet_tx.Attributes = make_unique_script_attr(tx.Attributes) context = ContractParametersContext(wallet_tx) wallet.Sign(context) if owners: gather_signatures(context, wallet_tx, list(owners)) if context.Completed: wallet_tx.scripts = context.GetScripts() relayed = False # print("SENDING TX: %s " % json.dumps(wallet_tx.ToJson(), indent=4)) relayed = NodeLeader.Instance().Relay(wallet_tx) if relayed: print("Relayed Tx: %s " % wallet_tx.Hash.ToString()) wallet.SaveTransaction(wallet_tx) return wallet_tx else: print("Could not relay tx %s " % wallet_tx.Hash.ToString()) else: print("Incomplete signature") else: print("Insufficient funds") return False
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 example2(): source_address = "AJQ6FoaSXDFzA6wLnyZ1nFN7SGSN2oNTc3" source_script_hash = address_to_scripthash(source_address) # start by creating a base InvocationTransaction # the inputs, outputs and Type do not have to be set anymore. invocation_tx = InvocationTransaction() # Since we are building a raw transaction, we will add the raw_tx flag invocation_tx.raw_tx = True # often times smart contract developers use the function ``CheckWitness`` to determine if the transaction is signed by somebody eligible of calling a certain method # in order to pass that check you want to add the corresponding script_hash as a transaction attribute (this is generally the script_hash of the public key you use for signing) # Note that for public functions like the NEP-5 'getBalance' and alike this would not be needed, but it doesn't hurt either invocation_tx.Attributes.append( TransactionAttribute(usage=TransactionAttributeUsage.Script, data=source_script_hash)) # next we need to build a 'script' that gets executed against the smart contract. # this is basically the script that calls the entry point of the contract with the necessary parameters smartcontract_scripthash = UInt160.ParseString( "31730cc9a1844891a3bafd1aa929a4142860d8d3") sb = ScriptBuilder() # call the NEP-5 `name` method on the contract (assumes contract address is a NEP-5 token) sb.EmitAppCallWithOperation(smartcontract_scripthash, 'name') invocation_tx.Script = binascii.unhexlify(sb.ToArray()) # 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(invocation_tx) wallet.Sign(context) invocation_tx.scripts = context.GetScripts() raw_tx = invocation_tx.ToArray() return raw_tx
def create_tx(contract_hash, address_from, address_to, tnc_amount, gas_change, input_txid, preIndex): nep5TokenId = get_nep5token_id(contract_hash) scripthash_from = ToScriptHash(address_from) scripthash_to = ToScriptHash(address_to) f8amount = amount_from_string(nep5TokenId, tnc_amount) f8amount_change = Fixed8.TryParse(gas_change, require_positive=True) assetId = get_asset_id("gas") preHash = UInt256(data=binascii.unhexlify(hex_reverse(input_txid))) input = TransactionInput(prevHash=preHash, prevIndex=preIndex) output = TransactionOutput(AssetId=assetId, Value=f8amount_change, script_hash=scripthash_from) tx = InvocationTransaction(outputs=[output], inputs=[input]) tx.Version = 1 context = ContractParametersContext(tx) tx.scripts = context.GetScripts() invoke_args = [ nep5TokenId.ScriptHash, 'transfer', [ bytearray.fromhex(hex_reverse(scripthash_from.ToString())), bytearray.fromhex(hex_reverse(scripthash_to.ToString())), BigInteger(f8amount) ] ] sb = ScriptBuilder() invoke_args.reverse() for item in invoke_args[:2]: if type(item) is list: item.reverse() listlength = len(item) for listitem in item: sb.push(listitem) sb.push(listlength) sb.Emit(PACK) else: sb.push(binascii.hexlify(item.encode())) sb.EmitAppCall(nep5TokenId.ScriptHash.ToArray()) op_data = sb.ToArray().decode() tx.Script = binascii.unhexlify(op_data) tx_data = get_tx_data(tx)[:-2] print("tx_data:", tx_data) signstr = binascii.hexlify( Crypto.Sign(message=tx_data, private_key=private_key)).decode() rawtx_data = tx_data + "014140" + signstr + "2321" + public_key + "ac" return rawtx_data
def sign_context(binary_tx, private): wallet = Wallet(b'', b'0' * 32, True) wallet.CreateKey(binascii.unhexlify(private)) script_hash = WalletContract.CreateSignatureContract( list(wallet._keys.values())[0].PublicKey) wallet._contracts[script_hash.ScriptHash.ToBytes()] = script_hash tx = ContractTransaction.DeserializeFromBufer( binascii.unhexlify(binary_tx)) context = ContractParametersContext(tx, isMultiSig=False) context.ScriptHashes = [script_hash.ScriptHash] wallet.Sign(context) return [x.ToJson() for x in context.GetScripts()]
def InvokeContract(wallet, tx, fee=Fixed8.Zero(), from_addr=None, owners=None): if from_addr is not None: from_addr = PromptUtils.lookup_addr_str(wallet, from_addr) try: wallet_tx = wallet.MakeTransaction(tx=tx, fee=fee, use_standard=True, from_addr=from_addr) except ValueError: print("Insufficient funds") return False if wallet_tx: if owners: for owner in list(owners): wallet_tx.Attributes.append(TransactionAttribute(usage=TransactionAttributeUsage.Script, data=owner)) wallet_tx.Attributes = make_unique_script_attr(tx.Attributes) context = ContractParametersContext(wallet_tx) wallet.Sign(context) if owners: gather_signatures(context, wallet_tx, list(owners)) if context.Completed: wallet_tx.scripts = context.GetScripts() passed, reason = validate_simple_policy(wallet_tx) if not passed: print(reason) return False nodemgr = NodeManager() relayed = nodemgr.relay(wallet_tx) if relayed: print("Relayed Tx: %s " % wallet_tx.Hash.ToString()) wallet.SaveTransaction(wallet_tx) return wallet_tx else: print("Could not relay tx %s " % wallet_tx.Hash.ToString()) else: print("Incomplete signature") else: print("Insufficient funds") return False
def Sign(self, NEP2orPrivateKey, NEP2password=None, multisig_args=[]): """ Sign the raw transaction Args: NEP2orPrivateKey: (str) the NEP2 or PrivateKey string from the address you are sending from. NOTE: Assumes WIF if NEP2password is None. NEP2password: (str, optional) the NEP2 password associated with the NEP2 key string. Defaults to None. multisig_args: (list, optional) the arguments for importing a multsig address (e.g. [<owner pubkey>, <num required sigs>, [<signing pubkey>, ...]]) """ temp_path = "temp_wallet.wallet" temp_password = "******" wallet = UserWallet.Create(temp_path, to_aes_key(temp_password), generate_default_key=False) if NEP2password: private_key = KeyPair.PrivateKeyFromNEP2(NEP2orWIF, NEP2password) else: private_key = binascii.unhexlify(NEP2orPrivateKey) wallet.CreateKey(private_key) if multisig_args: # import a multisig address verification_contract = Contract.CreateMultiSigContract( Crypto.ToScriptHash(multisig_args[0], unhex=True), multisig_args[1], multisig_args[2]) wallet.AddContract(verification_contract) if self.Type == b'\xd1' and not self.SOURCE_SCRIPTHASH: # in case of an invocation with no funds transfer context = ContractParametersContext(self) elif not self._context: # used during transactions involving a funds transfer signer_contract = wallet.GetContract(self.SOURCE_SCRIPTHASH) context = ContractParametersContext( self, isMultiSig=signer_contract.IsMultiSigContract) else: context = self._context # used for a follow-on signature for a multi-sig transaction wallet.Sign(context) if context.Completed: self.scripts = context.GetScripts() self.Validate() # ensure the tx is ready to be relayed elif context.ContextItems: self._context = context print( "Transaction initiated, but the signature is incomplete. Sign again with another valid multi-sig keypair." ) else: raise SignatureError("Unable to sign transaction.") wallet.Close() wallet = None os.remove(temp_path)
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 InvokeContract(wallet, tx, fee=Fixed8.Zero(), from_addr=None): if from_addr is not None: from_addr = lookup_addr_str(wallet, from_addr) wallet_tx = wallet.MakeTransaction(tx=tx, fee=fee, use_standard=True, from_addr=from_addr) # pdb.set_trace() if wallet_tx: context = ContractParametersContext(wallet_tx) wallet.Sign(context) if context.Completed: wallet_tx.scripts = context.GetScripts() relayed = False # print("SENDING TX: %s " % json.dumps(wallet_tx.ToJson(), indent=4)) relayed = NodeLeader.Instance().Relay(wallet_tx) if relayed: print("Relayed Tx: %s " % wallet_tx.Hash.ToString()) wallet.SaveTransaction(wallet_tx) return wallet_tx else: print("Could not relay tx %s " % wallet_tx.Hash.ToString()) else: print("Incomplete signature") else: print("Insufficient funds") return False
def PerformWithdrawTx(wallet, tx, contract_hash): requestor_contract = wallet.GetDefaultContract() withdraw_contract_state = Blockchain.Default().GetContract( contract_hash.encode('utf-8')) reedeem_script = withdraw_contract_state.Code.Script.hex() # there has to be at least 1 param, and the first # one needs to be a signature param param_list = bytearray(b'\x00') # if there's more than one param # we set the first parameter to be the signature param if len(withdraw_contract_state.Code.ParameterList) > 1: param_list = bytearray(withdraw_contract_state.Code.ParameterList) param_list[0] = 0 verification_contract = Contract.Create(reedeem_script, param_list, requestor_contract.PublicKeyHash) context = ContractParametersContext(tx) context.Add(verification_contract, 0, bytearray(0)) if context.Completed: tx.scripts = context.GetScripts() print("withdraw tx %s " % json.dumps(tx.ToJson(), indent=4)) relayed = NodeLeader.Instance().Relay(tx) if relayed: # wallet.SaveTransaction(tx) # dont save this tx print("Relayed Withdrawal Tx: %s " % tx.Hash.ToString()) return tx else: print("Could not relay witdrawal tx %s " % tx.Hash.ToString()) else: print("Incomplete signature") return False
def SendBlog(wallet, tx, fee=Fixed8.Zero(), from_addr=None, privatekey=None): wallet_tx = wallet.MakeTransaction(tx=tx, fee=fee, use_standard=False, from_addr=from_addr) # wallet_tx = tx if wallet_tx: context = ContractParametersContext(wallet_tx) if privatekey != None: prikey = KeyPair.PrivateKeyFromWIF(privatekey) kp = KeyPair(prikey) wallet.Sign(context, kp) else: wallet.Sign(context) if context.Completed: wallet_tx.scripts = context.GetScripts() relayed = False # print("SENDING TX: %s " % json.dumps(wallet_tx.ToJson(), indent=4)) relayed = NodeLeader.Instance().Relay(wallet_tx) print("Tx: %s " % wallet_tx.ToJson()) if relayed: print("Relayed Tx: %s " % wallet_tx.Hash.ToString()) wallet.SaveTransaction(wallet_tx) return wallet_tx else: print("Could not relay tx %s " % wallet_tx.Hash.ToString()) else: print("Incomplete signature") else: print("Insufficient funds") return False
def InvokeContract(wallet, tx, fee=Fixed8.Zero()): wallet_tx = wallet.MakeTransaction(tx=tx, fee=fee, use_standard=True) # pdb.set_trace() if wallet_tx: context = ContractParametersContext(wallet_tx) wallet.Sign(context) if context.Completed: wallet_tx.scripts = context.GetScripts() relayed = False # print("SENDING TX: %s " % json.dumps(wallet_tx.ToJson(), indent=4)) # check if we can save the tx first save_tx = wallet.SaveTransaction(wallet_tx) if save_tx: relayed = NodeLeader.Instance().Relay(wallet_tx) else: print("Could not save tx to wallet, will not send tx") if relayed: print("Relayed Tx: %s " % wallet_tx.Hash.ToString()) return wallet_tx else: print("Could not relay tx %s " % wallet_tx.Hash.ToString()) else: print("Incomplete signature") else: print("Insufficient funds") 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 InvokeContract(wallet, tx, fee=Fixed8.Zero()): wallet_tx = wallet.MakeTransaction(tx=tx, fee=fee, use_standard=True) # pdb.set_trace() if wallet_tx: context = ContractParametersContext(wallet_tx) wallet.Sign(context) if context.Completed: wallet_tx.scripts = context.GetScripts() relayed = False # print("SENDING TX: %s " % json.dumps(wallet_tx.ToJson(), indent=4)) relayed = NodeLeader.Instance().Relay(wallet_tx) if relayed: logger.info("Relayed Tx: %s " % wallet_tx.Hash.ToString()) wallet.SaveTransaction(wallet_tx) return wallet_tx else: logger.error("Could not relay tx %s " % wallet_tx.Hash.ToString()) raise RuntimeError("Could not relay tx %s " % wallet_tx.Hash.ToString()) else: logger.error("Incomplete signature") raise RuntimeError('Incomplete signature') else: logger.error("Insufficient funds") raise RuntimeError('Insufficient funds') return False
def process_transaction(self, contract_tx, fee=None, address_from=None, change_addr=None): standard_contract = self.wallet.GetStandardAddress() signer_contract = self.wallet.GetContract(standard_contract) try: tx = self.wallet.MakeTransaction(tx=contract_tx, change_address=change_addr, fee=fee, from_addr=address_from) except ValueError: # if not enough unspents while fully synced raise JsonRpcError(-300, "Insufficient funds") if tx is None: # if not enough unspents while not being fully synced raise JsonRpcError(-300, "Insufficient funds") data = standard_contract.Data tx.Attributes = [ TransactionAttribute(usage=TransactionAttributeUsage.Script, data=data) ] context = ContractParametersContext( tx, isMultiSig=signer_contract.IsMultiSigContract ) self.wallet.Sign(context) if context.Completed: tx.scripts = context.GetScripts() passed, reason = validate_simple_policy(tx) if not passed: raise JsonRpcError(-32602, reason) relayed = self.nodemgr.relay(tx) if relayed: self.wallet.SaveTransaction(tx) return tx.ToJson() else: raise JsonRpcError(-32602, "Invalid params") else: return context.ToJson()
def process_transaction(wallet, contract_tx, scripthash_from=None, scripthash_change=None, fee=None, owners=None, user_tx_attributes=None): try: tx = wallet.MakeTransaction(tx=contract_tx, change_address=scripthash_change, fee=fee, from_addr=scripthash_from) if tx is None: logger.debug("insufficient funds") return False # password prompt 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) print(context.ScriptHashes) for s in context.GetScripts(): print(s.ToJson()) print(tx.ToJson()) 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 test_deploy_and_invoke(deploy_script, invoke_args, wallet, from_addr=None, min_fee=DEFAULT_MIN_FEE, invocation_test_mode=True, debug_map=None, invoke_attrs=None, owners=None): bc = GetBlockchain() accounts = DBCollection(bc._db, DBPrefix.ST_Account, AccountState) assets = DBCollection(bc._db, DBPrefix.ST_Asset, AssetState) validators = DBCollection(bc._db, DBPrefix.ST_Validator, ValidatorState) contracts = DBCollection(bc._db, DBPrefix.ST_Contract, ContractState) storages = DBCollection(bc._db, DBPrefix.ST_Storage, StorageItem) if settings.USE_DEBUG_STORAGE: debug_storage = DebugStorage.instance() storages = DBCollection(debug_storage.db, DBPrefix.ST_Storage, StorageItem) storages.DebugStorage = True dtx = InvocationTransaction() dtx.Version = 1 dtx.outputs = [] dtx.inputs = [] dtx.scripts = [] dtx.Script = binascii.unhexlify(deploy_script) if from_addr is not None: from_addr = PromptUtils.lookup_addr_str(wallet, from_addr) try: dtx = wallet.MakeTransaction(tx=dtx, from_addr=from_addr) except (ValueError, TXFeeError): pass context = ContractParametersContext(dtx) wallet.Sign(context) dtx.scripts = context.GetScripts() script_table = CachedScriptTable(contracts) service = StateMachine(accounts, validators, assets, contracts, storages, None) contract = wallet.GetDefaultContract() dtx.Attributes = [ TransactionAttribute(usage=TransactionAttributeUsage.Script, data=Crypto.ToScriptHash(contract.Script, unhex=False)) ] dtx.Attributes = make_unique_script_attr(dtx.Attributes) to_dispatch = [] engine = ApplicationEngine(trigger_type=TriggerType.Application, container=dtx, table=script_table, service=service, gas=dtx.Gas, testMode=True) engine.LoadScript(dtx.Script) # first we will execute the test deploy # then right after, we execute the test invoke d_success = engine.Execute() if d_success: items = engine.ResultStack.Items contract_state = None for i in items: if type(i) is ContractState: contract_state = i break elif type(i) is InteropInterface: item = i.GetInterface() if type(item) is ContractState: contract_state = item break shash = contract_state.Code.ScriptHash() invoke_args, neo_to_attach, gas_to_attach = PromptUtils.get_asset_attachments( invoke_args) invoke_args, no_parse_addresses = PromptUtils.get_parse_addresses( invoke_args) invoke_args.reverse() if '--i' in invoke_args: invoke_args = [] for index, iarg in enumerate(contract_state.Code.ParameterList): param, abort = PromptUtils.gather_param(index, iarg) if abort: return None, [], 0, None else: invoke_args.append(param) invoke_args.reverse() sb = ScriptBuilder() for p in invoke_args: item = PromptUtils.parse_param(p, wallet, parse_addr=no_parse_addresses) if type(item) is list: item.reverse() listlength = len(item) for listitem in item: subitem = PromptUtils.parse_param( listitem, wallet, parse_addr=no_parse_addresses) if type(subitem) is list: subitem.reverse() for listitem2 in subitem: subsub = PromptUtils.parse_param( listitem2, wallet, parse_addr=no_parse_addresses) sb.push(subsub) sb.push(len(subitem)) sb.Emit(PACK) else: sb.push(subitem) sb.push(listlength) sb.Emit(PACK) else: sb.push(item) sb.EmitAppCall(shash.Data) out = sb.ToArray() outputs = [] if neo_to_attach: output = TransactionOutput( AssetId=Blockchain.SystemShare().Hash, Value=neo_to_attach, script_hash=contract_state.Code.ScriptHash(), ) outputs.append(output) if gas_to_attach: output = TransactionOutput( AssetId=Blockchain.SystemCoin().Hash, Value=gas_to_attach, script_hash=contract_state.Code.ScriptHash()) outputs.append(output) itx = InvocationTransaction() itx.Version = 1 itx.outputs = outputs itx.inputs = [] itx.scripts = [] itx.Attributes = deepcopy(invoke_attrs) if invoke_attrs else [] itx.Script = binascii.unhexlify(out) if len(outputs) < 1 and not owners: contract = wallet.GetDefaultContract() itx.Attributes.append( TransactionAttribute(usage=TransactionAttributeUsage.Script, data=contract.ScriptHash)) itx.Attributes = make_unique_script_attr(itx.Attributes) try: itx = wallet.MakeTransaction(tx=itx, from_addr=from_addr) except (ValueError, TXFeeError): pass context = ContractParametersContext(itx) wallet.Sign(context) if owners: owners = list(owners) for owner in owners: itx.Attributes.append( TransactionAttribute( usage=TransactionAttributeUsage.Script, data=owner)) itx.Attributes = make_unique_script_attr(itx.Attributes) context = ContractParametersContext(itx, isMultiSig=True) if context.Completed: itx.scripts = context.GetScripts() else: logger.warn( "Not gathering signatures for test build. For a non-test invoke that would occur here." ) # if not gather_signatures(context, itx, owners): # return None, [], 0, None # print("gathered signatures %s " % itx.scripts) engine = ApplicationEngine(trigger_type=TriggerType.Application, container=itx, table=script_table, service=service, gas=itx.Gas, testMode=invocation_test_mode) engine.invocation_args = invoke_args engine.LoadScript(itx.Script) engine.LoadDebugInfoForScriptHash(debug_map, shash.Data) i_success = engine.Execute() service.ExecutionCompleted(engine, i_success) to_dispatch = to_dispatch + service.events_to_dispatch for event in to_dispatch: events.emit(event.event_type, event) if i_success: service.TestCommit() if len(service.notifications) > 0: for n in service.notifications: Blockchain.Default().OnNotify(n) logger.info("Used %s Gas " % engine.GasConsumed().ToString()) consumed = engine.GasConsumed() - Fixed8.FromDecimal(10) consumed = consumed.Ceil() if consumed <= Fixed8.Zero(): consumed = min_fee total_ops = engine.ops_processed # set the amount of gas the tx will need itx.Gas = consumed itx.Attributes = [] result = engine.ResultStack.Items return itx, result, total_ops, engine else: print("error executing invoke contract...") else: print("error executing deploy contract.....") service.ExecutionCompleted(engine, False, 'error') return None, [], 0, None