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

Commit

Permalink
adding ability to import NEP5 token contract
Browse files Browse the repository at this point in the history
  • Loading branch information
localhuman committed Nov 3, 2017
1 parent f1b2495 commit dff1a4f
Show file tree
Hide file tree
Showing 8 changed files with 134 additions and 14 deletions.
9 changes: 8 additions & 1 deletion neo/Implementations/Wallets/peewee/Models.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,17 @@ class Contract(ModelBase):

class Key(ModelBase):
Id = PrimaryKeyField()
Name = CharField(unique=True, )
Name = CharField(unique=True)
Value = CharField()


class NEP5Token(ModelBase):
ContractHash = CharField(unique=True)
Name = CharField()
Symbol = CharField()
Decimals = IntegerField()


class Transaction(ModelBase):
Id = PrimaryKeyField()
Hash = CharField(unique=True)
Expand Down
42 changes: 36 additions & 6 deletions neo/Implementations/Wallets/peewee/UserWallet.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,28 +3,27 @@
from neo.Wallets.Wallet import Wallet
from neo.Wallets.Coin import Coin as WalletCoin
from neo.SmartContract.Contract import Contract as WalletContract
from neo.Wallets.KeyPair import KeyPair as WalletKeyPair
from neo.IO.Helper import Helper
from neo.Core.Blockchain import Blockchain
from neo.Core.CoinReference import CoinReference
from neo.Core.TX.Transaction import TransactionOutput
from neo.Core.TX.Transaction import Transaction as CoreTransaction

from neo.Wallets.KeyPair import KeyPair as WalletKeyPair
from neo.Wallets.NEP5Token import NEP5Token as WalletNEP5Token
from Crypto import Random
from neo.Cryptography.Crypto import Crypto
import os
from neo.UInt160 import UInt160
import binascii
import pdb
from neo.Fixed8 import Fixed8
from neo.UInt160 import UInt160
from neo.UInt256 import UInt256

from .PWDatabase import PWDatabase

from neo.Implementations.Wallets.peewee.Models import Account, Address, Coin, Contract, Key, Transaction, \
TransactionInfo
from neo.Implementations.Wallets.peewee.Models import Account, Address, Coin, \
Contract, Key, Transaction, \
TransactionInfo, NEP5Token

from autologging import logged
import json
Expand All @@ -49,7 +48,7 @@ def BuildDatabase(self):
PWDatabase.Initialize(self._path)
db = PWDatabase.ContextDB()
try:
db.create_tables([Account, Address, Coin, Contract, Key, Transaction, TransactionInfo, ], safe=True)
db.create_tables([Account, Address, Coin, Contract, Key, NEP5Token, Transaction, TransactionInfo, ], safe=True)
except Exception as e:
print("Couldnt build database %s " % e)
self.__log.debug("couldnt build database %s " % e)
Expand Down Expand Up @@ -163,6 +162,27 @@ def AddWatchOnly(self, script_hash):
else:
raise Exception("Address already exists in wallet")


def AddNEP5Token(self,token):

super(UserWallet, self).AddNEP5Token(token)

try:
db_token = NEP5Token.get(ContractHash=token.ScriptHash.ToBytes())
db_token.delete_instance()
except Exception as e:
pass

db_token = NEP5Token.create(
ContractHash = token.ScriptHash.ToBytes(),
Name = token.name,
Symbol = token.symbol,
Decimals = token.decimals
)
db_token.save()
return True


def FindUnspentCoins(self, from_addr=None, use_standard=False, watch_only_val=0):
return super(UserWallet, self).FindUnspentCoins(from_addr, use_standard, watch_only_val=watch_only_val)

Expand Down Expand Up @@ -231,6 +251,16 @@ def LoadKeyPairs(self):

return keypairs

def LoadNEP5Tokens(self):
tokens = {}

for db_token in NEP5Token.select():
token = WalletNEP5Token.FromDBInstance(db_token)
print("token %s " % json.dumps(token.ToJson(), indent=4))
tokens[token.ScriptHash.ToBytes()] = token

return tokens

def LoadStoredData(self, key):
self.__log.debug("Looking for key %s " % key)
try:
Expand Down
2 changes: 1 addition & 1 deletion neo/Prompt/Commands/Invoke.py
Original file line number Diff line number Diff line change
Expand Up @@ -140,11 +140,11 @@ def TestInvokeContract(wallet, args, withdrawal_tx=None, parse_params=True):
contract = BC.GetContract(args[0])

if contract:
descripe_contract(contract)

verbose = False

if 'verbose' in args:
descripe_contract(contract)
verbose = True
args.remove('verbose')

Expand Down
35 changes: 32 additions & 3 deletions neo/Prompt/Commands/Wallet.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@

from neo.Core.Blockchain import Blockchain
from neo.Wallets.NEP5Token import NEP5Token
import binascii
import json

def DeleteAddress(prompter, wallet, addr):

Expand All @@ -21,8 +24,34 @@ def ImportWatchAddr(wallet, addr):

script_hash = wallet.ToScriptHash(addr)

print("will import watch address %s %s " % (addr, script_hash))

result = wallet.AddWatchOnly(script_hash)

print("result %s " % result)


def ImportToken(wallet, contract_hash):

if wallet is None:
print("please open a wallet")
return False

contract = Blockchain.Default().GetContract(contract_hash)

if contract:
hex_script = binascii.hexlify(contract.Code.Script)
token = NEP5Token(script= hex_script)

result = token.Query(wallet)

if result:

print("queried token %s " % json.dumps(token.ToJson(), indent=4))

wallet.AddNEP5Token(token)

else:

print("Could not import token")



40 changes: 40 additions & 0 deletions neo/SmartContract/ApplicationEngine.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@
import os
from autologging import logged

# used for ApplicationEngine.Run
from neo.Implementations.Blockchains.LevelDB.DBPrefix import DBPrefix
from neo.Implementations.Blockchains.LevelDB.DBCollection import DBCollection
from neo.Implementations.Blockchains.LevelDB.CachedScriptTable import CachedScriptTable
from neo.Core.State import ContractState,AssetState,AccountState,ValidatorState,StorageItem
from neo.SmartContract import TriggerType

@logged
class ApplicationEngine(ExecutionEngine):
Expand Down Expand Up @@ -291,3 +297,37 @@ def GetPriceForSysCall(self):
return 100

return 1



@staticmethod
def Run(script, container=None):

from neo.Core.Blockchain import Blockchain
from neo.SmartContract.StateMachine import StateMachine

bc = Blockchain.Default()

sn = bc._db.snapshot()

accounts = DBCollection(bc._db, sn, DBPrefix.ST_Account, AccountState)
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)

script_table = CachedScriptTable(contracts)
service = StateMachine(accounts, validators, assets, contracts, storages, None)

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

engine.LoadScript(script, False)
engine.Execute()
return engine
13 changes: 12 additions & 1 deletion neo/Wallets/Wallet.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ class Wallet(object):
_master_key = None
_keys = {} # holds keypairs
_contracts = {} # holds Contracts

_tokens = {} # holds references to NEP5 tokens
_watch_only = [] # holds set of hashes
_coins = {} # holds Coin References

Expand Down Expand Up @@ -110,6 +110,7 @@ def __init__(self, path, passwordKey, create):
self._keys = self.LoadKeyPairs()
self._contracts = self.LoadContracts()
self._watch_only = self.LoadWatchOnly()
self._tokens = self.LoadNEP5Tokens()
self._coins = self.LoadCoins()
try:
h = int(self.LoadStoredData('Height'))
Expand Down Expand Up @@ -143,6 +144,12 @@ def AddWatchOnly(self, script_hash):

self._watch_only.append(script_hash)

def AddNEP5Token(self, token):
if token.ScriptHash.ToBytes() in self._tokens.keys():
print("Token already in wallet")
return
self._tokens[token.ScriptHash.ToBytes()] = token

def ChangePassword(self, password_old, password_new):
if not self.ValidatePassword(password_old):
return False
Expand Down Expand Up @@ -332,6 +339,10 @@ def LoadCoins(self):
# abstract
pass

def LoadNEP5Tokens(self):
# abstract
pass

def ProcessBlocks(self):

# start = time.clock()
Expand Down
5 changes: 4 additions & 1 deletion prompt.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
from neo.Prompt.Commands.Withdraw import RequestWithdraw, RedeemWithdraw
from neo.Prompt.Commands.LoadSmartContract import LoadContract, GatherContractDetails, ImportContractAddr, ImportMultiSigContractAddr
from neo.Prompt.Commands.Send import construct_and_send, parse_and_sign
from neo.Prompt.Commands.Wallet import DeleteAddress, ImportWatchAddr
from neo.Prompt.Commands.Wallet import DeleteAddress, ImportWatchAddr,ImportToken
from neo.Prompt.Utils import get_arg
from neo.Prompt.Notify import SubscribeNotifications
from neo.Settings import settings
Expand Down Expand Up @@ -306,6 +306,9 @@ def do_import(self, arguments):
elif item == 'multisig_addr':
return ImportMultiSigContractAddr(self.Wallet, arguments[1:])

elif item == 'token':
return ImportToken(self.Wallet, get_arg(arguments, 1))

print("please specify something to import")
return

Expand Down
2 changes: 1 addition & 1 deletion protocol.testnet.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
],
"VersionName": "/NEO-PYTHON:2.3.4/",
"WsPort": 20334,
"theme": "light",
"theme": "dark",
"themes": {
"dark": {
"Command": "#ff0066",
Expand Down

0 comments on commit dff1a4f

Please sign in to comment.