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

Commit

Permalink
refactor neo.SmartContract.Framework package into the boa.blockchain.…
Browse files Browse the repository at this point in the history
…vm package. updated test files. adding support for Storage and block api
  • Loading branch information
localhuman committed Sep 25, 2017
1 parent 4a18bc6 commit 2917b2f
Show file tree
Hide file tree
Showing 63 changed files with 533 additions and 488 deletions.
File renamed without changes.
5 changes: 5 additions & 0 deletions boa/blockchain/vm/FunctionCode.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
from boa.blockchain.vm.SmartContract import SmartContract

class FunctionCode(SmartContract):

pass
3 changes: 3 additions & 0 deletions boa/blockchain/vm/Neo/Account.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@

class Account():
pass
3 changes: 3 additions & 0 deletions boa/blockchain/vm/Neo/Asset.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@

class Asset():
pass
3 changes: 3 additions & 0 deletions boa/blockchain/vm/Neo/Block.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@

class Block():
pass
36 changes: 36 additions & 0 deletions boa/blockchain/vm/Neo/Blockchain.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
from boa.blockchain.vm.Neo.Header import Header
from boa.blockchain.vm.Neo.Block import Block
from boa.blockchain.vm.Neo.Transaction import Transaction
from boa.blockchain.vm.Neo.Account import Account
from boa.blockchain.vm.Neo.Asset import Asset
from boa.blockchain.vm.Neo.Contract import Contract



def GetHeight() -> int:
pass

def GetHeader(height_or_hash) -> Header:
pass

def GetBlock(height_or_hash) -> Block:
pass


def GetTransaction(hash) -> Transaction:
pass

def GetAccount(script_hash) -> Account:
pass


def GetValidators() -> []:
pass


def GetAsset(asset_id) -> Asset:
pass


def GetContract(script_hash) -> Contract:
pass
3 changes: 3 additions & 0 deletions boa/blockchain/vm/Neo/Contract.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@

class Contract():
pass
15 changes: 15 additions & 0 deletions boa/blockchain/vm/Neo/Header.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@


class Header():
pass


def GetHash():
pass

def GetVersion():
pass

def GetPrevHash():
pass

3 changes: 3 additions & 0 deletions boa/blockchain/vm/Neo/Transaction.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@

class Transaction():
pass
18 changes: 18 additions & 0 deletions boa/blockchain/vm/SmartContract.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@

class SmartContract():


def Sha1(data):
pass

def Sha256(data):
pass

def Hash160(data):
pass

def Hash256(data):
pass

def VerifySignature(pubkey, signature):
pass
157 changes: 157 additions & 0 deletions boa/blockchain/vm/VMOp.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
# Constants
PUSH0 = b'\x00' # An empty array of bytes is pushed onto the stack.
PUSHF = PUSH0
PUSHBYTES1 = b'\x01' # b'\x01-b'\x4B The next opcode bytes is data to be pushed onto the stack
PUSHBYTES75 = b'\x4B'
PUSHDATA1 = b'\x4C' # The next byte contains the number of bytes to be pushed onto the stack.
PUSHDATA2 = b'\x4D' # The next two bytes contain the number of bytes to be pushed onto the stack.
PUSHDATA4 = b'\x4E' # The next four bytes contain the number of bytes to be pushed onto the stack.
PUSHM1 = b'\x4F' # The number -1 is pushed onto the stack.
PUSH1 = b'\x51' # The number 1 is pushed onto the stack.
PUSHT = PUSH1
PUSH2 = b'\x52' # The number 2 is pushed onto the stack.
PUSH3 = b'\x53' # The number 3 is pushed onto the stack.
PUSH4 = b'\x54' # The number 4 is pushed onto the stack.
PUSH5 = b'\x55' # The number 5 is pushed onto the stack.
PUSH6 = b'\x56' # The number 6 is pushed onto the stack.
PUSH7 = b'\x57' # The number 7 is pushed onto the stack.
PUSH8 = b'\x58' # The number 8 is pushed onto the stack.
PUSH9 = b'\x59' # The number 9 is pushed onto the stack.
PUSH10 = b'\x5A' # The number 10 is pushed onto the stack.
PUSH11 = b'\x5B' # The number 11 is pushed onto the stack.
PUSH12 = b'\x5C' # The number 12 is pushed onto the stack.
PUSH13 = b'\x5D' # The number 13 is pushed onto the stack.
PUSH14 = b'\x5E' # The number 14 is pushed onto the stack.
PUSH15 = b'\x5F' # The number 15 is pushed onto the stack.
PUSH16 = b'\x60' # The number 16 is pushed onto the stack.


