Skip to content
This repository has been archived by the owner on Nov 15, 2021. It is now read-only.

Commit

Permalink
added support for attaching assets to invoke tx, added support for in…
Browse files Browse the repository at this point in the history
…voking with an array object
  • Loading branch information
localhuman committed Oct 2, 2017
1 parent c504e80 commit 0409eee
Show file tree
Hide file tree
Showing 8 changed files with 117 additions and 26 deletions.
5 changes: 5 additions & 0 deletions neo/Fixed8.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ def __init__(self, number):
self.value = number


def GetData(self):
return self.value


@staticmethod
def FromDecimal(number):
Expand Down Expand Up @@ -115,5 +118,7 @@ def __ge__(self, other):
def __le__(self, other):
return self.value <= other.value

def ToString(self):
return self.value / Fixed8.D
# def __str__(self):
# return self.value
53 changes: 44 additions & 9 deletions neo/Prompt/Commands/Invoke.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from neo.VM.ScriptBuilder import ScriptBuilder
from neo.VM.InteropService import InteropInterface
from neo.Network.NodeLeader import NodeLeader
from neo.Prompt.Utils import parse_param
from neo.Prompt.Utils import parse_param,get_asset_attachments

import binascii

Expand All @@ -19,6 +19,7 @@

from neo.Core.TX.InvocationTransaction import InvocationTransaction
from neo.Core.TX.TransactionAttribute import TransactionAttribute,TransactionAttributeUsage
from neo.Core.TX.Transaction import TransactionOutput

from neo.SmartContract.ApplicationEngine import ApplicationEngine
from neo.SmartContract import TriggerType
Expand All @@ -27,8 +28,11 @@
from neo.Cryptography.Crypto import Crypto
from neo.Fixed8 import Fixed8

from neo.Core.Blockchain import Blockchain

from neo.BigInteger import BigInteger
import traceback
import pdb

def InvokeContract(wallet, tx):

Expand Down Expand Up @@ -84,6 +88,11 @@ def TestInvokeContract(wallet, args):
return



params,neo_to_attach,gas_to_attach = get_asset_attachments(params)

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

params.reverse()

sb = ScriptBuilder()
Expand All @@ -94,7 +103,6 @@ def TestInvokeContract(wallet, args):

if type(item) is list:
listlength = len(item)
print("ITEM IS LIST, PUSH LENGTH: %s " % listlength)
sb.push(listlength)
for listitem in item:
sb.push(listitem)
Expand All @@ -106,7 +114,17 @@ def TestInvokeContract(wallet, args):

out = sb.ToArray()

return test_invoke(out, wallet)
outputs = []

if neo_to_attach:

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

return test_invoke(out, wallet, outputs)

else:

Expand All @@ -117,7 +135,9 @@ def TestInvokeContract(wallet, args):



def test_invoke(script, wallet):
def test_invoke(script, wallet, outputs):

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

bc = GetBlockchain()

Expand All @@ -131,23 +151,35 @@ def test_invoke(script, wallet):

tx = InvocationTransaction()
tx.Version = 1
tx.outputs = []
tx.outputs = outputs
tx.inputs = []
tx.scripts = []
tx.Script = binascii.unhexlify(script)
print("testing invokeeee %s " % tx.Script)

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

contract = wallet.GetDefaultContract()
# contract = wallet.GetDefaultContract()

# tx.Attributes = [TransactionAttribute(usage=TransactionAttributeUsage.Script, data=Crypto.ToScriptHash( contract.Script))]


wallet_tx = wallet.MakeTransaction(tx=tx)

if wallet_tx:

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

if context.Completed:
tx.scripts = context.GetScripts()


tx.Attributes = [TransactionAttribute(usage=TransactionAttributeUsage.Script, data=Crypto.ToScriptHash( contract.Script))]


