Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merge neo-python development into jseagrave21 GET-Requests #71

Merged
merged 7 commits into from
Nov 19, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,16 @@ All notable changes to this project are documented in this file.
- Move some warnings and 'expected' errors to `DEBUG` level to avoid logging to console by default
- Empty VerificationScripts for deployed contracts now work as intended
- Fix RPC's ``getaccountstate`` response schema to match ``neo-cli`` `#714 </~https://github.com/CityOfZion/neo-python/issues/714>`
- Add fix to ensure tx is saved to wallet when sent using RPC
- Add bad peers to the ``getpeers`` RPC method `#715 </~https://github.com/CityOfZion/neo-python/pull/715>`
- Introduce Django inspired component loading for REST and RPC server
- Allow a raw tx to be build without an active blockchain db in the environment
- Fix unnecessary default bootstrap warning for mainnet showing.


[0.8.2] 2018-10-31
-------------------
- Improve Tokens.py and ``token_send``, increase test coverage
- Fix max recursion depth exceeding when network data inflow exceeds processing speed
- Add log output control via the new ``config output_level`` command. The old ``config debug`` command is removed.
- Update Readme and Prompt.py ``help``
Expand Down
12 changes: 11 additions & 1 deletion examples/build_raw_transactions.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,9 @@ def example1():
# The constructor already sets the correct `Type` and `Version` fields, so we do not have to worry about that
contract_tx = ContractTransaction()

# the ContractTransaction type has no special data, so we do not have to do anything there
# Since we are building a raw transaction, we will add the raw_tx flag

contract_tx.raw_tx = True

# Next we can add Attributes if we want. Again the various types are described in point 4. of the main link above
# We will add a simple "description"
Expand Down Expand Up @@ -114,6 +116,8 @@ def example1():

raw_tx = contract_tx.ToArray()

return raw_tx

# you can confirm that this transaction is correct by running it against our docker testnet image using the following instructions
# docker pull cityofzion/neo-python-privnet-unittest:v0.0.1
# docker run --rm -d --name neo-python-privnet-unittest -p 20333-20336:20333-20336/tcp -p 30333-30336:30333-30336/tcp cityofzion/neo-python-privnet-unittest:v0.0.1
Expand Down Expand Up @@ -159,6 +163,10 @@ def example2():
# the inputs, outputs and Type do not have to be set anymore.
invocation_tx = InvocationTransaction()

# Since we are building a raw transaction, we will add the raw_tx flag

invocation_tx.raw_tx = True

# often times smart contract developers use the function ``CheckWitness`` to determine if the transaction is signed by somebody eligible of calling a certain method
# in order to pass that check you want to add the corresponding script_hash as a transaction attribute (this is generally the script_hash of the public key you use for signing)
# Note that for public functions like the NEP-5 'getBalance' and alike this would not be needed, but it doesn't hurt either
Expand Down Expand Up @@ -193,6 +201,8 @@ def example2():
invocation_tx.scripts = context.GetScripts()
raw_tx = invocation_tx.ToArray()

return raw_tx

# you can confirm that this transaction is correct by running it against our docker testnet image using the following instructions
# docker pull cityofzion/neo-python-privnet-unittest:v0.0.1
# docker run --rm -d --name neo-python-privnet-unittest -p 20333-20336:20333-20336/tcp -p 30333-30336:30333-30336/tcp cityofzion/neo-python-privnet-unittest:v0.0.1
Expand Down
22 changes: 22 additions & 0 deletions examples/test_build_raw_transactions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import os
from unittest import TestCase
from examples.build_raw_transactions import example1, example2


class BuildRawTransactionsTestCase(TestCase):

def test_example1(self):
res = example1()

self.assertTrue(res)
self.assertEqual(res.decode('utf-8'), "80000190274d792072617720636f6e7472616374207472616e73616374696f6e206465736372697074696f6e01949354ea0a8b57dfee1e257a1aedd1e0eea2e5837de145e8da9c0f101bfccc8e0100029b7cffdaa674beae0f930ebe6085af9093e5fe56b34a5c220ccdcf6efc336fc500a3e11100000000ea610aa6db39bd8c8556c9569d94b5e5a5d0ad199b7cffdaa674beae0f930ebe6085af9093e5fe56b34a5c220ccdcf6efc336fc5004f2418010000001cc9c05cefffe6cdd7b182816a9152ec218d2ec000")

os.remove("path")

def test_example2(self):
res = example2()

self.assertTrue(res)
self.assertEqual(res.decode('utf-8'), "d1001b00046e616d6567d3d8602814a429a91afdbaa3914884a1c90c73310290274d792072617720636f6e7472616374207472616e73616374696f6e206465736372697074696f6e201cc9c05cefffe6cdd7b182816a9152ec218d2ec000000141405bd8ba993473b51bfa338dd3f2d4a236b4e940572cf6f077c411cd3a5fa8ccce09d945159a3978e7697915620473da0e2189048d768ed2a70535a73a9cba3a33232103cbb45da6072c14761c9da545749d9cfd863f860c351066d16df480602a2024c6ac")

os.remove("path")
21 changes: 21 additions & 0 deletions neo/Core/Helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@
from neo.Implementations.Blockchains.LevelDB.DBCollection import DBCollection
from neo.Implementations.Blockchains.LevelDB.DBPrefix import DBPrefix
from neo.Core.State.ContractState import ContractState
from neo.Core.State.AssetState import AssetState
from neocore.Cryptography.Crypto import Crypto
from neocore.IO.BinaryWriter import BinaryWriter
from neocore.UInt160 import UInt160
from neocore.UInt256 import UInt256
from neo.IO.MemoryStream import StreamManager
from neo.VM.ScriptBuilder import ScriptBuilder
from neo.SmartContract.ApplicationEngine import ApplicationEngine
Expand Down Expand Up @@ -226,3 +228,22 @@ def IToBA(value):
def EmitServiceEvents(state_reader):
for event in state_reader.events_to_dispatch:
events.emit(event.event_type, event)

@staticmethod
def StaticAssetState(assetId):
neo = AssetState()
neo.AssetId = UInt256.ParseString("0xc56f33fc6ecfcd0c225c4ab356fee59390af8560be0e930faebe74a6daff7c9b")
neo.AssetType = 0x00

gas = AssetState()
gas.AssetId = UInt256.ParseString("0x602c79718b16e442de58778e148d0b1084e3b2dffd5de6b7b16cee7969282de7")
gas.AssetType = 0x01

if assetId == neo.AssetId:
return neo

elif assetId == gas.AssetId:
return gas

else:
return None
7 changes: 6 additions & 1 deletion neo/Core/TX/Transaction.py
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,8 @@ class Transaction(InventoryMixin):

withdraw_hold = None

raw_tx = False

"""docstring for Transaction"""

def __init__(self, inputs=[], outputs=[], attributes=[], scripts=[]):
Expand Down Expand Up @@ -716,7 +718,10 @@ def GetScriptHashesForVerifying(self):
hashes.add(UInt160(data=attr.Data))

for key, group in groupby(self.outputs, lambda p: p.AssetId):
asset = GetBlockchain().GetAssetState(key.ToBytes())
if self.raw_tx:
asset = Helper.StaticAssetState(key)
else:
asset = GetBlockchain().GetAssetState(key.ToBytes())
if asset is None:
raise Exception("Invalid operation")

Expand Down
70 changes: 70 additions & 0 deletions neo/Core/TX/test_transactions.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
from neo.Utils.NeoTestCase import NeoTestCase
from neo.Core.Helper import Helper
from neo.Core.TX.MinerTransaction import MinerTransaction
from neo.Core.TX.Transaction import Transaction, TransactionType
from neo.Core.State.AssetState import AssetState
from neocore.IO.BinaryWriter import BinaryWriter
from neocore.IO.BinaryReader import BinaryReader
from neocore.Fixed8 import Fixed8
from neo.IO.MemoryStream import MemoryStream, StreamManager
import binascii
import os
from neo.Settings import settings
from mock import patch


class TransactionTestCase(NeoTestCase):
Expand Down Expand Up @@ -203,3 +206,70 @@ def test_tx_big_remark(self):
tx = Transaction.DeserializeFrom(reader)

self.assertEqual(tx.Hash.ToString(), self.giant_tx_hash)

rtx = b'800002900e5468697320697320612074657374900e546869732069732061207465737400019b7cffdaa674beae0f930ebe6085af9093e5fe56b34a5c220ccdcf6efc326fc500a3e111000000001cc9c05cefffe6cdd7b182816a9152ec218d2ec000'

def test_GetScriptHashesForVerifying_invalid_operation(self):
# test a normal tx with a bad assetId
ms = MemoryStream(binascii.unhexlify(self.rtx))
reader = BinaryReader(ms)
tx = Transaction.DeserializeFrom(reader)

with self.assertRaises(Exception) as e:
tx.GetScriptHashesForVerifying()

self.assertTrue("Invalid operation" in str(e.exception))

# test a raw tx with a bad assetId
ms = MemoryStream(binascii.unhexlify(self.rtx))
reader = BinaryReader(ms)
tx = Transaction.DeserializeFrom(reader)
tx.raw_tx = True

with self.assertRaises(Exception) as e:
tx.GetScriptHashesForVerifying()

self.assertTrue("Invalid operation" in str(e.exception))

drtx = b'800001900e546869732069732061207465737400019b7cffdaa674beae0f930ebe6085af9093e5fe56b34a5c220ccdcf6efc336fc500a3e111000000001cc9c05cefffe6cdd7b182816a9152ec218d2ec000'

def test_GetScriptHashesForVerifying_DutyFlag(self):
# test a raw tx
ms = MemoryStream(binascii.unhexlify(self.rtx))
reader = BinaryReader(ms)
tx = Transaction.DeserializeFrom(reader)
tx.raw_tx = True

# create the mocked asset
mock_asset = AssetState()
mock_asset.AssetType = 0x80

with patch("neo.Core.TX.Transaction.Helper.StaticAssetState", return_value=mock_asset):
res = tx.GetScriptHashesForVerifying()

self.assertTrue(type(res), list)
self.assertEqual(res[0], Helper.AddrStrToScriptHash("AJQ6FoaSXDFzA6wLnyZ1nFN7SGSN2oNTc3"))

ntx = b'80000190274d792072617720636f6e7472616374207472616e73616374696f6e206465736372697074696f6e01949354ea0a8b57dfee1e257a1aedd1e0eea2e5837de145e8da9c0f101bfccc8e0100029b7cffdaa674beae0f930ebe6085af9093e5fe56b34a5c220ccdcf6efc336fc500a3e11100000000ea610aa6db39bd8c8556c9569d94b5e5a5d0ad199b7cffdaa674beae0f930ebe6085af9093e5fe56b34a5c220ccdcf6efc336fc5004f2418010000001cc9c05cefffe6cdd7b182816a9152ec218d2ec000'
gtx = b'80000190274d792072617720636f6e7472616374207472616e73616374696f6e206465736372697074696f6e01949354ea0a8b57dfee1e257a1aedd1e0eea2e5837de145e8da9c0f101bfccc8e010002e72d286979ee6cb1b7e65dfddfb2e384100b8d148e7758de42e4168b71792c6000a3e11100000000ea610aa6db39bd8c8556c9569d94b5e5a5d0ad19e72d286979ee6cb1b7e65dfddfb2e384100b8d148e7758de42e4168b71792c60e05c9041000000001cc9c05cefffe6cdd7b182816a9152ec218d2ec000'

def test_GetScriptHashesForVerifying_neo_gas(self):
# test a raw tx using neo
ms = MemoryStream(binascii.unhexlify(self.ntx))
reader = BinaryReader(ms)
tx = Transaction.DeserializeFrom(reader)
tx.raw_tx = True

res = tx.GetScriptHashesForVerifying()

self.assertTrue(type(res), list)

# test a raw tx using gas
ms = MemoryStream(binascii.unhexlify(self.gtx))
reader = BinaryReader(ms)
tx = Transaction.DeserializeFrom(reader)
tx.raw_tx = True

res = tx.GetScriptHashesForVerifying()

self.assertTrue(type(res), list)
Loading