# Flow control
NOP = b'\x61' # Does nothing.
JMP = b'\x62'
JMPIF = b'\x63'
JMPIFNOT = b'\x64'
CALL = b'\x65'
RET = b'\x66'
APPCALL = b'\x67'
SYSCALL = b'\x68'
TAILCALL = b'\x69'


# Stack
DUPFROMALTSTACK = b'\x6A'
TOALTSTACK = b'\x6B' # Puts the input onto the top of the alt stack. Removes it from the main stack.
FROMALTSTACK = b'\x6C' # Puts the input onto the top of the main stack. Removes it from the alt stack.
XDROP = b'\x6D'
XSWAP = b'\x72'
XTUCK = b'\x73'
DEPTH = b'\x74' # Puts the number of stack items onto the stack.
DROP = b'\x75' # Removes the top stack item.
DUP = b'\x76' # Duplicates the top stack item.
NIP = b'\x77' # Removes the second-to-top stack item.
OVER = b'\x78' # Copies the second-to-top stack item to the top.
PICK = b'\x79' # The item n back in the stack is copied to the top.
ROLL = b'\x7A' # The item n back in the stack is moved to the top.
ROT = b'\x7B' # The top three items on the stack are rotated to the left.
SWAP = b'\x7C' # The top two items on the stack are swapped.
TUCK = b'\x7D' # The item at the top of the stack is copied and inserted before the second-to-top item.


# Splice
CAT = b'\x7E' # Concatenates two strings.
SUBSTR = b'\x7F' # Returns a section of a string.
LEFT = b'\x80' # Keeps only characters left of the specified point in a string.
RIGHT = b'\x81' # Keeps only characters right of the specified point in a string.
SIZE = b'\x82' # Returns the length of the input string.


# Bitwise logic
INVERT = b'\x83' # Flips all of the bits in the input.
AND = b'\x84' # Boolean and between each bit in the inputs.
OR = b'\x85' # Boolean or between each bit in the inputs.
XOR = b'\x86' # Boolean exclusive or between each bit in the inputs.
EQUAL = b'\x87' # Returns 1 if the inputs are exactly equal' 0 otherwise.
# OP_EQUALVERIFY = b'\x88' # Same as OP_EQUAL' but runs OP_VERIFY afterward.
# OP_RESERVED1 = b'\x89' # Transaction is invalid unless occuring in an unexecuted OP_IF branch
# OP_RESERVED2 = b'\x8A' # Transaction is invalid unless occuring in an unexecuted OP_IF branch

# Arithmetic
# Note: Arithmetic inputs are limited to signed 32-bit integers' but may overflow their output.
INC = b'\x8B' # 1 is added to the input.
DEC = b'\x8C' # 1 is subtracted from the input.
SIGN = b'\x8D'
NEGATE = b'\x8F' # The sign of the input is flipped.
ABS = b'\x90' # The input is made positive.
NOT = b'\x91' # If the input is 0 or 1' it is flipped. Otherwise the output will be 0.
NZ = b'\x92' # Returns 0 if the input is 0. 1 otherwise.
ADD = b'\x93' # a is added to b.
SUB = b'\x94' # b is subtracted from a.
MUL = b'\x95' # a is multiplied by b.
DIV = b'\x96' # a is divided by b.
MOD = b'\x97' # Returns the remainder after dividing a by b.
SHL = b'\x98' # Shifts a left b bits' preserving sign.
SHR = b'\x99' # Shifts a right b bits' preserving sign.
BOOLAND = b'\x9A' # If both a and b are not 0' the output is 1. Otherwise 0.
BOOLOR = b'\x9B' # If a or b is not 0' the output is 1. Otherwise 0.
NUMEQUAL = b'\x9C' # Returns 1 if the numbers are equal' 0 otherwise.
NUMNOTEQUAL = b'\x9E' # Returns 1 if the numbers are not equal' 0 otherwise.
LT = b'\x9F' # Returns 1 if a is less than b' 0 otherwise.
GT = b'\xA0' # Returns 1 if a is greater than b' 0 otherwise.
LTE = b'\xA1' # Returns 1 if a is less than or equal to b' 0 otherwise.
GTE = b'\xA2' # Returns 1 if a is greater than or equal to b' 0 otherwise.
MIN = b'\xA3' # Returns the smaller of a and b.
MAX = b'\xA4' # Returns the larger of a and b.
WITHIN = b'\xA5' # Returns 1 if x is within the specified range (left-inclusive)' 0 otherwise.

# Crypto
# RIPEMD160 = b'\xA6' # The input is hashed using RIPEMD-160.
SHA1 = b'\xA7' # The input is hashed using SHA-1.
SHA256 = b'\xA8' # The input is hashed using SHA-256.
HASH160 = b'\xA9'
HASH256 = b'\xAA'
CHECKSIG = b'\xAC'
CHECKMULTISIG = b'\xAE'


# Array
ARRAYSIZE = b'\xC0'
PACK = b'\xC1'
UNPACK = b'\xC2'
PICKITEM = b'\xC3'
SETITEM = b'\xC4'
NEWARRAY = b'\xC5' # 用作引用類型
NEWSTRUCT = b'\xC6' # 用作值類型


import sys
import importlib
import binascii

module = importlib.import_module('neo.VM.OpCode')
items = dir(sys.modules[__name__])


def ToName(op):

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

for item in items:
n = getattr(module, item)

try:
nn = int(binascii.hexlify(n))

if op == nn:
return item
except Exception as e:
pass

try:
nn2 = int.from_bytes(n, 'little')
if op == nn2:
return item
except Exception as e:
pass

return None
Empty file added boa/blockchain/vm/__init__.py
Empty file.
1 change: 0 additions & 1 deletion boa/boa.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import os
import binascii
from boa.code.module import Module

from neo.IO.MemoryStream import StreamManager
Expand Down
11 changes: 9 additions & 2 deletions boa/code/items.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
from boa.code.method import Method
from boa.code import pyop
import importlib
import pdb

class Item():
items = None
Expand All @@ -20,12 +19,16 @@ class Definition(Item):

class Import(Item):

NEO_SC_FRAMEWORK = 'neo.SmartContract.Framework.'

module_path = None
module_name = None


imported_module = None

is_system_module = None

def __init__(self, item_list):
super(Import, self).__init__(item_list)

Expand All @@ -36,6 +39,8 @@ def __init__(self, item_list):
elif op == pyop.STORE_NAME:
self.module_name = arg

self.is_system_module = False

self.build()

def build(self):
Expand All @@ -47,8 +52,10 @@ def build(self):

filename = module.__file__

self.imported_module = Module(filename, module_name=self.module_path)
if self.NEO_SC_FRAMEWORK in self.module_path:
self.is_system_module = True

self.imported_module = Module(filename, module_name=self.module_path, is_sys_module=self.is_system_module)

def is_valid(self):

Expand Down
4 changes: 2 additions & 2 deletions boa/code/method.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from byteplay3 import SetLinenoType,Opcode,Label,Code
from byteplay3 import SetLinenoType,Label

from boa.code.token import PyToken,VMToken,VMTokenizer
from boa.code.token import PyToken,VMTokenizer
from boa.code.block import Block
from boa.code import pyop

Expand Down
21 changes: 14 additions & 7 deletions boa/code/module.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@
from boa.code.method import Method
from boa.code.items import Definition, Klass, Import

from neo.VM import OpCode

from boa.blockchain.vm import VMOp

from collections import OrderedDict

Expand All @@ -27,6 +26,7 @@ class Module():

methods = None # a list to keep all methods in the module

is_sys_module = None

all_vm_tokens = None # dict for converting method tokens into linked method tokens for writing

Expand Down Expand Up @@ -71,12 +71,14 @@ def method_by_name(self, method_name):
return m
return None

def __init__(self, path, module_name=''):
def __init__(self, path, module_name='', is_sys_module=False):

self.path = path

self._module_name = module_name

self.is_sys_module = is_sys_module

source = open(path, 'rb')

suite = compile(source.read(), path, 'exec')
Expand All @@ -101,8 +103,13 @@ def build(self):
for lineset in self.lines:

if lineset.is_import:
imp = Import(lineset.items)
self.process_import(imp)

if not self.is_sys_module:
imp = Import(lineset.items)
self.process_import(imp)
else:
print("will not import items from sys module")

elif lineset.is_definition:
self.module_variables.append(Definition(lineset.items))
elif lineset.is_class:
Expand All @@ -115,6 +122,7 @@ def build(self):


def process_import(self, import_item):

self.imports.append(import_item)

self.loaded_modules.append(import_item.imported_module)
Expand Down Expand Up @@ -176,7 +184,7 @@ def write_methods(self):

b_array.append(vm_token.out_op)

if vm_token.data is not None and vm_token.vm_op != OpCode.NOP:
if vm_token.data is not None and vm_token.vm_op != VMOp.NOP:
b_array = b_array + vm_token.data

return b_array
Expand Down Expand Up @@ -216,4 +224,3 @@ def link_methods(self):
jump_len = target_method.method_address - vmtoken.addr

vmtoken.data = jump_len.to_bytes(2, 'little', signed=True)

0 comments on commit 2917b2f

Please sign in to comment.