engine = ApplicationEngine(
trigger_type=TriggerType.Application,
container=tx,
container=wallet_tx,
table=script_table,
service=service,
gas=tx.Gas,
Expand Down Expand Up @@ -180,6 +212,9 @@ def test_invoke(script, wallet):
return tx, engine.EvaluationStack.Items
else:
print("error executing contract.....")
tx.Gas = Fixed8.One()
tx.Attributes = []
return tx, []

except Exception as e:
print("COULD NOT EXECUTE %s " % e)
Expand Down
31 changes: 27 additions & 4 deletions neo/Prompt/Utils.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,36 @@
import binascii
from neo.BigInteger import BigInteger
from neo.Fixed8 import Fixed8

import pdb

def get_asset_attachments(params):

to_remove = []
neo_to_attach = None
gas_to_attach = None
for item in params:
if '--attach-neo=' in item:
to_remove.append(item)
try:
neo_to_attach = Fixed8.TryParse(int(item.replace('--attach-neo=', '')))
except Exception as e:
pass
elif '--attach-gas=' in item:
to_remove.append(item)
try:
gas_to_attach = Fixed8.FromDecimal(float(item.replace('--attach-gas=', '')))
except Exception as e:
pass
for item in to_remove:
params.remove(item)


return params, neo_to_attach, gas_to_attach


def parse_param(p, ignore_int=False, prefer_hex=True):

print("parsing param: %s " % p)
# print("parsing param: %s " % p)

# pdb.set_trace()

Expand All @@ -19,11 +42,11 @@ def parse_param(p, ignore_int=False, prefer_hex=True):
parsed = []
for item in items:
parsed.append(parse_param(item))
print("PARSED %s " % parsed)
return parsed

except Exception as e:
print("couldnt eval items as array %s " % e)
# print("couldnt eval items as array %s " % e)
pass

if not ignore_int:
try:
Expand Down
2 changes: 2 additions & 0 deletions neo/SmartContract/StateMachine.py
Original file line number Diff line number Diff line change
Expand Up @@ -449,7 +449,9 @@ def Storage_Get(self, engine):
return False

key = engine.EvaluationStack.Pop().GetByteArray()

storage_key = StorageKey(script_hash=context.ScriptHash, key = key)

item = self._storages.TryGet(storage_key.GetHashCodeBytes())
if item is not None:

Expand Down
29 changes: 27 additions & 2 deletions neo/SmartContract/StateReader.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ def __init__(self):
self.Register("Neo.Transaction.GetType", self.Transaction_GetType)
self.Register("Neo.Transaction.GetAttributes", self.Transaction_GetAttributes)
self.Register("Neo.Transaction.GetInputs", self.Transaction_GetInputs)
self.Register("Neo.Transaction.GetOutpus", self.Transaction_GetOutputs)
self.Register("Neo.Transaction.GetOutputs", self.Transaction_GetOutputs)
self.Register("Neo.Transaction.GetReferences", self.Transaction_GetReferences)

self.Register("Neo.Attribute.GetData", self.Attribute_GetData)
Expand Down Expand Up @@ -210,6 +210,16 @@ def Runtime_CheckWitness(self, engine):
def Runtime_Notify(self, engine):

state = engine.EvaluationStack.Pop()


try:
items = state.GetArray()
for item in items:
print("[neo.SmartContract.StateReader] -> RUNTIME.Notify: %s " % str(item))
return True
except Exception as e:
print("Couldnt get array %s " % e)

print("[neo.SmartContract.StateReader] -> RUNTIME.Notify: %s " % str(state))
return True

Expand Down Expand Up @@ -393,6 +403,7 @@ def Header_GetTimestamp(self, engine):
if header is None:
return False
engine.EvaluationStack.PushT(header.Timestamp)

return True

def Header_GetConsensusData(self, engine):
Expand Down Expand Up @@ -481,21 +492,29 @@ def Transaction_GetInputs(self, engine):

def Transaction_GetOutputs(self, engine):


tx = engine.EvaluationStack.Pop().GetInterface('neo.Core.TX.Transaction.Transaction')

if tx is None:
return False

outputs = [StackItem.FromInterface(output) for output in tx.outputs]
outputs = []
for output in tx.outputs:
stackoutput = StackItem.FromInterface(output)
outputs.append(stackoutput)

engine.EvaluationStack.PushT(outputs)
return True

def Transaction_GetReferences(self, engine):

tx = engine.EvaluationStack.Pop().GetInterface('neo.Core.TX.Transaction.Transaction')

if tx is None:
return False

refs = [StackItem.FromInterface(tx.References[input]) for input in tx.inputs]

engine.EvaluationStack.PushT(refs)
return True

Expand Down Expand Up @@ -534,8 +553,10 @@ def Input_GetIndex(self, engine):
def Output_GetAssetId(self, engine):

output = engine.EvaluationStack.Pop().GetInterface('neo.Core.TX.Transaction.TransactionOutput')

if output is None:
return False

engine.EvaluationStack.PushT(output.AssetId.ToArray())
return True

Expand All @@ -544,14 +565,17 @@ def Output_GetValue(self, engine):
output = engine.EvaluationStack.Pop().GetInterface('neo.Core.TX.Transaction.TransactionOutput')
if output is None:
return False

engine.EvaluationStack.PushT(output.Value.GetData())
return True

def Output_GetScriptHash(self, engine):

output = engine.EvaluationStack.Pop().GetInterface('neo.Core.TX.Transaction.TransactionOutput')

if output is None:
return False

engine.EvaluationStack.PushT(output.ScriptHash.ToArray())
return True

Expand Down Expand Up @@ -680,6 +704,7 @@ def Storage_Get(self, engine):

item = Blockchain.Default().GetStorageItem(storage_key)


if item is not None:

engine.EvaluationStack.PushT( item.Value)
Expand Down
6 changes: 3 additions & 3 deletions neo/VM/ExecutionEngine.py
Original file line number Diff line number Diff line change
Expand Up @@ -200,8 +200,8 @@ def ExecuteOp(self, opcode, context):
self.LoadScript(script)

elif opcode == SYSCALL:

if not self._Service.Invoke( context.OpReader.ReadVarBytes(252).decode('ascii'), self):
call = context.OpReader.ReadVarBytes(252).decode('ascii')
if not self._Service.Invoke( call, self):
self._VMState |= VMState.FAULT

#stack operations
Expand Down Expand Up @@ -441,7 +441,7 @@ def ExecuteOp(self, opcode, context):

x2 = estack.Pop().GetBigInteger()
x1 = estack.Pop().GetBigInteger()
# print("x2, x1 %s .. %s " % (x2, x1))

estack.PushT(x1 - x2)

elif opcode == MUL:
Expand Down
12 changes: 5 additions & 7 deletions neo/VM/InteropService.py
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,6 @@ def Register(self, method, func):
self._dictionary[method] = func

def Invoke(self, method, engine):

if not method in self._dictionary.keys():

self.__log.debug("method %s not found in ->" % method)
Expand All @@ -299,27 +298,26 @@ def Invoke(self, method, engine):
return False

func = self._dictionary[method]
#print("invoking method -> %s" % func)


return func(engine)

@staticmethod
def GetScriptContainer(engine):

engine.EvaluationStack.PushT( StackItem.FromInterface(engine.ScriptContainer))
return True

@staticmethod
def GetExecutingScriptHash(engine):
engine.EvaluationStack.PushT( engine.CurrentContext.ScriptHash )
engine.EvaluationStack.PushT( engine.CurrentContext.ScriptHash() )
return True

@staticmethod
def GetCallingScriptHash(engine):
engine.EvaluationStack.PushT( engine.CallingContext.ScriptHash )
engine.EvaluationStack.PushT( engine.CallingContext.ScriptHash() )
return True

@staticmethod
def GetEntryScriptHash(engine):
engine.EvaluationStack.PushT( engine.EntryContext.ScriptHash )

engine.EvaluationStack.PushT( engine.EntryContext.ScriptHash() )
return True
5 changes: 4 additions & 1 deletion neo/Wallets/Wallet.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
from neo.Core.Helper import Helper
from Crypto import Random
from Crypto.Cipher import AES

import pdb
@logged
class Wallet(object):

Expand Down Expand Up @@ -502,6 +502,9 @@ def MakeTransaction(self, tx, change_address = None, fee = Fixed8(0)):
if not tx.outputs: tx.outputs = []
if not tx.inputs: tx.inputs = []

# for o in tx.outputs:
# print("OUTPUT %s " % json.dumps(o.ToJson(), indent=4))

fee = fee + tx.SystemFee()

paytotal = {}
Expand Down

0 comments on commit 0409eee

Please sign in to comment.