Exemplo n.º 1
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
Exemplo n.º 2
0
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()

            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
Exemplo n.º 3
0
def InvokeWithTokenVerificationScript(wallet, tx, token, fee=Fixed8.Zero(), invoke_attrs=None):

    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)
        ]

        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()

            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
Exemplo n.º 4
0
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
Exemplo n.º 5
0
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
Exemplo n.º 6
0
    def begin_send(wallet, arguments):

        to_send = arguments[0]
        address_to = arguments[1]
        amount = arguments[2]
        from_address = arguments[3]

        assetId = None

        if to_send == 'neo':
            assetId = Blockchain.Default().SystemShare().Hash
        else:
            assetId = Blockchain.Default().SystemCoin().Hash

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

        f8amount = Fixed8.TryParse(amount)

        if f8amount.value % pow(
                10, 8 - Blockchain.Default().GetAssetState(
                    assetId.ToBytes()).Precision) != 0:
            print("incorrect amount precision")
            return

        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, were funds already moved from multi-sig contract?"
            )
            return None

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

        if context.Completed:
            print("Something went wrong, multi-sig transaction failed")
            return None

        else:
            print("Transaction initiated")
            return json.dumps(context.ToJson(), separators=(',', ':'))
Exemplo n.º 7
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()]
Exemplo n.º 8
0
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
Exemplo n.º 9
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)
Exemplo n.º 10
0
    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
Exemplo n.º 11
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
Exemplo n.º 12
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
Exemplo n.º 13
0
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
Exemplo n.º 14
0
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
Exemplo n.º 15
0
def testNeoClient():
    invocation_tx = InvocationTransaction()

    smartcontract_scripthash = UInt160.ParseString(CONTRACT_HASH)
    sb = ScriptBuilder()
    sb.EmitAppCallWithOperationAndArgs(
        smartcontract_scripthash, 'onboard',
        [b'Munich', b'*****@*****.**', b'xxx'])
    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 json.dumps({
        "raw_tx": raw_tx.decode("ascii"),
        "result": result,
        "payload": payload,
    })
Exemplo n.º 16
0
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
Exemplo n.º 17
0
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
Exemplo n.º 18
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)
Exemplo n.º 19
0
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
Exemplo n.º 20
0
    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()
Exemplo n.º 21
0
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
Exemplo n.º 22
0
def construct_invoke_tx(wallet, params):
    params = params[0]
    from_addr = params['from_addr']
    
    BC = GetBlockchain()

    contract = BC.GetContract(params['addr'])

    if not contract:
        raise Exception('no such contract')

    neo_to_attach = params.get('neo_to_attach', 0)
    gas_to_attach = params.get('gas_to_attach', 0)

    sb = ScriptBuilder()
    contract_parameters = [ContractParameter.FromJson(p) for p in params['contract_params']]
    sb.EmitAppCallWithJsonArgs(contract.Code.ScriptHash(), contract_parameters)
    
    invoke_script = sb.ToArray()

    outputs = []

    if neo_to_attach:

        output = TransactionOutput(AssetId=Blockchain.SystemShare().Hash,
                Value=neo_to_attach,
                script_hash=contract.Code.ScriptHash(),
        )
        outputs.append(output)

    if gas_to_attach:

        output = TransactionOutput(AssetId=Blockchain.SystemCoin().Hash,
                Value=gas_to_attach,
                script_hash=contract.Code.ScriptHash(),
        )

        outputs.append(output)

    bc = GetBlockchain()
    sn = bc._db.snapshot()
    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)


    tx = InvocationTransaction()
    tx.outputs = outputs
    tx.inputs = []
    tx.Version = 1
    tx.scripts = []
    tx.Script = binascii.unhexlify(invoke_script)

    script_table = CachedScriptTable(contracts)
    service = StateMachine(accounts, validators, assets, contracts, storages, None)
    contract = wallet.GetDefaultContract()
    tx.Attributes = [TransactionAttribute(usage=TransactionAttributeUsage.Script, data=Crypto.ToScriptHash(contract.Script, unhex=False).Data)]
    tx = wallet.MakeTransaction(tx=tx)

    engine = ApplicationEngine(
            trigger_type=TriggerType.Application,
            container=tx,
            table=script_table,
            service=service,
            gas=tx.Gas,
            testMode=True
    )   
    engine.LoadScript(tx.Script, False)
    success = engine.Execute()
    if not success:
        raise Exception('exec failed')
    
    service.ExecutionCompleted(engine, success)

    consumed = engine.GasConsumed() - Fixed8.FromDecimal(10)
    consumed = consumed.Ceil()

    net_fee = None
    tx_gas = None

    if consumed <= Fixed8.Zero():
        net_fee = Fixed8.FromDecimal(.0001)
        tx_gas = Fixed8.Zero()
    else:
        tx_gas = consumed
        net_fee = Fixed8.Zero()
    tx.Gas = tx_gas
    tx.outputs = outputs
    tx.Attributes = []



    # InvokeContract
    from_addr = lookup_addr_str(wallet, from_addr)
    tx = wallet.MakeTransaction(tx=tx, fee=net_fee, use_standard=True, from_addr=from_addr)
    if tx is None:
        raise Exception("no gas")


    context = ContractParametersContext(tx)
    ms = StreamManager.GetStream()
    writer = BinaryWriter(ms)
    tx.Serialize(writer)
    ms.flush()
    binary_tx = ms.ToArray()
    return {'context': context.ToJson(), 'tx': binary_tx.decode()}
