From 438ec899946e2a1f51f82837b2fb67f84e374bd4 Mon Sep 17 00:00:00 2001 From: Thomas Saunders Date: Sat, 13 Jan 2018 07:46:52 -0600 Subject: [PATCH] adding ability to claim gas from SC address --- neo/Blockchain.py | 2 +- neo/Core/Helper.py | 12 +++++++-- neo/Prompt/Commands/Wallet.py | 26 +++++++++++++++---- neo/SmartContract/ContractParameterContext.py | 1 - prompt.py | 2 +- 5 files changed, 33 insertions(+), 10 deletions(-) diff --git a/neo/Blockchain.py b/neo/Blockchain.py index 837fe60fb..62203ab92 100644 --- a/neo/Blockchain.py +++ b/neo/Blockchain.py @@ -22,7 +22,7 @@ def GetSystemShare(): def GetStateReader(): from neo.SmartContract.StateReader import StateReader - return StateReader.Instance() + return StateReader() def GetConsensusAddress(validators): diff --git a/neo/Core/Helper.py b/neo/Core/Helper.py index b02fd0e0f..3996169bd 100644 --- a/neo/Core/Helper.py +++ b/neo/Core/Helper.py @@ -9,6 +9,7 @@ from neocore.Fixed8 import Fixed8 from neo.SmartContract import TriggerType from neo.Settings import settings +from neo.EventHub import events class Helper(object): @@ -152,7 +153,6 @@ def VerifyScripts(verifiable): if len(hashes) != len(verifiable.Scripts): return False - state_reader = GetStateReader() blockchain = GetBlockchain() for i in range(0, len(hashes)): @@ -168,6 +168,7 @@ def VerifyScripts(verifiable): if hashes[i] != verification_hash: return False + state_reader = GetStateReader() engine = ApplicationEngine(TriggerType.Verification, verifiable, blockchain, state_reader, Fixed8.Zero()) engine.LoadScript(verification, False) invoction = verifiable.Scripts[i].InvocationScript @@ -176,15 +177,22 @@ def VerifyScripts(verifiable): try: success = engine.Execute() state_reader.ExecutionCompleted(engine, success) - except Exception as e: state_reader.ExecutionCompleted(engine, False, e) if engine.EvaluationStack.Count != 1 or not engine.EvaluationStack.Pop().GetBoolean(): + Helper.EmitServiceEvents(state_reader) return False + Helper.EmitServiceEvents(state_reader) + return True @staticmethod def IToBA(value): return [1 if digit == '1' else 0 for digit in bin(value)[2:]] + + @staticmethod + def EmitServiceEvents(state_reader): + for event in state_reader.events_to_dispatch: + events.emit(event.event_type, event) diff --git a/neo/Prompt/Commands/Wallet.py b/neo/Prompt/Commands/Wallet.py index fd12a373d..65e1e95d8 100644 --- a/neo/Prompt/Commands/Wallet.py +++ b/neo/Prompt/Commands/Wallet.py @@ -2,10 +2,12 @@ from neo.Wallets.NEP5Token import NEP5Token from neo.Core.TX.ClaimTransaction import ClaimTransaction from neo.Core.TX.Transaction import TransactionOutput +from neo.Core.TX.TransactionAttribute import TransactionAttribute, TransactionAttributeUsage from neo.SmartContract.ContractParameterContext import ContractParametersContext from neo.Network.NodeLeader import NodeLeader -from neo.Prompt.Utils import string_from_fixed8, get_asset_id +from neo.Prompt.Utils import string_from_fixed8, get_asset_id, get_from_addr from neocore.Fixed8 import Fixed8 +from neocore.UInt160 import UInt160 from prompt_toolkit import prompt import binascii import json @@ -110,7 +112,7 @@ def AddAlias(wallet, addr, title): print(e) -def ClaimGas(wallet, require_password=True): +def ClaimGas(wallet, require_password=True, args=None): unclaimed_coins = wallet.GetUnclaimedCoins() unclaimed_coin_refs = [coin.Reference for coin in unclaimed_coins] @@ -122,7 +124,6 @@ def ClaimGas(wallet, require_password=True): available_bonus = Blockchain.Default().CalculateBonusIgnoreClaimed(unclaimed_coin_refs) if available_bonus == Fixed8.Zero(): - print("No gas to claim") return False @@ -130,8 +131,21 @@ def ClaimGas(wallet, require_password=True): claim_tx.Claims = unclaimed_coin_refs claim_tx.Attributes = [] claim_tx.inputs = [] + + script_hash = wallet.GetChangeAddress() + + # the following can be used to claim gas that is in an imported contract_addr + # example, wallet claim --from-addr={smart contract addr} + if args: + params, from_addr_str = get_from_addr(args) + if from_addr_str: + script_hash = wallet.ToScriptHash(from_addr_str) + standard_contract = wallet.GetStandardAddress() + claim_tx.Attributes = [TransactionAttribute(usage=TransactionAttributeUsage.Script, + data=standard_contract.Data)] + claim_tx.outputs = [ - TransactionOutput(AssetId=Blockchain.SystemCoin().Hash, Value=available_bonus, script_hash=wallet.GetChangeAddress()) + TransactionOutput(AssetId=Blockchain.SystemCoin().Hash, Value=available_bonus, script_hash=script_hash) ] context = ContractParametersContext(claim_tx) @@ -153,12 +167,14 @@ def ClaimGas(wallet, require_password=True): if context.Completed: claim_tx.scripts = context.GetScripts() - wallet.SaveTransaction(claim_tx) + + print("claim tx: %s " % json.dumps(claim_tx.ToJson(), indent=4)) relayed = NodeLeader.Instance().Relay(claim_tx) if relayed: print("Relayed Tx: %s " % claim_tx.Hash.ToString()) + wallet.SaveTransaction(claim_tx) else: print("Could not relay tx %s " % claim_tx.Hash.ToString()) diff --git a/neo/SmartContract/ContractParameterContext.py b/neo/SmartContract/ContractParameterContext.py index 8228692e0..050a011bd 100755 --- a/neo/SmartContract/ContractParameterContext.py +++ b/neo/SmartContract/ContractParameterContext.py @@ -242,7 +242,6 @@ def GetScripts(self): # logger.info("SCRIPT IS %s " % item.Script) witness = Witness( - # invocation_script='40fdb984faf0a400b6894c1ce5b317cf894ba3eb89b899cefda2ac307b278418b943534ad298884f9200dc4b7e1dc244db16c62a44a830a860060ec11d3e6e9717', invocation_script=sb.ToArray(), verification_script=vscript ) diff --git a/prompt.py b/prompt.py index 08a10c96d..4a183d868 100644 --- a/prompt.py +++ b/prompt.py @@ -491,7 +491,7 @@ def show_wallet(self, arguments): elif item == 'close': self.do_close_wallet() elif item == 'claim': - ClaimGas(self.Wallet) + ClaimGas(self.Wallet, True, arguments[1:]) elif item == 'rebuild': self.Wallet.Rebuild() try: