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

Commit

Permalink
initial implementation of local invoke
Browse files Browse the repository at this point in the history
  • Loading branch information
localhuman committed Sep 7, 2017
1 parent ec42bd5 commit 723a89e
Show file tree
Hide file tree
Showing 10 changed files with 194 additions and 32 deletions.
2 changes: 0 additions & 2 deletions fixtures/.gitignore
@@ -1,5 +1,3 @@
*
!.gitignore
!1050514.txt
!1321456.txt
!bigtx.txt
20 changes: 0 additions & 20 deletions neo/Core/ContractParameterType.py

This file was deleted.

1 change: 0 additions & 1 deletion neo/Implementations/Wallets/peewee/UserWallet.py
Expand Up @@ -27,7 +27,6 @@
TransactionInfo

from autologging import logged
from neo.SmartContract.ContractParameterType import ContractParameterType
import json

@logged
Expand Down
142 changes: 142 additions & 0 deletions neo/Prompt/Commands/Invoke.py
@@ -0,0 +1,142 @@
from neo.Blockchain import GetBlockchain
from neo.SmartContract.ContractParameterType import ContractParameterType, ToName
from neo.VM.ScriptBuilder import ScriptBuilder
import binascii
import json

from neo.Implementations.Blockchains.LevelDB.DBCollection import DBCollection
from neo.Implementations.Blockchains.LevelDB.DBPrefix import DBPrefix
from neo.Implementations.Blockchains.LevelDB.CachedScriptTable import CachedScriptTable
from neo.Core.State.UnspentCoinState import UnspentCoinState
from neo.Core.State.AccountState import AccountState
from neo.Core.State.CoinState import CoinState
from neo.Core.State.SpentCoinState import SpentCoinState,SpentCoinItem
from neo.Core.State.AssetState import AssetState
from neo.Core.State.ValidatorState import ValidatorState
from neo.Core.State.ContractState import ContractState
from neo.Core.State.StorageItem import StorageItem

from neo.Core.TX.InvocationTransaction import InvocationTransaction
from neo.Core.Witness import Witness

from neo.SmartContract.ApplicationEngine import ApplicationEngine
from neo.SmartContract import TriggerType
from neo.SmartContract.StateMachine import StateMachine

from neo.BigInteger import BigInteger

def InvokeContract(wallet, args, test=True):

# print("invoking contract! %s %s " % (wallet, args))

BC = GetBlockchain()

contract = BC.GetContract(args[0])

if contract:
descripe_contract(contract)

params = args[1:] if len(args) > 1 else []

if params[0] == 'describe':
return

params.reverse()

sb = ScriptBuilder()

for p in params:
print("pushitng param %s " % p)

item = parse_param(p)
sb.push(item)

print("Script.. %s " % sb.ToArray(cleanup=False))

sb.EmitAppCall(contract.Code.ScriptHash().Data)
# sb.push(binascii.hexlify(contract.Code.Script))
print("script is %s " % sb.ToArray(cleanup=False))
out = sb.ToArray()
print("out %s " % out)
test_invoke(out)
else:

print("Contract %s not found" % args[0])



def test_invoke(script):
bc = GetBlockchain()

sn = bc._db.snapshot()

accounts = DBCollection(bc._db, sn, DBPrefix.ST_Account, AccountState)
unspentcoins = DBCollection(bc._db, sn, DBPrefix.ST_Coin, UnspentCoinState)
spentcoins = DBCollection(bc._db, sn, DBPrefix.ST_SpentCoin, SpentCoinState)
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)

tx = InvocationTransaction()
tx.scripts = [ Witness()]
tx.Script = binascii.unhexlify(script)
print("script is %s " % tx.Script)
script_table = CachedScriptTable(contracts)
service = StateMachine(accounts, validators, assets, contracts, storages, None)

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

engine.LoadScript(tx.Script, False)

try:
# drum roll?
success = engine.Execute()
print("SUCCESSS!!!!!!")
if success:

service.TestCommit()

for item in engine.EvaluationStack.Items:
print("evaluation item %s " % item)

except Exception as e:
print("COULD NOT EXECUTE %s " % e)


def descripe_contract(contract):
print("invoking contract - %s" % contract.Name.decode('utf-8'))

functionCode = contract.Code

parameters = functionCode.ParameterList
script = functionCode.Script

method_signature = []
for p in parameters:
method_signature.append("{ %s } " % ToName(p))
rettype = ToName(functionCode.ReturnType)
print("method signature %s --> %s" % (' '.join(method_signature), rettype))



def parse_param(p):

try:
val = int(p)
out = BigInteger(val)
return out
except Exception as e:
pass

if type(p) is str:
return binascii.hexlify( p.encode('utf-8'))

return p
Empty file added neo/Prompt/Commands/__init__.py
Empty file.
Empty file added neo/Prompt/__init__.py
Empty file.
27 changes: 27 additions & 0 deletions neo/SmartContract/ContractParameterType.py
Expand Up @@ -15,5 +15,32 @@ class ContractParameterType(object):
Hash256 = 0x04 # 256位散列值
ByteArray = 0x05 # 字节数组
PublicKey = 0x06
String = 0x07
Array = 16
Void = 0xff



import inspect
#import sys
#import importlib
import binascii

#module = importlib.import_module('neo.SmartContract.ContractParameterType')
#items = dir(sys.modules[__name__])


def ToName(param_type):

items = inspect.getmembers(ContractParameterType)

if type(param_type) is bytes:
param_type = int.from_bytes(param_type, 'little')

for item in items:
name = item[0]
val = item[1]
if val == param_type:
return name

return None
3 changes: 2 additions & 1 deletion neo/SmartContract/StateMachine.py
Expand Up @@ -88,7 +88,8 @@ def Commit(self):
self._contracts.Commit(self._wb, False)
self._storages.Commit(self._wb, False)


def TestCommit(self):
print("test commit items....")

def Blockchain_GetAccount(self, engine):
hash = UInt160(data=engine.EvaluationStack.Pop().GetByteArray())
Expand Down
13 changes: 7 additions & 6 deletions neo/VM/ScriptBuilder.py
Expand Up @@ -11,6 +11,7 @@
from neo.VM.OpCode import *
from neo.IO.MemoryStream import MemoryStream
from neo.Cryptography.Helper import base256_encode
from neo.BigInteger import BigInteger

class ScriptBuilder(object):
"""docstring for ScriptBuilder"""
Expand All @@ -28,15 +29,15 @@ def add(self, op):
def push(self, data):
if data == None:
return
if isinstance(data,int):
if type(data) is int or type(data) is BigInteger:
if data == -1:
return self.add(PUSHM1)
elif data == 0:
return self.add(PUSH0)
elif data > 0 and data <= 16:
return self.add(int.from_bytes(PUSH1,'little') -1 + data)
else:
return self.push(base256_encode(data))
return self.push(binascii.hexlify( base256_encode(data)))
else:
buf = binascii.unhexlify(data)
if len(buf) <= int.from_bytes( PUSHBYTES75, 'big'):
Expand Down Expand Up @@ -80,11 +81,11 @@ def EmitAppCall(self, scriptHash, useTailCall=False):
return self.Emit(TAILCALL, scriptHash)
return self.Emit(APPCALL, scriptHash)

def ToArray(self):
self.ms.flush()
def ToArray(self, cleanup=True):
retval = self.ms.ToArray()
self.ms.Cleanup()
self.ms = None
if cleanup:
self.ms.Cleanup()
self.ms = None

return retval

Expand Down
18 changes: 16 additions & 2 deletions prompt.py
Expand Up @@ -21,6 +21,7 @@
from neo.Wallets.SignatureContext import SignatureContext
from neo.Wallets.KeyPair import KeyPair
from neo.Network.NodeLeader import NodeLeader
from neo.Prompt.Commands.Invoke import InvokeContract
from neo import Settings
from neo.Fixed8 import Fixed8
import traceback
Expand Down Expand Up @@ -605,6 +606,17 @@ def show_contract_state(self, args):
else:
print("please specify a contract")

def invoke_contract(self, args):
# if not self.Wallet:
# print("please open a wallet")
# return

if args and len(args) > 0:
return InvokeContract(self.Wallet, args)

print("please specify a contract to invoke")


def show_spent_coins(self, args):
item = self.get_arg(args)

Expand Down Expand Up @@ -761,12 +773,14 @@ def run(self):
self.show_tx(arguments)
elif command == 'header':
self.show_header(arguments)
elif command =='account':
elif command == 'account':
self.show_account_state(arguments)
elif command == 'asset':
self.show_asset_state(arguments)
elif command =='contract':
elif command == 'contract':
self.show_contract_state(arguments)
elif command == 'invoke':
self.invoke_contract(arguments)
elif command == 'sc':
self.show_spent_coins(arguments)
elif command == 'mem':
Expand Down

0 comments on commit 723a89e

Please sign in to comment.