CityOfZion / neo-python

Python Node and SDK for the NEO 2.x blockchain. For NEO 3.x go to our successor project neo-mamba
https://neo-python.readthedocs.io/en/latest/
MIT License
313 stars 189 forks source link

Create (raw) Transaction builder class #886

Open ixje opened 5 years ago

ixje commented 5 years ago

This is a TODO for a project (see side bar)

As part of the Lightweight SDK API we would like to have a class that eases creation of (raw) transactions. A raw transaction can be understood as a serialised Transaction that can be send to the network via a RPC node or directly on the TCP network.

The available Transactions and their possible attributes are described in the documentation. There are 2 existing examples on how to manually build raw transactions in python here. From that code you can see there is enough room to simplify this for the end user. e.g. adding a description attribute to the transaction is currently done as follows

 contract_tx.Attributes.append(TransactionAttribute(usage=TransactionAttributeUsage.Description, data="My raw contract transaction description"))

a simplified interface could be

contract_tx.addDescription("My raw contract transaction description")

Some ideas:

For the first iteration we should only support the following transactions

jseagrave21 commented 5 years ago

@ixje Could you take a look at https://github.com/jseagrave21/neo-python/blob/raw-transaction-class/neo/Core/TX/RawTransaction.py and let me know what you think? You can see from the commit description that I haven't included any coverage but I wanted to get your initial reaction before I kept working. If you like what you see, I have not figured out how you would like to implement support for InvocationTransactions. My idea (as you can see here), is to implement a buildTokenTransfer function, but I am not sure what else should be created. Most of the rest of the issue's wickets have been met, including validation (both in real time and via the Verify function).

ixje commented 5 years ago

At first glance looks good. I can't say if the function names might need to be renamed later on though to be inline with the rest of the exposed lightweight API. I had intentionally put #885 above this issue on the project board because I expected to learn from there the API's and naming style we want to support (I don't have the full picture as this point either).

Some random things I noticed in your current code:

jseagrave21 commented 5 years ago

@ixje Thank you for the quick feedback. I will keep working on this and hopefully I will be able to merge it with the exposed lightweight API when it is ready.

jseagrave21 commented 5 years ago

@ixje I made the corrections per your feedback and have now verified Contract and Claim Functionality. Please see the description for commit https://github.com/CityOfZion/neo-python/commit/db1c1e726b8b6a8e248aea9b8f20bb6f807e26ff

jseagrave21 commented 5 years ago

Token Transfers are now supported. See ac929933558aae5cdc0fc00f73d932bbca004c3f

jseagrave21 commented 5 years ago

Importing raw transaction is now supported. See 4d78a5f7ccac9493099919224c5c2062a34689d4

@ixje I think all of the original objectives for this issue have been met. Please review and let me know what you think. In the meantime, I can work on providing test coverage (I have manually tested every feature at this point).

ixje commented 5 years ago

Some things I believe we should do at minimum

Other things that we have to keep in mind until the other objective is realised: (note: don't implement that now, the other objective should give a clear idea how to structure this)

  1. We might want to not inherit from Transaction but just from object and turn the class into a real builder class. It now suggests to be a real NEO transaction type, which it is not. It would also allow re-use in the existing code where we can test on TX's being an instanceof ClaimTransaction etc. The TXType() could be dropped and made part of the constructor. It could then also support building multiple transactions in 1 single block E.g. 1 raw TX that sends multiple assets and claims gas and <insert action>
  2. We have to assess if the current exception classes are sufficient. I see you've expanded them, but I can't judge if the granularity is low enough.
lock9 commented 5 years ago

Hello,

I agree with @ixje, specially about this:

  • support use of custom neoscan servers (now it's all forced to api.neoscan.io). This should be configurable such that people can point it to their own instances (e.g. neolocal instance). Try to use a variable for the URL and create constants for the API endpoint locations. That way if we ever need to update an endpoint (e.g. /v1/get_balance/) we don't have to search and find all locations in the code.

I think almost everyone should develop using their own private network, so I think this feature is absolutely important.

Also:

I'm still having trouble when I use it in a loop statement, @jseagrave21 please contact me in slack! It's probably my fault, but I could use some help to find out what is going on.

jseagrave21 commented 5 years ago

@ixje offline multi-sig is now fully supported and most feedback was implemented in ceb091821b0c07dec743c0e01a0eb73b68b8ac12. With @lock9's help, SourceAddress was split into Address and Network and the testnet is now the default network if Network is not implemented (see 54e4d730fa9db36026bb57a8d283cbc151bf1217). At this point, I think most recommendations have been adjudicated. Please let me know if you have any more feedback.

ixje commented 5 years ago

I think that all we can address now is there 👍. I'm not so sure about Address as name, but I would have to use the script in a couple of scenario's first. Just leave it as is for now; we need to deal with https://github.com/CityOfZion/neo-python/issues/885 first before we can streamline naming. I'll copy the other outstanding "things to think about" below.

Other things that we have to keep in mind until the other objective is realised: (note: don't implement that now, the other objective should give a clear idea how to structure this)

  1. We might want to not inherit from Transaction but just from object and turn the class into a real builder class. It now suggests to be a real NEO transaction type, which it is not. It would also allow re-use in the existing code where we can test on TX's being an instanceof ClaimTransaction etc. The TXType() could be dropped and made part of the constructor. It could then also support building multiple transactions in 1 single block E.g. 1 raw TX that sends multiple assets and claims gas and
  2. We have to assess if the current exception classes are sufficient. I see you've expanded them, but I can't judge if the granularity is low enough.