# Problem with ed25519verify

**URL:** <https://forum.algorand.co/t/problem-with-ed25519verify/8088>\
**Category:** General\
**Tags:** smart-contracts\
**Created:** [October 19, 2022, 5:15pm UTC](https://forum.algorand.co/t/problem-with-ed25519verify/8088 "2022-10-19T17:15:11Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![pogginicolo98](https://avatars.discourse-cdn.com/v4/letter/p/4af34b/32.png) [@pogginicolo98](https://forum.algorand.co/u/pogginicolo98)\
**Post date:** [October 19, 2022, 5:15pm UTC](https://forum.algorand.co/t/problem-with-ed25519verify/8088/1 "2022-10-19T17:15:12Z")

</div>

Hi everyone!  
As described in the title I’m having trouble using the Ed25519Verify function.  
I’m not understanding the following error and even doing some research I haven’t found useful information to solve it:

> algosdk.error.AlgodHTTPError: TransactionPool.Remember: transaction L5SNG7ALALAM5RMTAZDIYIBJ3TWIIXL5BMOABV3STIC2CRD4BWLQ: logic eval error: pc=383 dynamic cost budget exceeded, executing ed25519verify: local program cost was 42. Details: pc=383, opcodes=txna ApplicationArgs 2  
> txna ApplicationArgs 3  
> ed25519verify

I think the problem is that the function is computationally too expensive but also reducing the method to a single Assert with Ed25519Verify() and an Approve() does not change.

Below I report part of the code of my smart contract and the Python code i use to create the transaction:

Smart contract

```auto
    @Subroutine(TealType.none)
    def delegate_vote():
        return Seq(
            Assert(
                Ed25519Verify(Txn.application_args[1], Txn.application_args[2], Txn.application_args[3]),
            ),
            Approve()
        )

```

Transaction

```auto
def sign_param(hash, app_account, private_key):
    to_sign = (
        b"ProgData"
        + encoding.decode_address(app_account)
        + hash
    )
    signature = sign_bytes(to_sign, private_key)
    return signature

```

```auto
op = "test_ed25519verify"
param = "data"
hash = base64.b64encode(sha256(param.encode("utf-8")).digest())
sign = sign_param(hash, app_account, delegator['private_key'])
app_args = [op, hash, str(sign), delegator['address']]
vote_txn = make_app_call_txn(client, app_id, sender['address'], app_args)

```

In \*\* make\_app\_call\_txn \*\* I encode of the app\_args and the final result is the following:

> [b’test\_ed25519verify’, b’Om6weQ85rIfJTzhWst0sXREOaBFgImGpqSPTuyOtyLc=‘, b’MsmsZbtLNwycFXlfLpba4llJk0EW27OumW6jZaKWkRwBGg56QjeSujDi8JgIv14XNOsWZj4CROtwolrVQfsiBw==’, b’JG3IBNG4LBCPAVYB5VISGIS3QCL4LLFVP3K6UIKBFB3MESVRE7Y5BNYUBA’]

---

<div class="post-metadata">

**Author:** ![Ben](https://sea2.discourse-cdn.com/flex016/user_avatar/forum.algorand.co/ben/32/1979_2.png) [@Ben](https://forum.algorand.co/u/Ben)\
**Post date:** [October 19, 2022, 6:07pm UTC](https://forum.algorand.co/t/problem-with-ed25519verify/8088/2 "2022-10-19T18:07:30Z")

</div>

You can make additional “noop” app calls to increase your opcode budget, note that you’ll need to appropriately handle them in the contract and probably add some nonce to the note field since they’ll probably be identical besides that and you’ll get an error message saying something like “transaction already in ledger”

---

<div class="post-metadata">

**Author:** ![pogginicolo98](https://avatars.discourse-cdn.com/v4/letter/p/4af34b/32.png) [@pogginicolo98](https://forum.algorand.co/u/pogginicolo98)\
**Post date:** [October 20, 2022, 10:50am UTC](https://forum.algorand.co/t/problem-with-ed25519verify/8088/3 "2022-10-20T10:50:21Z")

</div>

Thanks, your solution solved the budget opcode problem, but I still have problems running the Ed25519Verify function correctly.  
In order to give you as much info as possible, I will post the entire code I’m running.

Smart contract:

```auto
from pyteal import *
from lib.pyteal_helpers import program

def approval():
    op_test_ed25519_verify = Bytes("ed25519_verify")
    op_increase_budget = Bytes("increase budget")

    @Subroutine(TealType.none)
    def test_ed25519_verify():
        return Seq(
            Assert(
                Ed25519Verify(Txn.application_args[1], Txn.application_args[2], Txn.accounts[1]),
            ),
            Approve()
        )

    @Subroutine(TealType.none)
    def increase_budget():
        return Seq(
            Approve()
        )

    return program.event(
        init=Approve(),
        delete=Approve(),
        update=Approve(),
        close_out=Approve(),
        opt_in=Approve(),
        no_op=Seq(
            Cond(
                [
                    Txn.application_args[0] == op_test_ed25519_verify,
                    test_ed25519_verify()
                ],
                [
                    Txn.application_args[0] == op_increase_budget,
                    increase_budget()
                ],
            ),
            Reject(),
        ),
    )

def clear():
    return Approve()

```

After compile, deploy and optin I run this Python script:

```auto
import base64

from algosdk import encoding
from algosdk.future import transaction
from hashlib import sha256
from lib.utils.accounts import load_account
from lib.utils.clients import get_algod_client
from lib.utils.transaction_composer import load_sc

def sign_data(data, app_account, private_key):
    to_sign = (
        b"ProgData"
        + encoding.decode_address(app_account)
        + data
    )
    signing_key = transaction.SigningKey(base64.b64decode(private_key)[:32])
    signed = signing_key.sign(to_sign)
    return signed.signature

def noop_call(client, sender, data_signer, sc):
    print(f'Testing Ed25519Verify...')
    # Transaction to test Ed25519Verify
    op = "ed25519_verify"
    param = "data"
    data = sha256(param.encode('utf-8')).digest()
    signed_data = sign_data(data, sc['account'], data_signer['private_key'])
    app_args = [op.encode("utf-8"), base64.b64encode(data), base64.b64encode(signed_data)]
    sp_params = client.suggested_params()
    accounts = [data_signer['address']]
    ed25519_verify_txn = transaction.ApplicationNoOpTxn(sender['address'], sp_params, sc['id'], app_args, accounts)

    # Transaction to increase opcode budget n.1
    op = "increase budget"
    note = "txn 1".encode("utf-8")
    app_args = [op.encode("utf-8")]
    sp_params = client.suggested_params()
    increase_budget_1_txn = transaction.ApplicationNoOpTxn(sender['address'], sp_params, sc['id'], app_args, note=note)

    # Transaction to increase opcode budget n.2
    note = "txn 2".encode("utf-8")
    sp_params = client.suggested_params()
    increase_budget_2_txn = transaction.ApplicationNoOpTxn(sender['address'], sp_params, sc['id'], app_args, note=note)

    group_id = transaction.calculate_group_id([ed25519_verify_txn, increase_budget_1_txn, increase_budget_2_txn])
    ed25519_verify_txn.group = group_id
    increase_budget_1_txn.group = group_id
    increase_budget_2_txn.group = group_id

    signed_txn_1 = ed25519_verify_txn.sign(sender['private_key'])
    signed_txn_2 = increase_budget_1_txn.sign(sender['private_key'])
    signed_txn_3 = increase_budget_2_txn.sign(sender['private_key'])
    signed_txns = [signed_txn_1, signed_txn_2, signed_txn_3]

    tx_id = client.send_transactions(signed_txns)
    try:
        transaction_response = transaction.wait_for_confirmation(client, tx_id, 2)
    except Exception as err:
        print(err)
        return
    print(f'Test Ed25519Verify successful')

def main():
    client = get_algod_client()
    sender = load_account("master")
    data_signer = load_account("user")
    sc = load_sc('test')
    noop_call(client, sender, data_signer, sc)

if __name__ == ' __main__':
    main()

```

These are my **app\_args** :

> [b’ed25519\_verify’, b’Om6weQ85rIfJTzhWst0sXREOaBFgImGpqSPTuyOtyLc=‘, b’nHwAgzHAwbefshLVGVNtFgMrUsszk+lFLlbwy6zzbhjoshU4I0aoGLMBDwbL9iRaWqPybkSSgB5gLRRE0KlYDw==’]

This is the error:

> algosdk.error.AlgodHTTPError: TransactionPool.Remember: transaction ZQCM3NINZTTIU6K2OQPPZVN5G2A2XK54FR4PJXU6FZSFI4Q47ZWA: logic eval error: invalid signature. Details: pc=129, opcodes=txna ApplicationArgs 2  
> txna Accounts 1  
> ed25519verify

I think the problem is how I sign **data** or the format of **app\_args** is wrong.  
The **sign\_data()** function is an adapted version of the one you posted some time ago in another [topic](https://forum.algorand.co/t/unable-to-use-ed25519verify-with-pyteal-and-python-algorand-sdk/7400): [https://github.com/algorand-devrel/decipher-drop/blob/main/util.py#L82-L92](https://github.com/algorand-devrel/decipher-drop/blob/main/util.py#L82-L92)

---

<div class="post-metadata">

**Author:** ![Ben](https://sea2.discourse-cdn.com/flex016/user_avatar/forum.algorand.co/ben/32/1979_2.png) [@Ben](https://forum.algorand.co/u/Ben)\
**Post date:** [October 20, 2022, 11:18am UTC](https://forum.algorand.co/t/problem-with-ed25519verify/8088/4 "2022-10-20T11:18:40Z")

</div>

I see at least 1 issue, that is using the `app_addr` to prefix the data, the method requires the hash of the contract _not_ the app address. While for lsigs the address is the hash of the program, applications addresses are the hash of the app id. You can get the hash of the approval program when you compile it or you can use the new op as of AVM7 `ed25519verify_bare` which doesn’t require any special prefixing prior to hashing

---

<div class="post-metadata">

**Author:** ![pogginicolo98](https://avatars.discourse-cdn.com/v4/letter/p/4af34b/32.png) [@pogginicolo98](https://forum.algorand.co/u/pogginicolo98)\
**Post date:** [October 20, 2022, 2:13pm UTC](https://forum.algorand.co/t/problem-with-ed25519verify/8088/5 "2022-10-20T14:13:10Z")

</div>

> [@Ben](#):
>
> ed25519verify\_bare

Thanks, I used `ed25519verify_bare` and with your suggestions I was able to verify the signature correctly!
