Skip to content

Commit

Permalink
Show file tree
Hide file tree
Showing 61 changed files with 1,758 additions and 2,873 deletions.
3 changes: 3 additions & 0 deletions neo3/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,9 @@ class Settings(IndexableNamespace):
}
}
},
'policy': {
'max_tx_per_block': 512
},
'native_contract_activation': {}
}

Expand Down
10 changes: 6 additions & 4 deletions neo3/blockchain.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,20 +36,19 @@ def height(self):

@staticmethod
def _create_genesis_block() -> payloads.Block:
b = payloads.Block(
h = payloads.Header(
version=0,
prev_hash=types.UInt256.zero(),
timestamp=int(datetime(2016, 7, 15, 15, 8, 21, 0, timezone.utc).timestamp() * 1000),
index=0,
primary_index=0,
next_consensus=contracts.Contract.get_consensus_address(settings.standby_validators),
witness=payloads.Witness(
invocation_script=b'',
verification_script=b'\x11' # (OpCode.PUSH1)
),
consensus_data=payloads.ConsensusData(primary_index=0, nonce=2083236893),
transactions=[]
)
return b
return payloads.Block(header=h, transactions=[])

def persist(self, block: payloads.Block):
with self.backend.get_snapshotview() as snapshot:
Expand Down Expand Up @@ -77,6 +76,7 @@ def persist(self, block: payloads.Block):
cloned_snapshot.commit()
else:
cloned_snapshot = snapshot.clone()

engine = contracts.ApplicationEngine(contracts.TriggerType.POST_PERSIST,
None, snapshot, 0, True) # type: ignore
engine.load_script(vm.Script(self.native_postpersist_script))
Expand All @@ -90,6 +90,8 @@ def persist(self, block: payloads.Block):
Therefore we wait with persisting the block until here
"""
snapshot.blocks.put(block)
snapshot.best_block_height = block.index

snapshot.commit()
self._current_snapshot = snapshot
msgrouter.on_block_persisted(block)
15 changes: 13 additions & 2 deletions neo3/contracts/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from __future__ import annotations
import hashlib
import typing
from .callflags import CallFlags
from .contracttypes import (TriggerType)
from .descriptor import (ContractPermissionDescriptor)
Expand Down Expand Up @@ -30,13 +31,21 @@
NonFungibleToken,
NFTState,
NameService,
LedgerContract)
LedgerContract,
CryptoContract,
StdLibContract)


def syscall_name_to_int(name: str) -> int:
return int.from_bytes(hashlib.sha256(name.encode()).digest()[:4], 'little', signed=False)


def validate_type(obj: object, type_: typing.Type):
if type(obj) != type_:
raise ValueError(f"Expected type '{type_}' , got '{type(obj)}' instead")
return obj


__all__ = ['ContractParameterType',
'TriggerType',
'ContractMethodDescriptor',
Expand All @@ -58,4 +67,6 @@ def syscall_name_to_int(name: str) -> int:
'LedgerContract',
'NEF',
'MethodToken',
'FindOptions']
'FindOptions',
'CryptoContract',
'StdLibContract']
26 changes: 15 additions & 11 deletions neo3/contracts/abi.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import enum
from typing import List, Optional, Type, Union, cast
from enum import IntEnum
from neo3.core import types, IJson, IInteroperable, serialization
from neo3.core import types, IJson, IInteroperable, serialization, cryptography
from neo3 import contracts, vm


Expand All @@ -18,13 +18,13 @@ class ContractParameterType(IntEnum):
SIGNATURE = 0x17,
ARRAY = 0x20,
MAP = 0x22,
INTEROP_INTERFACE = 0x30,
INTEROPINTERFACE = 0x30,
VOID = 0xff

def PascalCase(self) -> str:
if self == ContractParameterType.BYTEARRAY:
return "ByteArray"
elif self == ContractParameterType.INTEROP_INTERFACE:
elif self == ContractParameterType.INTEROPINTERFACE:
return "InteropInterface"
elif self == ContractParameterType.PUBLICKEY:
return "PublicKey"
Expand All @@ -41,6 +41,8 @@ def from_type(cls, class_type: Optional[Type[object]]) -> ContractParameterType:
return ContractParameterType.INTEGER
elif class_type in [bytes, bytearray, vm.BufferStackItem, vm.ByteStringStackItem]:
return ContractParameterType.BYTEARRAY
elif class_type == cryptography.ECPoint:
return ContractParameterType.PUBLICKEY
elif hasattr(class_type, '__origin__'):
if class_type.__origin__ == list: # type: ignore
return ContractParameterType.ARRAY
Expand All @@ -64,10 +66,12 @@ def from_type(cls, class_type: Optional[Type[object]]) -> ContractParameterType:
return ContractParameterType.ARRAY
elif issubclass(class_type, IInteroperable):
return ContractParameterType.ARRAY
elif class_type == vm.StackItem:
return ContractParameterType.ANY
elif issubclass(class_type, enum.Enum):
return ContractParameterType.INTEGER
else:
return ContractParameterType.ANY
return ContractParameterType.INTEROPINTERFACE


class ContractParameterDefinition(IJson):
Expand Down Expand Up @@ -112,8 +116,8 @@ def from_json(cls, json: dict) -> ContractParameterDefinition:
ValueError: if the type is VOID.
"""
c = cls(
name=json['name'],
type=contracts.ContractParameterType[json['type'].upper()]
name=contracts.validate_type(json['name'], str),
type=contracts.ContractParameterType[contracts.validate_type(json['type'], str).upper()]
)
if c.name is None or len(c.name) == 0:
raise ValueError("Format error - invalid 'name'")
Expand Down Expand Up @@ -169,7 +173,7 @@ def from_json(cls, json: dict) -> ContractEventDescriptor:
ValueError: if the 'name' property has an incorrect format
"""
c = cls(
name=json['name'],
name=contracts.validate_type(json['name'], str),
parameters=list(map(lambda p: ContractParameterDefinition.from_json(p), json['parameters']))
)
if c.name is None or len(c.name) == 0:
Expand Down Expand Up @@ -241,11 +245,11 @@ def from_json(cls, json: dict) -> ContractMethodDescriptor:
ValueError: if the offset is negative.
"""
c = cls(
name=json['name'],
offset=json['offset'],
name=contracts.validate_type(json['name'], str),
offset=contracts.validate_type(json['offset'], int),
parameters=list(map(lambda p: contracts.ContractParameterDefinition.from_json(p), json['parameters'])),
return_type=contracts.ContractParameterType[json['returntype'].upper()],
safe=json['safe']
return_type=contracts.ContractParameterType[contracts.validate_type(json['returntype'], str).upper()],
safe=contracts.validate_type(json['safe'], bool)
)
if c.name is None or len(c.name) == 0:
raise ValueError("Format error - invalid 'name'")
Expand Down
Loading

0 comments on commit 8b18e30

Please sign in to comment.