def SearchContracts(self, query): res = [] sn = self._db.snapshot() contracts = DBCollection(self._db, sn, DBPrefix.ST_Contract, ContractState) keys = contracts.Keys query = query.casefold() for item in keys: contract = contracts.TryGet(keyval=item) try: if query in contract.Name.decode('utf-8').casefold(): res.append(contract) elif query in contract.Author.decode('utf-8').casefold(): res.append(contract) elif query in contract.Description.decode('utf-8').casefold(): res.append(contract) elif query in contract.Email.decode('utf-8').casefold(): res.append(contract) except Exception as e: logger.info("Could not query contract: %s " % e) sn.close() return res
def test_contract_create_block(self): hexdata = binascii.unhexlify(self.contract_create_block) block = Helper.AsSerializableWithType(hexdata, 'neo.Core.Block.Block') self.assertEqual(block.Index, self.contract_block_index) result = Blockchain.Default().Persist(block) self.assertTrue(result) contracts = DBCollection(Blockchain.Default()._db, DBPrefix.ST_Contract, ContractState) contract_added = contracts.TryGet(self.contract_hash) self.assertIsNotNone(contract_added) self.assertEqual(contract_added.HasStorage, False) self.assertEqual(contract_added.Name, b'test') self.assertEqual(contract_added.Email, b'test') self.assertEqual(len(Blockchain.Default().SearchContracts("test NEX Template V3")), 1) self.assertEqual(len(Blockchain.Default().SearchContracts("TEST nex TEMPLATE v3")), 1) self.assertEqual(len(Blockchain.Default().SearchContracts("TEST!")), 0) code = contract_added.Code self.assertIsNotNone(code) self.assertEqual(code.ReturnType, 2) self.assertEqual(code.ScriptHash().ToBytes(), self.contract_hash) self.assertEqual(code.Script.hex().encode('utf-8'), self.contract_block_script)
def test_invocation_assetcreate_block(self): hexdata = binascii.unhexlify(self.asset_create_block) block = Helper.AsSerializableWithType(hexdata, 'neo.Core.Block.Block') self.assertEqual(block.Index, self.asset_create_index) result = Blockchain.Default().Persist(block) self.assertTrue(result) # now the asset that was created should be there assets = DBCollection(Blockchain.Default()._db, DBPrefix.ST_Asset, AssetState) newasset = assets.TryGet(self.asset_create_id) self.assertIsNotNone(newasset) self.assertEqual(newasset.AssetType, 1) self.assertEqual(newasset.Precision, 8) self.assertEqual(Crypto.ToAddress(newasset.Admin), self.asset_admin) self.assertEqual(Crypto.ToAddress(newasset.Issuer), self.asset_admin) self.assertIsInstance(newasset.AssetId, UInt256) self.assertEqual(newasset.AssetId.ToBytes(), self.asset_create_id)
def GetSpentCoins(self,tx_hash): if type(tx_hash) is not bytes: tx_hash = bytes(tx_hash.encode('utf-8')) sn = self._db.snapshot() coins = DBCollection(self._db, sn, DBPrefix.ST_SpentCoin, SpentCoinState) return coins.TryGet(keyval=tx_hash)
def GetContract(self, hash): if type(hash) is str: try: hash = UInt160.ParseString(hash).ToBytes() except Exception as e: logger.info("could not convert argument to bytes :%s " % e) return None contracts = DBCollection(self._db, DBPrefix.ST_Contract, ContractState) contract = contracts.TryGet(keyval=hash) return contract
def GetAccountState(self, address, print_all_accounts=False): if type(address) is str: try: address = address.encode('utf-8') except Exception as e: logger.info("could not convert argument to bytes :%s " % e) return None accounts = DBCollection(self._db, DBPrefix.ST_Account, AccountState) acct = accounts.TryGet(keyval=address) return acct
def GetAssetState(self, assetId): if type(assetId) is str: try: assetId = assetId.encode('utf-8') except Exception as e: logger.info("could not convert argument to bytes :%s " % e) return None assets = DBCollection(self._db, DBPrefix.ST_Asset, AssetState) asset = assets.TryGet(assetId) return asset
def GetContract(self, hash): if type(hash) is str: try: hash = hash.encode('utf-8') except Exception as e: self.__log.debug("could not convert argument to bytes :%s " % e) return None sn = self._db.snapshot() contracts = DBCollection(self._db, sn, DBPrefix.ST_Contract, ContractState) contract = contracts.TryGet(keyval=hash) sn.close() return contract
def GetAssetState(self, assetId): if type(assetId) is str: try: assetId = assetId.encode('utf-8') except Exception as e: self.__log.debug("could not convert argument to bytes :%s " % e) return None sn = self._db.snapshot() assets = DBCollection(self._db, sn, DBPrefix.ST_Asset, AssetState) asset = assets.TryGet(assetId) return asset
def GetAllUnspent(self, hash): unspents = [] unspentcoins = DBCollection(self._db, DBPrefix.ST_Coin, UnspentCoinState) state = unspentcoins.TryGet(keyval=hash.ToBytes()) if state: tx, height = self.GetTransaction(hash) for index, item in enumerate(state.Items): if item & CoinState.Spent == 0: unspents.append(tx.outputs[index]) return unspents
def SearchAssetState(self, query): res = [] assets = DBCollection(self._db, DBPrefix.ST_Asset, AssetState) keys = assets.Keys for item in keys: asset = assets.TryGet(keyval=item) if query in asset.Name.decode('utf-8'): res.append(asset) elif query in Crypto.ToAddress(asset.Issuer): res.append(asset) elif query in Crypto.ToAddress(asset.Admin): res.append(asset) return res
def GetUnspent(self, hash, index): coins = DBCollection(self._db, DBPrefix.ST_Coin, UnspentCoinState) state = coins.TryGet(hash) if state is None: return None if index >= len(state.Items): return None if state.Items[index] & CoinState.Spent > 0: return None tx, height = self.GetTransaction(hash) return tx.outputs[index]
def GetAccountState(self, script_hash, print_all_accounts=False): if type(script_hash) is str: try: script_hash = script_hash.encode('utf-8') except Exception as e: logger.info("could not convert argument to bytes :%s " % e) return None sn = self._db.snapshot() accounts = DBCollection(self._db, sn, DBPrefix.ST_Account, AccountState) acct = accounts.TryGet(keyval=script_hash) sn.close() return acct
def GetUnclaimed(self, hash): tx, height = self.GetTransaction(hash) if tx is None: return None out = {} coins = DBCollection(self._db, DBPrefix.ST_SpentCoin, SpentCoinState) state = coins.TryGet(keyval=hash.ToBytes()) if state: for item in state.Items: out[item.index] = SpentCoin(tx.outputs[item.index], height, item.height) return out
def GetAccountState(self, script_hash, print_all_accounts=False): if type(script_hash) is str: try: script_hash = script_hash.encode('utf-8') except Exception as e: self.__log.debug("could not convert argument to bytes :%s " % e) return None sn = self._db.snapshot() accounts = DBCollection(self._db, sn, DBPrefix.ST_Account, AccountState) acct = accounts.TryGet(keyval=script_hash) sn.close() if acct is None: print("Could not find account. Length of accounts %s " % len(accounts.Collection.keys())) if print_all_accounts: print("All accounts: %s " % accounts.Collection.keys()) return acct
def SearchContracts(self, query): res = [] sn = self._db.snapshot() contracts = DBCollection(self._db, sn, DBPrefix.ST_Contract, ContractState) keys = contracts.Keys for item in keys: contract = contracts.TryGet(keyval=item) if query in contract.Name.decode('utf-8'): res.append(contract) elif query in contract.Author.decode('utf-8'): res.append(contract) elif query in contract.Description.decode('utf-8'): res.append(contract) elif query in contract.Email.decode('utf-8'): res.append(contract) sn.close() return res
def SearchAssetState(self, query): res = [] assets = DBCollection(self._db, DBPrefix.ST_Asset, AssetState) keys = assets.Keys if query.lower() == "neo": query = "AntShare" if query.lower() in {"gas", "neogas"}: query = "AntCoin" for item in keys: asset = assets.TryGet(keyval=item) if query in asset.Name.decode('utf-8'): res.append(asset) elif query in Crypto.ToAddress(asset.Issuer): res.append(asset) elif query in Crypto.ToAddress(asset.Admin): res.append(asset) return res
def test_contract_create_block(self): return hexdata = binascii.unhexlify(self.contract_create_block) block = Helper.AsSerializableWithType(hexdata, 'neo.Core.Block.Block') self.assertEqual(block.Index, self.contract_block_index) result = Blockchain.Default().Persist(block) self.assertTrue(result) snapshot = Blockchain.Default()._db.snapshot() contracts = DBCollection(Blockchain.Default()._db, snapshot, DBPrefix.ST_Contract, ContractState) contract_added = contracts.TryGet(self.contract_hash) self.assertIsNotNone(contract_added) self.assertEqual(contract_added.HasStorage, False) self.assertEqual(contract_added.Name, b'test create') self.assertEqual(contract_added.Email, b'*****@*****.**') code = contract_added.Code self.assertIsNotNone(code) self.assertEqual(code.ReturnType, 255) self.assertEqual(code.ScriptHash().ToBytes(), self.contract_hash) self.assertEqual(code.Script.hex().encode('utf-8'), self.contract_block_script) snapshot.close()
def Persist(self, block): start = time.clock() sn = self._db.snapshot() accounts = DBCollection(self._db, sn, DBPrefix.ST_Account, AccountState) unspentcoins = DBCollection(self._db, sn, DBPrefix.ST_Coin, UnspentCoinState) spentcoins = DBCollection(self._db, sn, DBPrefix.ST_SpentCoin, SpentCoinState) assets = DBCollection(self._db, sn, DBPrefix.ST_Asset, AssetState) validators = DBCollection(self._db, sn, DBPrefix.ST_Validator, ValidatorState) contracts = DBCollection(self._db, sn, DBPrefix.ST_Contract, ContractState) storages = DBCollection(self._db, sn, DBPrefix.ST_Storage, StorageItem) amount_sysfee = self.GetSysFeeAmount(block.PrevHash) + block.TotalFees().value amount_sysfee_bytes = amount_sysfee.to_bytes(8, 'little') self.__log.debug("[BlockFee] : %s %s " % (block.Index, amount_sysfee)) try: with self._db.write_batch() as wb: wb.put(DBPrefix.DATA_Block + block.Hash.ToBytes(), amount_sysfee_bytes + block.Trim()) for tx in block.Transactions: wb.put(DBPrefix.DATA_Transaction + tx.Hash.ToBytes(), block.IndexBytes() + tx.ToArray()) # go through all outputs and add unspent coins to them unspentcoinstate = UnspentCoinState.FromTXOutputsConfirmed(tx.outputs) unspentcoins.Add(tx.Hash.ToBytes(), unspentcoinstate) # go through all the accounts in the tx outputs for output in tx.outputs: account = accounts.GetAndChange(output.AddressBytes, AccountState(output.ScriptHash)) if account.HasBalance(output.AssetId): account.AddToBalance(output.AssetId, output.Value) else: account.SetBalanceFor(output.AssetId, output.Value) # go through all tx inputs unique_tx_input_hashes = [] for input in tx.inputs: if input.PrevHash not in unique_tx_input_hashes: unique_tx_input_hashes.append(input.PrevHash) for txhash in unique_tx_input_hashes: prevTx, height = self.GetTransaction(txhash.ToBytes()) coin_refs_by_hash = [coinref for coinref in tx.inputs if coinref.PrevHash.ToBytes() == txhash.ToBytes()] for input in coin_refs_by_hash: uns = unspentcoins.GetAndChange(input.PrevHash.ToBytes()) uns.OrEqValueForItemAt(input.PrevIndex, CoinState.Spent) if prevTx.outputs[input.PrevIndex].AssetId.ToBytes() == Blockchain.SystemShare().Hash.ToBytes(): sc = spentcoins.GetAndChange(input.PrevHash.ToBytes(), SpentCoinState(input.PrevHash, height, [])) sc.Items.append(SpentCoinItem(input.PrevIndex, block.Index)) output = prevTx.outputs[input.PrevIndex] acct = accounts.GetAndChange(prevTx.outputs[input.PrevIndex].AddressBytes, AccountState(output.ScriptHash)) assetid = prevTx.outputs[input.PrevIndex].AssetId acct.SubtractFromBalance(assetid, prevTx.outputs[input.PrevIndex].Value) # do a whole lotta stuff with tx here... if tx.Type == TransactionType.RegisterTransaction: asset = AssetState(tx.Hash, tx.AssetType, tx.Name, tx.Amount, Fixed8(0), tx.Precision, Fixed8(0), Fixed8(0), UInt160(data=bytearray(20)), tx.Owner, tx.Admin, tx.Admin, block.Index + 2 * 2000000, False) assets.Add(tx.Hash.ToBytes(), asset) elif tx.Type == TransactionType.IssueTransaction: txresults = [result for result in tx.GetTransactionResults() if result.Amount.value < 0] for result in txresults: asset = assets.GetAndChange(result.AssetId.ToBytes()) asset.Available = asset.Available - result.Amount elif tx.Type == TransactionType.ClaimTransaction: for input in tx.Claims: sc = spentcoins.TryGet(input.PrevHash.ToBytes()) if sc and sc.HasIndex(input.PrevIndex): sc.DeleteIndex(input.PrevIndex) spentcoins.GetAndChange(input.PrevHash.ToBytes()) elif tx.Type == TransactionType.EnrollmentTransaction: newvalidator = ValidatorState(pub_key=tx.PublicKey) validators.GetAndChange(tx.PublicKey.ToBytes(), newvalidator) elif tx.Type == TransactionType.PublishTransaction: contract = ContractState(tx.Code, tx.NeedStorage, tx.Name, tx.CodeVersion, tx.Author, tx.Email, tx.Description) contracts.GetAndChange(tx.Code.ScriptHash().ToBytes(), contract) elif tx.Type == TransactionType.InvocationTransaction: # print("RUNNING INVOCATION TRASACTION!!!!!! %s %s " % (block.Index, tx.Hash.ToBytes())) print("[neo.Implementations.Blockchains.LevelDBBlockchain.PersistBlock: Invoke tx] -> index, tx hash %s %s " % (block.Index, tx.Hash.ToBytes())) script_table = CachedScriptTable(contracts) service = StateMachine(accounts, validators, assets, contracts, storages, wb) engine = ApplicationEngine( trigger_type=TriggerType.Application, container=tx, table=script_table, service=service, gas=tx.Gas, testMode=False ) engine.LoadScript(tx.Script, False) try: # drum roll? success = engine.Execute() print("[neo.Implementations.Blockchains.LevelDBBlockchain.PersistBlock: engine execute] -> Success") if success: service.Commit() if len(service.notifications) > 0: for n in service.notifications: self.OnNotify(n) for item in engine.EvaluationStack.Items: print("[neo.Implementations.Blockchains.LevelDBBlockchain.PersistBlock: engine execute result] -> %s " % item) except Exception as e: print("[neo.Implementations.Blockchains.LevelDBBlockchain.PersistBlock: engine execute result] Could not execute smart contract. See logs for more details. %s " % e) else: if tx.Type != b'\x00' and tx.Type != 128: self.__log.debug("TX Not Found %s " % tx.Type) # do save all the accounts, unspent, coins, validators, assets, etc # now sawe the current sys block # filter out accounts to delete then commit for key, account in accounts.Current.items(): if not account.IsFrozen and len(account.Votes) == 0 and account.AllBalancesZeroOrLess(): accounts.Remove(key) accounts.Commit(wb) # filte out unspent coins to delete then commit for key, unspent in unspentcoins.Current.items(): unspentcoins.Remove(key) unspentcoins.Commit(wb) # filter out spent coins to delete then commit to db for key, spent in spentcoins.Current.items(): if len(spent.Items) == 0: spentcoins.Remove(key) spentcoins.Commit(wb) # commit validators validators.Commit(wb) # commit assets assets.Commit(wb) # commit contracts contracts.Commit(wb) # commit storages ( not implemented ) storages.Commit(wb) sn.close() wb.put(DBPrefix.SYS_CurrentBlock, block.Hash.ToBytes() + block.IndexBytes()) self._current_block_height = block.Index end = time.clock() self.__log.debug("PERSISTING BLOCK %s (cache) %s %s " % (block.Index, len(self._block_cache), end - start)) except Exception as e: print("couldnt persist block %s " % e)
def Persist(self, block): self._persisting_block = block sn = self._db.snapshot() accounts = DBCollection(self._db, sn, DBPrefix.ST_Account, AccountState) unspentcoins = DBCollection(self._db, sn, DBPrefix.ST_Coin, UnspentCoinState) spentcoins = DBCollection(self._db, sn, DBPrefix.ST_SpentCoin, SpentCoinState) assets = DBCollection(self._db, sn, DBPrefix.ST_Asset, AssetState) validators = DBCollection(self._db, sn, DBPrefix.ST_Validator, ValidatorState) contracts = DBCollection(self._db, sn, DBPrefix.ST_Contract, ContractState) storages = DBCollection(self._db, sn, DBPrefix.ST_Storage, StorageItem) amount_sysfee = self.GetSysFeeAmount(block.PrevHash) + block.TotalFees().value amount_sysfee_bytes = amount_sysfee.to_bytes(8, 'little') to_dispatch = [] with self._db.write_batch() as wb: wb.put(DBPrefix.DATA_Block + block.Hash.ToBytes(), amount_sysfee_bytes + block.Trim()) for tx in block.Transactions: wb.put(DBPrefix.DATA_Transaction + tx.Hash.ToBytes(), block.IndexBytes() + tx.ToArray()) # go through all outputs and add unspent coins to them unspentcoinstate = UnspentCoinState.FromTXOutputsConfirmed(tx.outputs) unspentcoins.Add(tx.Hash.ToBytes(), unspentcoinstate) # go through all the accounts in the tx outputs for output in tx.outputs: account = accounts.GetAndChange(output.AddressBytes, AccountState(output.ScriptHash)) if account.HasBalance(output.AssetId): account.AddToBalance(output.AssetId, output.Value) else: account.SetBalanceFor(output.AssetId, output.Value) # go through all tx inputs unique_tx_input_hashes = [] for input in tx.inputs: if input.PrevHash not in unique_tx_input_hashes: unique_tx_input_hashes.append(input.PrevHash) for txhash in unique_tx_input_hashes: prevTx, height = self.GetTransaction(txhash.ToBytes()) coin_refs_by_hash = [coinref for coinref in tx.inputs if coinref.PrevHash.ToBytes() == txhash.ToBytes()] for input in coin_refs_by_hash: uns = unspentcoins.GetAndChange(input.PrevHash.ToBytes()) uns.OrEqValueForItemAt(input.PrevIndex, CoinState.Spent) if prevTx.outputs[input.PrevIndex].AssetId.ToBytes() == Blockchain.SystemShare().Hash.ToBytes(): sc = spentcoins.GetAndChange(input.PrevHash.ToBytes(), SpentCoinState(input.PrevHash, height, [])) sc.Items.append(SpentCoinItem(input.PrevIndex, block.Index)) output = prevTx.outputs[input.PrevIndex] acct = accounts.GetAndChange(prevTx.outputs[input.PrevIndex].AddressBytes, AccountState(output.ScriptHash)) assetid = prevTx.outputs[input.PrevIndex].AssetId acct.SubtractFromBalance(assetid, prevTx.outputs[input.PrevIndex].Value) # do a whole lotta stuff with tx here... if tx.Type == TransactionType.RegisterTransaction: asset = AssetState(tx.Hash, tx.AssetType, tx.Name, tx.Amount, Fixed8(0), tx.Precision, Fixed8(0), Fixed8(0), UInt160(data=bytearray(20)), tx.Owner, tx.Admin, tx.Admin, block.Index + 2 * 2000000, False) assets.Add(tx.Hash.ToBytes(), asset) elif tx.Type == TransactionType.IssueTransaction: txresults = [result for result in tx.GetTransactionResults() if result.Amount.value < 0] for result in txresults: asset = assets.GetAndChange(result.AssetId.ToBytes()) asset.Available = asset.Available - result.Amount elif tx.Type == TransactionType.ClaimTransaction: for input in tx.Claims: sc = spentcoins.TryGet(input.PrevHash.ToBytes()) if sc and sc.HasIndex(input.PrevIndex): sc.DeleteIndex(input.PrevIndex) spentcoins.GetAndChange(input.PrevHash.ToBytes()) elif tx.Type == TransactionType.EnrollmentTransaction: newvalidator = ValidatorState(pub_key=tx.PublicKey) validators.GetAndChange(tx.PublicKey.ToBytes(), newvalidator) elif tx.Type == TransactionType.StateTransaction: # @TODO Implement persistence for State Descriptors pass elif tx.Type == TransactionType.PublishTransaction: contract = ContractState(tx.Code, tx.NeedStorage, tx.Name, tx.CodeVersion, tx.Author, tx.Email, tx.Description) contracts.GetAndChange(tx.Code.ScriptHash().ToBytes(), contract) elif tx.Type == TransactionType.InvocationTransaction: script_table = CachedScriptTable(contracts) service = StateMachine(accounts, validators, assets, contracts, storages, wb) engine = ApplicationEngine( trigger_type=TriggerType.Application, container=tx, table=script_table, service=service, gas=tx.Gas, testMode=False ) engine.LoadScript(tx.Script, False) try: success = engine.Execute() service.ExecutionCompleted(engine, success) except Exception as e: service.ExecutionCompleted(engine, False, e) to_dispatch = to_dispatch + service.events_to_dispatch else: if tx.Type != b'\x00' and tx.Type != 128: logger.info("TX Not Found %s " % tx.Type) # do save all the accounts, unspent, coins, validators, assets, etc # now sawe the current sys block # filter out accounts to delete then commit for key, account in accounts.Current.items(): if not account.IsFrozen and len(account.Votes) == 0 and account.AllBalancesZeroOrLess(): accounts.Remove(key) accounts.Commit(wb) # filte out unspent coins to delete then commit for key, unspent in unspentcoins.Current.items(): if unspent.IsAllSpent: unspentcoins.Remove(key) unspentcoins.Commit(wb) # filter out spent coins to delete then commit to db for key, spent in spentcoins.Current.items(): if len(spent.Items) == 0: spentcoins.Remove(key) spentcoins.Commit(wb) # commit validators validators.Commit(wb) # commit assets assets.Commit(wb) # commit contracts contracts.Commit(wb) sn.close() wb.put(DBPrefix.SYS_CurrentBlock, block.Hash.ToBytes() + block.IndexBytes()) self._current_block_height = block.Index self._persisting_block = None self.TXProcessed += len(block.Transactions) for event in to_dispatch: events.emit(event.event_type, event)
def GetStorageItem(self, storage_key): sn = self._db.snapshot() storages = DBCollection(self._db, sn, DBPrefix.ST_Storage, StorageItem) item = storages.TryGet(storage_key.ToArray()) sn.close() return item
def GetStorageItem(self, storage_key): storages = DBCollection(self._db, DBPrefix.ST_Storage, StorageItem) item = storages.TryGet(storage_key.ToArray()) return item
def Persist(self, block): accounts = DBCollection(self._db, DBPrefix.ST_Account, AccountState) unspentcoins = DBCollection(self._db, DBPrefix.ST_Coin, UnspentCoinState) spentcoins = DBCollection(self._db, DBPrefix.ST_SpentCoin, SpentCoinState) assets = DBCollection(self._db, DBPrefix.ST_Asset, AssetState) validators = DBCollection(self._db, DBPrefix.ST_Validator, ValidatorState) contracts = DBCollection(self._db, DBPrefix.ST_Contract, ContractState) storages = DBCollection(self._db, DBPrefix.ST_Storage, StorageItem) amount_sysfee = self.GetSysFeeAmount( block.PrevHash) + block.TotalFees().value amount_sysfee_bytes = amount_sysfee.to_bytes(8, 'little') with self._db.write_batch() as wb: for tx in block.Transactions: unspentcoinstate = UnspentCoinState.FromTXOutputsConfirmed( tx.outputs) unspentcoins.Add(tx.Hash.ToBytes(), unspentcoinstate) # go through all the accounts in the tx outputs for output in tx.outputs: account = accounts.GetAndChange( output.AddressBytes, AccountState(output.ScriptHash)) if account.HasBalance(output.AssetId): account.AddToBalance(output.AssetId, output.Value) else: account.SetBalanceFor(output.AssetId, output.Value) # go through all tx inputs unique_tx_input_hashes = [] for input in tx.inputs: if input.PrevHash not in unique_tx_input_hashes: unique_tx_input_hashes.append(input.PrevHash) for txhash in unique_tx_input_hashes: prevTx, height = self.GetTransaction(txhash.ToBytes()) coin_refs_by_hash = [ coinref for coinref in tx.inputs if coinref.PrevHash.ToBytes() == txhash.ToBytes() ] for input in coin_refs_by_hash: uns = unspentcoins.GetAndChange( input.PrevHash.ToBytes()) uns.OrEqValueForItemAt(input.PrevIndex, CoinState.Spent) if prevTx.outputs[input.PrevIndex].AssetId.ToBytes( ) == Blockchain.SystemShare().Hash.ToBytes(): sc = spentcoins.GetAndChange( input.PrevHash.ToBytes(), SpentCoinState(input.PrevHash, height, [])) sc.Items.append( SpentCoinItem(input.PrevIndex, block.Index)) output = prevTx.outputs[input.PrevIndex] acct = accounts.GetAndChange( prevTx.outputs[input.PrevIndex].AddressBytes, AccountState(output.ScriptHash)) assetid = prevTx.outputs[input.PrevIndex].AssetId acct.SubtractFromBalance( assetid, prevTx.outputs[input.PrevIndex].Value) # do a whole lotta stuff with tx here... if tx.Type == TransactionType.RegisterTransaction: asset = AssetState(tx.Hash, tx.AssetType, tx.Name, tx.Amount, Fixed8(0), tx.Precision, Fixed8(0), Fixed8(0), UInt160(data=bytearray(20)), tx.Owner, tx.Admin, tx.Admin, block.Index + 2 * 2000000, False) assets.Add(tx.Hash.ToBytes(), asset) elif tx.Type == TransactionType.IssueTransaction: txresults = [ result for result in tx.GetTransactionResults() if result.Amount.value < 0 ] for result in txresults: asset = assets.GetAndChange(result.AssetId.ToBytes()) asset.Available = asset.Available - result.Amount elif tx.Type == TransactionType.ClaimTransaction: for input in tx.Claims: sc = spentcoins.TryGet(input.PrevHash.ToBytes()) if sc and sc.HasIndex(input.PrevIndex): sc.DeleteIndex(input.PrevIndex) spentcoins.GetAndChange(input.PrevHash.ToBytes()) elif tx.Type == TransactionType.EnrollmentTransaction: validator = validators.GetAndChange( tx.PublicKey, ValidatorState(pub_key=tx.PublicKey)) # logger.info("VALIDATOR %s " % validator.ToJson()) elif tx.Type == TransactionType.StateTransaction: # @TODO Implement persistence for State Descriptors pass elif tx.Type == TransactionType.PublishTransaction: contract = ContractState(tx.Code, tx.NeedStorage, tx.Name, tx.CodeVersion, tx.Author, tx.Email, tx.Description) contracts.GetAndChange(tx.Code.ScriptHash().ToBytes(), contract) elif tx.Type == TransactionType.InvocationTransaction: script_table = CachedScriptTable(contracts) service = StateMachine(accounts, validators, assets, contracts, storages, wb=wb) engine = ApplicationEngine( trigger_type=TriggerType.Application, container=tx, table=script_table, service=service, gas=tx.Gas, testMode=True) engine.LoadScript(tx.Script) # normally, this function does not return true/false # for testing purposes, we try to execute and if an exception is raised # we will return false, otherwise if success return true # this is different than the 'success' bool returned by engine.Execute() # the 'success' bool returned by engine.Execute() is a value indicating # wether or not the invocation was successful, and if so, we then commit # the changes made by the contract to the database try: success = engine.Execute() # service.ExecutionCompleted(engine, success) return True except Exception as e: # service.ExecutionCompleted(self, False, e) return False
def GetContract(self, hash): sn = self._db.snapshot() contracts = DBCollection(self._db, sn, DBPrefix.ST_Contract, ContractState) sn.close() return contracts.TryGet(keyval=hash)
def GetAssetState(self, assetId): sn = self._db.snapshot() assets = DBCollection(self._db, sn, DBPrefix.ST_Asset, AssetState) asset = assets.TryGet(assetId) return asset