def FromJson(jsn, isMultiSig=True):
        try:
            parsed = json.loads(jsn)
            if parsed['type'] == 'Neo.Core.ContractTransaction':
                verifiable = ContractTransaction()
                ms = MemoryStream(binascii.unhexlify(parsed['hex']))
                r = BinaryReader(ms)
                verifiable.DeserializeUnsigned(r)
                context = ContractParametersContext(verifiable,
                                                    isMultiSig=isMultiSig)
                for key, value in parsed['items'].items():
                    if "0x" in key:
                        key = key[2:]
                    key = key.encode()
                    parameterbytes = []
                    for pt in value['parameters']:
                        if pt['type'] == 'Signature':
                            parameterbytes.append(0)
                    contract = Contract.Create(value['script'], parameterbytes,
                                               key)
                    context.ContextItems[key] = ContextItem(contract)
                    if 'signatures' in value:
                        context.ContextItems[key].Signatures = value[
                            'signatures']

                return context
            else:
                raise ("Unsupported transaction type in JSON")

        except Exception as e:
            logger.error(
                "Failed to import ContractParametersContext from JSON: {}".
                format(e))
Beispiel #2
0
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
Beispiel #3
0
    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
Beispiel #4
0
    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
Beispiel #5
0
    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)
Beispiel #6
0
    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)
Beispiel #7
0
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 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 _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
Beispiel #10
0
    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 send_neo(wallet, address_from, address_to, amount):
        assetId = None

        assetId = Blockchain.Default().SystemShare().Hash

        scripthash_to = wallet.ToScriptHash(address_to)
        scripthash_from = wallet.ToScriptHash(address_from)

        f8amount = Fixed8.TryParse(amount)

        if 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, change_address=None, fee=fee, from_addr=scripthash_from)

        if ttx is None:
            raise Exception("insufficient funds, were funds already moved from multi-sig contract?")

        context = ContractParametersContext(tx, isMultiSig=True)
        wallet.Sign(context)

        if context.Completed:
            raise Exception("Something went wrong, multi-sig transaction failed")

        else:
            print("Transaction initiated")
            return json.dumps(context.ToJson(), separators=(',', ':'))
 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
Beispiel #13
0
    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
Beispiel #14
0
    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
Beispiel #15
0
def deploy(from_addr, bytecode, contract_params, return_type, details):
    response = requests.post('http://127.0.0.1:20332',
                             json={
                                 'jsonrpc':
                                 '2.0',
                                 'id':
                                 1,
                                 'method':
                                 'mw_construct_deploy_tx',
                                 'params': [{
                                     'from_addr': from_addr,
                                     'bin': bytecode,
                                     'contract_params': contract_params,
                                     'return_type': return_type,
                                     'details': details,
                                 }]
                             }).json()
    if 'error' in response:
        print(response['error']['message'])
        return
    context = response['result']['context']
    binary_tx = response['result']['tx']
    contract_hash = response['result']['hash']

    tx = ContractTransaction.DeserializeFromBufer(
        binascii.unhexlify(binary_tx))

    scripts = requests.post('http://127.0.0.1:5000/neo_sign/',
                            json={
                                'binary_tx': binary_tx
                            }).json()
    tx.scripts = [
        Witness(
            x['invocation'].encode(),
            x['verification'].encode(),
        ) for x in scripts
    ]

    ms = StreamManager.GetStream()
    writer = BinaryWriter(ms)
    tx.Serialize(writer)
    ms.flush()
    signed_tx = ms.ToArray()

    response = requests.post('http://127.0.0.1:20332',
                             json={
                                 'jsonrpc': '2.0',
                                 'id': 1,
                                 'method': 'sendrawtransaction',
                                 'params': [
                                     signed_tx.decode(),
                                 ]
                             }).json()

    print('contract hash:', contract_hash)
    print(response)
Beispiel #16
0
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]
Beispiel #17
0
def send(addr_from, addr_to, asset, amount):
    response = requests.post('http://127.0.0.1:20332',
                             json={
                                 'jsonrpc': '2.0',
                                 'id': 1,
                                 'method': 'mw_construct_send_tx',
                                 'params': {
                                     'from': addr_from,
                                     'to': addr_to,
                                     'asset': asset,
                                     'amount': amount,
                                 }
                             }).json()
    print(response)
    context = response['result']['context']
    binary_tx = response['result']['tx']

    tx = ContractTransaction.DeserializeFromBufer(
        binascii.unhexlify(binary_tx))
    scripts = requests.post('http://127.0.0.1:5000/neo_sign/',
                            json={
                                'binary_tx': binary_tx,
                                'address': addr_from
                            }).json()
    print('scripts', scripts)
    tx.scripts = [
        Witness(
            x['invocation'].encode(),
            x['verification'].encode(),
        ) for x in scripts
    ]

    print(scripts)
    ms = StreamManager.GetStream()
    writer = BinaryWriter(ms)
    tx.Serialize(writer)
    ms.flush()
    signed_tx = ms.ToArray()

    print(tx.ToJson())

    #    print('does not send: return') ; return

    response = requests.post('http://127.0.0.1:20332',
                             json={
                                 'jsonrpc': '2.0',
                                 'id': 1,
                                 'method': 'sendrawtransaction',
                                 'params': [
                                     signed_tx.decode(),
                                 ]
                             }).json()
    print(response)
def create_withdraw_tx(wallet, hold):

    f8amount = Fixed8(hold.Amount)

    coinRef = CoinReference(prev_hash=hold.TXHash, prev_index=hold.Index)

    requested_vins = [coinRef]

    use_vins_for_asset = [requested_vins, hold.AssetId]

    output = TransactionOutput(AssetId=hold.AssetId, Value=f8amount, script_hash=hold.OutputHash)
    withdraw_tx = ContractTransaction(outputs=[output])
    withdraw_tx.withdraw_hold = hold

    return wallet.MakeTransaction(tx=withdraw_tx,
                                  change_address=hold.InputHash,
                                  fee=Fixed8.Zero(),
                                  from_addr=hold.InputHash,
                                  use_standard=False,
                                  watch_only_val=64,
                                  use_vins_for_asset=use_vins_for_asset)
Beispiel #19
0
    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)
Beispiel #20
0
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()]
Beispiel #21
0
    def deploy(self, contract_params='0710', return_type='05'):
        self.compile()
        from_addr = NETWORKS[self.contract.network.name]['address']
        bytecode = self.neo_contract_crowdsale.bytecode
        neo_int = NeoInt(self.contract.network.name)
        print('from address', from_addr)
        details = {
            'name': 'WISH',
            'description': 'NEO smart contract',
            'email': '*****@*****.**',
            'version': '1',
            'author': 'MyWish'
        }
        param_list = {
            'from_addr': from_addr,
            'bin': bytecode,
            'needs_storage': True,
            'needs_dynamic_invoke': False,
            'contract_params': contract_params,
            'return_type': return_type,
            'details': details,
        }
        response = neo_int.mw_construct_deploy_tx(param_list)
        print('construct response', response, flush=True)
        binary_tx = response['tx']
        contract_hash = response['hash']

        tx = ContractTransaction.DeserializeFromBufer(
            binascii.unhexlify(binary_tx))
        tx = sign_neo_transaction(tx, binary_tx, from_addr)
        print('after sign', tx.ToJson()['txid'], flush=True)
        ms = StreamManager.GetStream()
        writer = BinaryWriter(ms)
        tx.Serialize(writer)
        ms.flush()
        signed_tx = ms.ToArray()
        print('full tx:', flush=True)
        print(signed_tx, flush=True)

        result = neo_int.sendrawtransaction(signed_tx.decode())
        print(result, flush=True)
        if not result:
            raise TxFail()
        print('contract hash:', contract_hash)
        print('result of send raw transaction: ', result)
        self.neo_contract_crowdsale.address = contract_hash
        self.neo_contract_crowdsale.tx_hash = tx.ToJson()['txid']
        self.neo_contract_crowdsale.save()
Beispiel #22
0
    def msg_deployed(self, message):
        neo_int = NeoInt(self.contract.network.name)
        from_addr = NETWORKS[self.contract.network.name]['address']
        param_list = {
            'from_addr':
            from_addr,
            'contract_params': [{
                'type': str(ContractParameterType.String),
                'value': 'init'
            }, {
                'type': str(ContractParameterType.Array),
                'value': []
            }],
            'addr':
            self.neo_contract_crowdsale.address,
        }

        response = neo_int.mw_construct_invoke_tx(param_list)

        binary_tx = response['tx']

        tx = ContractTransaction.DeserializeFromBufer(
            binascii.unhexlify(binary_tx))
        tx = sign_neo_transaction(tx, binary_tx, from_addr)
        print('after sign', tx.ToJson()['txid'])
        ms = StreamManager.GetStream()
        writer = BinaryWriter(ms)
        tx.Serialize(writer)
        ms.flush()
        signed_tx = ms.ToArray()
        print('signed_tx', signed_tx)
        result = neo_int.sendrawtransaction(signed_tx.decode())
        print(result, flush=True)
        if not result:
            raise TxFail()
        print('result of send raw transaction: ', result)
        self.contract.save()
        self.neo_contract_crowdsale.tx_hash = tx.ToJson()['txid']
        self.neo_contract_crowdsale.save()
        return
Beispiel #23
0
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
    ]
Beispiel #24
0
    def DeserializeFrom(reader):
        """
        Deserialize full object.

        Args:
            reader (neo.IO.BinaryReader):

        Returns:
            Transaction:
        """
        ttype = ord(reader.ReadByte())
        tx = None

        from neo.Core.TX.RegisterTransaction import RegisterTransaction
        from neo.Core.TX.IssueTransaction import IssueTransaction
        from neo.Core.TX.ClaimTransaction import ClaimTransaction
        from neo.Core.TX.MinerTransaction import MinerTransaction
        from neo.Core.TX.PublishTransaction import PublishTransaction
        from neo.Core.TX.InvocationTransaction import InvocationTransaction
        from neo.Core.TX.EnrollmentTransaction import EnrollmentTransaction
        from neo.Core.TX.StateTransaction import StateTransaction
        from neo.Core.TX.Transaction import ContractTransaction

        if ttype == int.from_bytes(TransactionType.RegisterTransaction,
                                   'little'):
            tx = RegisterTransaction()
        elif ttype == int.from_bytes(TransactionType.MinerTransaction,
                                     'little'):
            tx = MinerTransaction()
        elif ttype == int.from_bytes(TransactionType.IssueTransaction,
                                     'little'):
            tx = IssueTransaction()
        elif ttype == int.from_bytes(TransactionType.ClaimTransaction,
                                     'little'):
            tx = ClaimTransaction()
        elif ttype == int.from_bytes(TransactionType.PublishTransaction,
                                     'little'):
            tx = PublishTransaction()
        elif ttype == int.from_bytes(TransactionType.InvocationTransaction,
                                     'little'):
            tx = InvocationTransaction()
        elif ttype == int.from_bytes(TransactionType.EnrollmentTransaction,
                                     'little'):
            tx = EnrollmentTransaction()
        elif ttype == int.from_bytes(TransactionType.StateTransaction,
                                     'little'):
            tx = StateTransaction()
        elif ttype == int.from_bytes(TransactionType.ContractTransaction,
                                     'little'):
            tx = ContractTransaction()
        else:
            tx = Transaction()
            tx.Type = ttype

        tx.DeserializeUnsignedWithoutType(reader)

        tx.scripts = []
        byt = reader.ReadVarInt()

        if byt > 0:
            for i in range(0, byt):
                witness = Witness()
                witness.Deserialize(reader)

                tx.scripts.append(witness)

        tx.OnDeserialized()

        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()}
Beispiel #26
0
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()
Beispiel #27
0
    def do_send(self, arguments):
        try:
            if not self.Wallet:
                print("please open a wallet")
                return
            if len(arguments) < 3:
                print("Not enough arguments")
                return

            to_send = get_arg(arguments)
            address = get_arg(arguments, 1)
            amount = get_arg(arguments, 2)

            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 = self.Wallet.ToScriptHash(address)
            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 = self.Wallet.MakeTransaction(tx=tx,
                                              change_address=None,
                                              fee=fee)

            if ttx is None:
                print("insufficient funds")
                return

            self._wallet_send_tx = ttx

            self._num_passwords_req = 1
            self._gathered_passwords = []
            self._gathering_password = True
            self._gather_password_action = self.do_send_created_tx

        except Exception as e:
            print("could not send: %s " % e)
            traceback.print_stack()
            traceback.print_exc()
Beispiel #28
0
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
    ]
Beispiel #29
0
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
Beispiel #30
0
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
Beispiel #31
0
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())
Beispiel #32
0
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()