Exemplo n.º 23
0
def construct_deploy_tx(wallet, params):
    params = params[0]
    from_addr = params['from_addr']
    # load_smart_contract
    contract_params = bytearray(binascii.unhexlify(params['contract_params']))
    return_type = bytearray(binascii.unhexlify(params['return_type']))
    
    contract_properties = 0
    if params.get('needs_storage', True):
        contract_properties += ContractPropertyState.HasStorage
    if params.get('needs_dynamic_invoke', False):
        contract_properties += ContractPropertyState.HasDynamicInvoke

    script = binascii.unhexlify(params['bin'])

    function_code = FunctionCode(
            script = script,
            param_list = contract_params,
            return_type = return_type,
            contract_properties = contract_properties,
    )

    if Blockchain.Default().GetContract(function_code.ScriptHash().To0xString()):
        raise Exception('contract already exists')

    # GatherContractDetails
    details = params['details']
    name = details['name']
    version = details['version']
    author = details['author']
    email = details['email']
    description = details['description']

    contract_script = generate_deploy_script(
            function_code.Script,
            name,
            version,
            author,
            email,
            description,
            function_code.ContractProperties,
            function_code.ReturnType,
            function_code.ParameterList,
    )

    # test_invoke    
    bc = GetBlockchain()
    sn = bc._db.snapshot()
    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)


    tx = InvocationTransaction()
    tx.outputs = []
    tx.inputs = []
    tx.Version = 1
    tx.scripts = []
    tx.Script = binascii.unhexlify(contract_script)

    script_table = CachedScriptTable(contracts)
    service = StateMachine(accounts, validators, assets, contracts, storages, None)
    contract = wallet.GetDefaultContract()
    tx.Attributes = [TransactionAttribute(usage=TransactionAttributeUsage.Script, data=Crypto.ToScriptHash(contract.Script, unhex=False).Data)]
    tx = wallet.MakeTransaction(tx=tx)

    engine = ApplicationEngine(
            trigger_type=TriggerType.Application,
            container=tx,
            table=script_table,
            service=service,
            gas=tx.Gas,
            testMode=True
    )   
    engine.LoadScript(tx.Script, False)
    success = engine.Execute()
    if not success:
        raise Exception('exec failed')
    
    service.ExecutionCompleted(engine, success)

    consumed = engine.GasConsumed() - Fixed8.FromDecimal(10)
    consumed = consumed.Ceil()

    net_fee = None
    tx_gas = None

    if consumed <= Fixed8.Zero():
        net_fee = Fixed8.FromDecimal(.0001)
        tx_gas = Fixed8.Zero()
    else:
        tx_gas = consumed
        net_fee = Fixed8.Zero()
    tx.Gas = tx_gas
    tx.outputs = []
    tx.Attributes = []

    # InvokeContract
    from_addr = lookup_addr_str(wallet, from_addr)
    tx = wallet.MakeTransaction(tx=tx, fee=net_fee, use_standard=True, from_addr=from_addr)
    if tx is None:
        raise Exception("no gas")


    context = ContractParametersContext(tx)
    ms = StreamManager.GetStream()
    writer = BinaryWriter(ms)
    tx.Serialize(writer)
    ms.flush()
    binary_tx = ms.ToArray()
    return {'context': context.ToJson(), 'tx': binary_tx.decode(), 'hash': function_code.ScriptHash().To0xString()}
Exemplo n.º 24
0
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()}
Exemplo n.º 25
0
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
Exemplo n.º 26
0
def test_invoke(script,
                wallet,
                outputs,
                withdrawal_tx=None,
                from_addr=None,
                min_fee=DEFAULT_MIN_FEE,
                invoke_attrs=None,
                owners=None):
    # print("invoke script %s " % script)

    if from_addr is not None:
        from_addr = PromptUtils.lookup_addr_str(wallet, from_addr)

    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 we are using a withdrawal tx, don't recreate the invocation tx
    # also, we don't want to reset the inputs / outputs
    # since those were already calculated
    if withdrawal_tx is not None:
        tx = withdrawal_tx

    else:
        tx = InvocationTransaction()
        tx.outputs = outputs
        tx.inputs = []

    tx.Version = 1
    tx.scripts = []
    tx.Script = binascii.unhexlify(script)
    tx.Attributes = [] if invoke_attrs is None else deepcopy(invoke_attrs)

    script_table = CachedScriptTable(contracts)
    service = StateMachine(accounts, validators, assets, contracts, storages,
                           None)

    if len(outputs) < 1:
        contract = wallet.GetDefaultContract()
        tx.Attributes.append(
            TransactionAttribute(usage=TransactionAttributeUsage.Script,
                                 data=contract.ScriptHash))
        tx.Attributes = make_unique_script_attr(tx.Attributes)

    # same as above. we don't want to re-make the transaction if it is a withdrawal tx
    if withdrawal_tx is not None:
        wallet_tx = tx
    else:
        try:
            wallet_tx = wallet.MakeTransaction(tx=tx,
                                               from_addr=from_addr,
                                               skip_fee_calc=True)
        except ValueError:
            pass

    context = ContractParametersContext(wallet_tx)
    wallet.Sign(context)

    if owners:
        owners = list(owners)
        for owner in owners:
            #            print("contract %s %s" % (wallet.GetDefaultContract().ScriptHash, owner))
            if wallet.GetDefaultContract().ScriptHash != owner:
                wallet_tx.Attributes.append(
                    TransactionAttribute(
                        usage=TransactionAttributeUsage.Script, data=owner))
                wallet_tx.Attributes = make_unique_script_attr(tx.Attributes)
        context = ContractParametersContext(wallet_tx, isMultiSig=True)

    if context.Completed:
        wallet_tx.scripts = context.GetScripts()
    else:
        logger.warning(
            "Not gathering signatures for test build.  For a non-test invoke that would occur here."
        )
    #        if not gather_signatures(context, wallet_tx, owners):
    #            return None, [], 0, None

    engine = ApplicationEngine(trigger_type=TriggerType.Application,
                               container=wallet_tx,
                               table=script_table,
                               service=service,
                               gas=wallet_tx.Gas,
                               testMode=True)

    engine.LoadScript(wallet_tx.Script)

    try:
        success = engine.Execute()

        service.ExecutionCompleted(engine, success)

        for event in service.events_to_dispatch:
            events.emit(event.event_type, event)

        if success:

            # this will be removed in favor of neo.EventHub
            if len(service.notifications) > 0:
                for n in service.notifications:
                    Blockchain.Default().OnNotify(n)

            # print("Used %s Gas " % engine.GasConsumed().ToString())

            consumed = engine.GasConsumed() - Fixed8.FromDecimal(10)
            consumed = consumed.Ceil()

            net_fee = None
            tx_gas = None

            if consumed <= Fixed8.Zero():
                net_fee = min_fee
                tx_gas = Fixed8.Zero()
            else:
                tx_gas = consumed
                net_fee = Fixed8.Zero()

            # set the amount of gas the tx will need
            wallet_tx.Gas = tx_gas
            # reset the wallet outputs
            wallet_tx.outputs = outputs
            wallet_tx.Attributes = [] if invoke_attrs is None else deepcopy(
                invoke_attrs)

            # calculate the required network fee for the tx and compare to fee
            if wallet_tx.Size() > settings.MAX_FREE_TX_SIZE:
                req_fee = Fixed8.FromDecimal(
                    settings.FEE_PER_EXTRA_BYTE *
                    (wallet_tx.Size() - settings.MAX_FREE_TX_SIZE))
                if req_fee < settings.LOW_PRIORITY_THRESHOLD:
                    req_fee = settings.LOW_PRIORITY_THRESHOLD
                if net_fee < req_fee:
                    net_fee = req_fee

            return wallet_tx, net_fee, engine.ResultStack.Items, engine.ops_processed, success

        # this allows you to to test invocations that fail
        else:
            wallet_tx.outputs = outputs
            wallet_tx.Attributes = [] if invoke_attrs is None else deepcopy(
                invoke_attrs)
            return wallet_tx, min_fee, [], engine.ops_processed, success

    except Exception as e:
        service.ExecutionCompleted(engine, False, e)

    return None, None, None, None, False
Exemplo n.º 27
0
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)
    except ValueError:
        print(
            "Insufficient funds. No unspent outputs available for building the transaction.\n"
            "If you are trying to sent multiple transactions in 1 block, then make sure you have enough 'vouts'\n."
            "Use `wallet unspent` and `wallet address split`, or wait until the first transaction is processed before sending another."
        )
        return
    except TXFeeError as e:
        print(e)
        return

    if tx is None:
        logger.debug("insufficient funds")
        return

    try:
        print("Validate your transaction details")
        print("-" * 33)
        input_coinref = wallet.FindCoinsByVins(tx.inputs)[0]
        source_addr = input_coinref.Address
        for order in tx.outputs:
            dest_addr = order.Address
            value = order.Value.ToString()  # fixed8
            if order.AssetId == Blockchain.Default().SystemShare().Hash:
                asset_name = 'NEO'
            else:
                asset_name = 'GAS'

            if source_addr != dest_addr:
                print(
                    f"Sending {value} {asset_name} from {source_addr} to {dest_addr}"
                )
            else:
                print(
                    f"Returning {value} {asset_name} as change to {dest_addr}")
        print(" ")
        print("Enter your password to send to the network")

        try:
            passwd = prompt("[Password]> ", is_password=True)
        except KeyboardInterrupt:
            print("Transaction cancelled")
            return
        if not wallet.ValidatePassword(passwd):
            print("Incorrect password")
            return

        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()
            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. Use the `sign` command with the information below to complete signing."
            )
            print(json.dumps(context.ToJson(), separators=(',', ':')))
            return

    except Exception as e:
        print("Could not send: %s " % e)
        traceback.print_stack()
        traceback.print_exc()

    return
Exemplo n.º 28
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
Exemplo n.º 29
0
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):

    bc = GetBlockchain()

    sn = bc._db.snapshot()

    accounts = DBCollection(bc._db, sn, DBPrefix.ST_Account, AccountState)
    assets = DBCollection(bc._db, sn, DBPrefix.ST_Asset, AssetState)
    validators = DBCollection(bc._db, sn, DBPrefix.ST_Validator,
                              ValidatorState)
    contracts = DBCollection(bc._db, sn, DBPrefix.ST_Contract, ContractState)
    storages = DBCollection(bc._db, sn, DBPrefix.ST_Storage, StorageItem)

    if settings.USE_DEBUG_STORAGE:
        debug_storage = DebugStorage.instance()
        debug_sn = debug_storage.db.snapshot()
        storages = DBCollection(debug_storage.db, debug_sn,
                                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 = lookup_addr_str(wallet, from_addr)

    dtx = wallet.MakeTransaction(tx=dtx, from_addr=from_addr)
    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))
    ]

    to_dispatch = []

    engine = ApplicationEngine(trigger_type=TriggerType.Application,
                               container=dtx,
                               table=script_table,
                               service=service,
                               gas=dtx.Gas,
                               testMode=True)

    engine.LoadScript(dtx.Script, False)

    # first we will execute the test deploy
    # then right after, we execute the test invoke

    d_success = engine.Execute()

    if d_success:

        items = engine.EvaluationStack.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 = get_asset_attachments(
            invoke_args)

        invoke_args.reverse()

        # print("neo, gas %s %s " % (neo_to_attach,gas_to_attach.ToString()))

        sb = ScriptBuilder()

        for p in invoke_args:

            item = parse_param(p, wallet)

            if type(item) is list:
                item.reverse()
                listlength = len(item)
                for listitem in item:
                    subitem = parse_param(listitem, wallet)
                    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 = []
        itx.Script = binascii.unhexlify(out)

        if len(outputs) < 1:
            contract = wallet.GetDefaultContract()
            itx.Attributes = [
                TransactionAttribute(usage=TransactionAttributeUsage.Script,
                                     data=Crypto.ToScriptHash(
                                         contract.Script, unhex=False).Data)
            ]

        itx = wallet.MakeTransaction(tx=itx, from_addr=from_addr)
        context = ContractParametersContext(itx)
        wallet.Sign(context)
        itx.scripts = context.GetScripts()

        #            print("tx: %s " % json.dumps(itx.ToJson(), indent=4))

        engine = ApplicationEngine(trigger_type=TriggerType.Application,
                                   container=itx,
                                   table=script_table,
                                   service=service,
                                   gas=itx.Gas,
                                   testMode=invocation_test_mode)

        engine.LoadScript(itx.Script, False)
        engine.LoadDebugInfo(debug_map)

        # call execute in its own blocking thread

        #        reactor.stop()

        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:
                    #                        print("NOTIFICATION : %s " % n)
                    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.EvaluationStack.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
Exemplo n.º 30
0
def test_invoke(script,
                wallet,
                outputs,
                withdrawal_tx=None,
                from_addr=None,
                min_fee=DEFAULT_MIN_FEE):

    # print("invoke script %s " % script)

    if from_addr is not None:
        from_addr = lookup_addr_str(wallet, from_addr)

    bc = GetBlockchain()

    sn = bc._db.snapshot()

    accounts = DBCollection(bc._db, sn, DBPrefix.ST_Account, AccountState)
    assets = DBCollection(bc._db, sn, DBPrefix.ST_Asset, AssetState)
    validators = DBCollection(bc._db, sn, DBPrefix.ST_Validator,
                              ValidatorState)
    contracts = DBCollection(bc._db, sn, DBPrefix.ST_Contract, ContractState)
    storages = DBCollection(bc._db, sn, DBPrefix.ST_Storage, StorageItem)

    # if we are using a withdrawal tx, don't recreate the invocation tx
    # also, we don't want to reset the inputs / outputs
    # since those were already calculated
    if withdrawal_tx is not None:
        tx = withdrawal_tx

    else:
        tx = InvocationTransaction()
        tx.outputs = outputs
        tx.inputs = []

    tx.Version = 1
    tx.scripts = []
    tx.Script = binascii.unhexlify(script)

    script_table = CachedScriptTable(contracts)
    service = StateMachine(accounts, validators, assets, contracts, storages,
                           None)

    if len(outputs) < 1:
        contract = wallet.GetDefaultContract()
        tx.Attributes = [
            TransactionAttribute(usage=TransactionAttributeUsage.Script,
                                 data=Crypto.ToScriptHash(contract.Script,
                                                          unhex=False).Data)
        ]

    # same as above. we don't want to re-make the transaction if it is a withdrawal tx
    if withdrawal_tx is not None:
        wallet_tx = tx
    else:
        wallet_tx = wallet.MakeTransaction(tx=tx, from_addr=from_addr)

    if wallet_tx:

        context = ContractParametersContext(wallet_tx)
        wallet.Sign(context)
        if context.Completed:
            wallet_tx.scripts = context.GetScripts()

    engine = ApplicationEngine(trigger_type=TriggerType.Application,
                               container=wallet_tx,
                               table=script_table,
                               service=service,
                               gas=wallet_tx.Gas,
                               testMode=True)

    engine.LoadScript(wallet_tx.Script, False)

    try:
        # drum roll?
        success = engine.Execute()

        service.ExecutionCompleted(engine, success)

        for event in service.events_to_dispatch:
            events.emit(event.event_type, event)

        if success:

            # this will be removed in favor of neo.EventHub
            if len(service.notifications) > 0:
                for n in service.notifications:
                    Blockchain.Default().OnNotify(n)

            print("Used %s Gas " % engine.GasConsumed().ToString())

            consumed = engine.GasConsumed() - Fixed8.FromDecimal(10)
            consumed = consumed.Ceil()

            net_fee = None
            tx_gas = None

            if consumed <= Fixed8.Zero():
                net_fee = min_fee
                tx_gas = Fixed8.Zero()
            else:
                tx_gas = consumed
                net_fee = Fixed8.Zero()

            # set the amount of gas the tx will need
            wallet_tx.Gas = tx_gas
            # reset the wallet outputs
            wallet_tx.outputs = outputs
            wallet_tx.Attributes = []

            return wallet_tx, net_fee, engine.EvaluationStack.Items, engine.ops_processed

    except Exception as e:
        service.ExecutionCompleted(engine, False, e)


#        print("COULD NOT EXECUTE %s " % e)

    return None, None, None, None