Skip to content
This repository has been archived by the owner on Mar 28, 2023. It is now read-only.

Using Inputs.GetHash and Transaction.GetHash in the same contract #38

Closed
slipo opened this issue Feb 2, 2018 · 4 comments
Closed

Using Inputs.GetHash and Transaction.GetHash in the same contract #38

slipo opened this issue Feb 2, 2018 · 4 comments

Comments

@slipo
Copy link
Contributor

slipo commented Feb 2, 2018

I was having quite a difficult time using Input.GetHash and Transaction.GetHash in the same contract. I ended up doing the following trick to get the compiler to allow me to.

@@ -697,6 +697,9 @@ class VMTokenizer(object):
             if fname == m.name:
                 full_name = m.full_name
 
+        if fname == 'InputGetHash':
+            full_name = 'boa.blockchain.vm.Neo.Input.GetHash'
+
         # operational call like len(items) or abs(value)
         if self.is_op_call(fname):
             vmtoken = self.convert_op_call(fname, pytoken)

Then in my contract I have a dummy function called InputGetHash.

Before doing this I tried everything including separating the calls into separate files. Any clues or is this a bug?

@slipo
Copy link
Contributor Author

slipo commented Feb 2, 2018

BTW, if anybody wants to confirm this is a bug and point me in the right direction to fixing it, I'm happy to take a look. I'm still pretty new to the codebase so just want to make sure I'm not missing something.

@trendsetter37
Copy link

@slipo can you post the entire contract file for more context?

@slipo
Copy link
Contributor Author

slipo commented Feb 8, 2018

Sure.

Here's example 1 which works:

from boa.blockchain.vm.Neo.Runtime import GetTrigger
from boa.blockchain.vm.Neo.TriggerType import Application, Verification
from boa.blockchain.vm.System.ExecutionEngine import GetScriptContainer
from boa.blockchain.vm.Neo.Storage import GetContext
from boa.blockchain.vm.Neo.Transaction import GetUnspentCoins, GetHash

def Main(operation, args):
    trigger = GetTrigger()

    if trigger == Application():
        if operation == 'deposit':
            tx = GetScriptContainer()
            tx_hash = tx.Hash
            print(tx_hash)

    return False

Here's example 2 which adds a call to Input.GetHash thereby breaking tx.Hash:

from boa.blockchain.vm.Neo.Runtime import GetTrigger
from boa.blockchain.vm.Neo.TriggerType import Application, Verification
from boa.blockchain.vm.System.ExecutionEngine import GetScriptContainer
from boa.blockchain.vm.Neo.Storage import GetContext
from boa.blockchain.vm.Neo.Transaction import GetInputs, GetUnspentCoins
from boa.blockchain.vm.Neo.Input import GetIndex, GetHash

def Main(operation, args):
    trigger = GetTrigger()

    if trigger == Verification():
        tx = GetScriptContainer()

        valid = True

        for input in tx.Inputs:
            hash = GetHash(input)
            print(hash)

        return valid

    elif trigger == Application():
        if operation == 'deposit':
            tx = GetScriptContainer()
            tx_hash = tx.Hash
            print(tx_hash)

    return False

Note: I don't even need to import Transaction.GetHash in this. And I haven't found a way to import it so it doesn't conflict with Input.GetHash.

When I run testinvoke EXAMPLE_2_SCRIPT_HASH deposit [] --attach-gas=1 I get errors like:

[E 180208 03:24:18 ExecutionEngine:852] COULD NOT EXECUTE OP: Invalid list operation b'\x9c' NUMEQUAL
[E 180208 03:24:18 ExecutionEngine:853] Invalid list operation

Originally somehow I think I saw an error related to Input's PrevHash not existing in tx which was my original clue of this issue.

@localhuman
Copy link
Collaborator

This is a little tricky since there's three things named GetHash in the interop module. Without type checking in python it's difficult to tell which one to use. Regardless, there is a workaround in the new version of the compiler. If you want to use tx.Hash and input.Hash in the same contract, you should use the long form version of the input.Hash attr accessor, which is GetInputHash(input)

You can see an example here, which uses both in the same contract: https://github.com/CityOfZion/neo-boa/blob/master/boa_test/example/blockchain/TransactionTest.py#L88

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants