Exemple #1
0
 def clone_from_live(self):
     print("cloining from live!")
     clone_db = GetBlockchain()._db.snapshot()
     for key, value in clone_db.iterator(prefix=DBPrefix.ST_Storage,
                                         include_value=True):
         self._db.put(key, value)
     print("cloned db")
Exemple #2
0
    def Blockchain_GetHeight(self, engine: ExecutionEngine):
        if GetBlockchain() is None:
            engine.CurrentContext.EvaluationStack.PushT(0)
        else:
            engine.CurrentContext.EvaluationStack.PushT(GetBlockchain().Height)

        return True
Exemple #3
0
    def NetworkFee(self):
        """
        Get the network fee.

        Returns:
            Fixed8:
        """
        if self.__network_fee is None:

            input = Fixed8(0)

            for coin_ref in self.References.values():
                if coin_ref.AssetId == GetBlockchain().SystemCoin().Hash:
                    input = input + coin_ref.Value

            output = Fixed8(0)

            for tx_output in self.outputs:
                if tx_output.AssetId == GetBlockchain().SystemCoin().Hash:
                    output = output + tx_output.Value

            self.__network_fee = input - output - self.SystemFee()

        #            logger.info("Determined network fee to be %s " % (self.__network_fee.value))

        return self.__network_fee
Exemple #4
0
    def FromTrimmedData(byts):
        """
        Deserialize a block from raw bytes.

        Args:
            byts:

        Returns:
            Block:
        """
        block = Block()
        block.__is_trimmed = True
        ms = StreamManager.GetStream(byts)
        reader = BinaryReader(ms)

        block.DeserializeUnsigned(reader)
        reader.ReadByte()
        witness = Witness()
        witness.Deserialize(reader)
        block.Script = witness

        bc = GetBlockchain()
        tx_list = []
        for tx_hash in reader.ReadHashes():
            tx = bc.GetTransaction(tx_hash)[0]
            if not tx:
                raise Exception("Could not find transaction!\n Are you running code against a valid Blockchain instance?\n Tests that accesses transactions or size of a block but inherit from NeoTestCase instead of BlockchainFixtureTestCase will not work.")
            tx_list.append(tx)

        block.Transactions = tx_list

        StreamManager.ReleaseStream(ms)

        return block
Exemple #5
0
    def Verify(self):
        """
        Verify block using the verification script.

        Returns:
            bool: True if valid. False otherwise.
        """
        if not self.Hash.ToBytes() == GetGenesis().Hash.ToBytes():
            return False

        bc = GetBlockchain()

        if not bc.ContainsBlock(self.Index):
            return False

        if self.Index > 0:
            prev_header = GetBlockchain().GetHeader(self.PrevHash.ToBytes())

            if prev_header is None:
                return False

            if prev_header.Index + 1 != self.Index:
                return False

            if prev_header.Timestamp >= self.Timestamp:
                return False

        # this should be done to actually verify the block
        if not Helper.VerifyScripts(self):
            return False

        return True
Exemple #6
0
    def Verify(self):
        if not self.Hash.ToBytes() == GetGenesis().Hash.ToBytes():
            return False

        bc = GetBlockchain()

        if not bc.ContainsBlock(self.Index):
            return False

        if self.Index > 0:
            prev_header = GetBlockchain().GetHeader(self.PrevHash.ToBytes())

            if prev_header is None:
                return False

            if prev_header.Index + 1 != self.Index:
                return False

            if prev_header.Timestamp >= self.Timestamp:
                return False

        # this should be done to actually verify the block
        if not Helper.VerifyScripts(self):
            return False

        return True
Exemple #7
0
    def Verify(self):
        print("verifying block base 1")
        if not self.Hash.ToBytes() == GetGenesis().Hash.ToBytes(): return False
        print("verifying block base @ %s " % self.Index)
        bc = GetBlockchain()
        print("BC: %s " % bc)
        if not bc.ContainsBlock(self.Index):
            print("blockchin didnt contain block index")
            return False
        print("verifying block base 3 %s " % self.PrevHash.ToBytes())

        if self.Index > 0:
            prev_header = GetBlockchain().GetHeader(self.PrevHash.ToBytes())

            if prev_header == None: return False

            if prev_header.Index + 1 != self.Index: return False

            if prev_header.Timestamp >= self.Timestamp: return False

        print("Will verify scripts!!")
        #this should be done to actually verify the block
        if not Helper.VerifyScripts(self):
            print("could not verify scripts")
            return False

        return True
Exemple #8
0
    def Verify(self, completely=False):

        self.__log.debug("Verifying BLOCK!!")
        from neo.Blockchain import GetBlockchain,GetConsensusAddress

        res = super(Block, self).Verify()
        if not res: return False

        #first TX has to be a miner transaction. other tx after that cant be miner tx
        if self.Transactions[0].Type != TransactionType.MinerTransaction: return False
        for tx in self.Transactions[1:]:
            if tx.Type == TransactionType.MinerTransaction: return False


        if completely:
            bc = GetBlockchain()

            if self.NextConsensus != GetConsensusAddress(bc.GetValidators(self.Transactions).ToArray()):
                return False
            
            for tx in self.Transactions:
                if not tx.Verify():
                    pass
            self.__log.debug("Blocks cannot be fully validated at this moment.  please pass completely=False")
            raise NotImplementedError()
            ## do this below!
            #foreach(Transaction tx in Transactions)
            #if (!tx.Verify(Transactions.Where(p = > !p.Hash.Equals(tx.Hash)))) return false;
            #Transaction tx_gen = Transactions.FirstOrDefault(p= > p.Type == TransactionType.MinerTransaction);
            #if (tx_gen?.Outputs.Sum(p = > p.Value) != CalculateNetFee(Transactions)) return false;

        return True
            
            
Exemple #9
0
    def Blockchain_GetTransactionHeight(self, engine: ExecutionEngine):
        data = engine.CurrentContext.EvaluationStack.Pop().GetByteArray()
        height = -1

        if GetBlockchain() is not None:
            tx, height = GetBlockchain().GetTransaction(UInt256(data=data))

        engine.CurrentContext.EvaluationStack.PushT(height)
        return True
Exemple #10
0
 def Runtime_GetCurrentTime(self, engine: ExecutionEngine):
     if self.Snapshot.PersistingBlock is None:
         BC = GetBlockchain()
         header = BC.GetHeaderByHeight(BC.Height)
         engine.CurrentContext.EvaluationStack.PushT(
             header.Timestamp + GetBlockchain().SECONDS_PER_BLOCK)
     else:
         engine.CurrentContext.EvaluationStack.PushT(
             self.Snapshot.PersistingBlock.Timestamp)
     return True
Exemple #11
0
    def Blockchain_GetTransaction(self, engine: ExecutionEngine):
        data = engine.CurrentContext.EvaluationStack.Pop().GetByteArray()
        tx = None

        if GetBlockchain() is not None:
            tx, height = GetBlockchain().GetTransaction(UInt256(data=data))

        engine.CurrentContext.EvaluationStack.PushT(
            StackItem.FromInterface(tx))
        return True
Exemple #12
0
def TestInvokeContract(wallet, args, withdrawal_tx=None, from_addr=None,
                       min_fee=DEFAULT_MIN_FEE, invoke_attrs=None, owners=None):
    BC = GetBlockchain()

    contract = BC.GetContract(args[0])

    if contract:
        #
        params = args[1:] if len(args) > 1 else []

        params, neo_to_attach, gas_to_attach = PromptUtils.get_asset_attachments(params)
        params, parse_addresses = PromptUtils.get_parse_addresses(params)
        params.reverse()

        if '--i' in params:
            params = []
            for index, iarg in enumerate(contract.Code.ParameterList):
                param, abort = PromptUtils.gather_param(index, iarg)
                if abort:
                    return None, None, None, None, False
                params.append(param)
            params.reverse()

        sb = ScriptBuilder()

        for p in params:
            process_params(sb, p, wallet, parse_addresses)

        sb.EmitAppCall(contract.Code.ScriptHash().Data)

        out = sb.ToArray()

        outputs = []

        if neo_to_attach:
            output = TransactionOutput(AssetId=Blockchain.SystemShare().Hash,
                                       Value=neo_to_attach,
                                       script_hash=contract.Code.ScriptHash(),
                                       )
            outputs.append(output)

        if gas_to_attach:
            output = TransactionOutput(AssetId=Blockchain.SystemCoin().Hash,
                                       Value=gas_to_attach,
                                       script_hash=contract.Code.ScriptHash())

            outputs.append(output)

        return test_invoke(out, wallet, outputs, withdrawal_tx, from_addr, min_fee, invoke_attrs=invoke_attrs, owners=owners)

    else:

        print("Contract %s not found" % args[0])

    return None, None, None, None, False
Exemple #13
0
    def Verify(self):
        if self.Hash == GetGenesis().Hash: return True

        if GetBlockchain().ContainsBlock(self.Hash): return True

        prev_header = GetBlockchain().GetHeader(self.PrevHash)

        if prev_header == None: return False

        if prev_header.Index + 1 != self.Index: return False

        if prev_header.Timestamp >= self.Timestamp: return False

        self.__log.debug("End verify for now. cannot verify scripts at the moment")
        return True
Exemple #14
0
    def Runtime_Log(self, engine: ExecutionEngine):
        item = engine.CurrentContext.EvaluationStack.Pop()
        # will raise an exception for types that don't support it
        item.GetByteArray()

        # if we pass we can call the convenience method to pretty print the data
        message = item.GetString()

        hash = UInt160(data=engine.CurrentContext.ScriptHash())

        tx_hash = None

        if engine.ScriptContainer:
            tx_hash = engine.ScriptContainer.Hash
        engine.write_log(str(message))

        # Build and emit smart contract event
        self.events_to_dispatch.append(
            SmartContractEvent(SmartContractEvent.RUNTIME_LOG,
                               ContractParameter(ContractParameterType.String,
                                                 value=message),
                               hash,
                               GetBlockchain().Height + 1,
                               tx_hash,
                               test_mode=engine.testMode))

        return True
Exemple #15
0
    def Contract_Destroy(self, engine):
        hash = UInt160(data=engine.CurrentContext.ScriptHash())

        contract = self.Snapshot.Contracts.TryGet(hash.ToBytes())

        if contract is not None:

            self.Snapshot.Contracts.Delete(hash.ToBytes())

            if contract.HasStorage:

                to_del = []
                for k, v in self.Snapshot.Storages.Find(hash.ToArray()):
                    storage_key = StorageKey(script_hash=hash, key=k[20:])
                    # Snapshot.Storages.Delete() modifies the underlying dictionary of the cache we'd be iterating
                    # over using Storages.Find. We therefore need to postpone deletion
                    to_del.append(storage_key)

                for storage_key in to_del:
                    self.Snapshot.Storages.Delete(storage_key.ToArray())

        self.events_to_dispatch.append(
            SmartContractEvent(SmartContractEvent.CONTRACT_DESTROY,
                               ContractParameter(
                                   ContractParameterType.InteropInterface,
                                   contract),
                               hash,
                               GetBlockchain().Height + 1,
                               engine.ScriptContainer.Hash
                               if engine.ScriptContainer else None,
                               test_mode=engine.testMode))
        return True
Exemple #16
0
    def VerifyScripts(verifiable):
        """
        Verify the scripts of the provided `verifiable` object.

        Args:
            verifiable (neo.IO.Mixins.VerifiableMixin):

        Returns:
            bool: True if verification is successful. False otherwise.
        """
        try:
            hashes = verifiable.GetScriptHashesForVerifying()
        except Exception as e:
            logger.debug("couldn't get script hashes %s " % e)
            return False

        if len(hashes) != len(verifiable.Scripts):
            return False

        blockchain = GetBlockchain()

        for i in range(0, len(hashes)):
            verification = verifiable.Scripts[i].VerificationScript

            if len(verification) == 0:
                sb = ScriptBuilder()
                sb.EmitAppCall(hashes[i].Data)
                verification = sb.ms.getvalue()
            else:
                verification_hash = Crypto.ToScriptHash(verification,
                                                        unhex=False)
                if hashes[i] != verification_hash:
                    return False

            state_reader = GetStateReader()
            script_table = CachedScriptTable(
                DBCollection(blockchain._db, DBPrefix.ST_Contract,
                             ContractState))

            engine = ApplicationEngine(TriggerType.Verification,
                                       verifiable, script_table, state_reader,
                                       Fixed8.Zero())
            engine.LoadScript(verification)
            invocation = verifiable.Scripts[i].InvocationScript
            engine.LoadScript(invocation)

            try:
                success = engine.Execute()
                state_reader.ExecutionCompleted(engine, success)
            except Exception as e:
                state_reader.ExecutionCompleted(engine, False, e)

            if engine.ResultStack.Count != 1 or not engine.ResultStack.Pop(
            ).GetBoolean():
                Helper.EmitServiceEvents(state_reader)
                return False

            Helper.EmitServiceEvents(state_reader)

        return True
Exemple #17
0
    def FullTransactions(self):
        """
        Get the list of full Transaction objects.

        Note: Transactions can be trimmed to contain only the header and the hash. This will get the full data if
        trimmed transactions are found.

        Returns:
            list: of neo.Core.TX.Transaction.Transaction objects.
        """
        is_trimmed = False
        try:
            tx = self.Transactions[0]
            if type(tx) is str:
                is_trimmed = True
        except Exception as e:
            pass

        if not is_trimmed:
            return self.Transactions

        txs = []
        for hash in self.Transactions:
            tx, height = GetBlockchain().GetTransaction(hash)
            txs.append(tx)

        self.Transactions = txs

        return self.Transactions
Exemple #18
0
    def test_Storage2(self):
        output = Compiler.instance().load('%s/boa_test/example/blockchain/StorageTest.py' % TestContract.dirname).default
        out = output.write()

        snapshot = GetBlockchain()._db.createSnapshot()

        tx, results, total_ops, engine = TestBuild(out, ['sget', 100, 10000000000], self.GetWallet1(), '070505', '05', snapshot=snapshot)
        self.assertEqual(len(results), 1)
        self.assertEqual(results[0].GetByteArray(), b'')

        tx, results, total_ops, engine = TestBuild(out, ['sput', 100, 10000000000], self.GetWallet1(), '070505', '05', snapshot=snapshot)
        self.assertEqual(len(results), 1)
        self.assertEqual(results[0].GetByteArray(), b'\x01')

        tx, results, total_ops, engine = TestBuild(out, ['sget', 100, 10000000000], self.GetWallet1(), '070505', '05', snapshot=snapshot)
        self.assertEqual(len(results), 1)
        self.assertEqual(results[0].GetBigInteger(), 10000000000)

        tx, results, total_ops, engine = TestBuild(out, ['sdel', 100, 10000000000], self.GetWallet1(), '070505', '05', snapshot=snapshot)
        self.assertEqual(len(results), 1)
        self.assertEqual(results[0].GetByteArray(), b'\x01')

        tx, results, total_ops, engine = TestBuild(out, ['sget', 100, 10000000000], self.GetWallet1(), '070505', '05', snapshot=snapshot)
        self.assertEqual(len(results), 1)
        self.assertEqual(results[0].GetByteArray(), b'')
Exemple #19
0
    def Storage_Delete(self, engine: ExecutionEngine):
        if self.Trigger != TriggerType.Application and self.Trigger != TriggerType.ApplicationR:
            return False

        context = engine.CurrentContext.EvaluationStack.Pop().GetInterface(
            neo.SmartContract.StorageContext.StorageContext)
        if not self.CheckStorageContext(context):
            return False
        if context.IsReadOnly:
            return False

        key = engine.CurrentContext.EvaluationStack.Pop().GetByteArray()
        storage_key = StorageKey(script_hash=context.ScriptHash, key=key)

        if type(engine) == ExecutionEngine:
            test_mode = False
        else:
            test_mode = engine.testMode
        self.events_to_dispatch.append(
            SmartContractEvent(SmartContractEvent.STORAGE_DELETE,
                               ContractParameter(ContractParameterType.String,
                                                 key),
                               context.ScriptHash,
                               GetBlockchain().Height + 1,
                               engine.ScriptContainer.Hash
                               if engine.ScriptContainer else None,
                               test_mode=test_mode))

        item = self.Snapshot.Storages.TryGet(storage_key.ToArray())
        if item and item.IsConstant:
            return False

        self.Snapshot.Storages.Delete(storage_key.ToArray())

        return True
Exemple #20
0
    def Blockchain_GetHeader(self, engine: ExecutionEngine):
        data = engine.CurrentContext.EvaluationStack.Pop().GetByteArray()

        header = None

        if len(data) <= 5:

            height = BigInteger.FromBytes(data)

            if GetBlockchain() is not None:

                header = GetBlockchain().GetHeaderBy(height_or_hash=height)

            elif height == 0:

                header = GetBlockchain().GenesisBlock().Header

        elif len(data) == 32:

            hash = UInt256(data=data)

            if GetBlockchain() is not None:

                header = GetBlockchain().GetHeaderBy(height_or_hash=hash)

            elif hash == GetBlockchain().GenesisBlock().Hash:

                header = GetBlockchain().GenesisBlock().Header

        engine.CurrentContext.EvaluationStack.PushT(
            StackItem.FromInterface(header))
        return True
Exemple #21
0
 def get_invoke_result(self, script):
     snapshot = GetBlockchain()._db.createSnapshot()
     appengine = ApplicationEngine.Run(snapshot, script=script)
     return {
         "script": script.decode('utf-8'),
         "state": VMStateStr(appengine.State),
         "gas_consumed": appengine.GasConsumed().ToString(),
         "stack": [ContractParameter.ToParameter(item).ToJson() for item in appengine.ResultStack.Items]
     }
Exemple #22
0
    def GetScriptHashesForVerifying(self):
        #if this is the genesis block, we dont have a prev hash!
        if self.PrevHash == bytearray(32):
            return [self.Script.VerificationScript.ToScriptHash()]

        prev_header = GetBlockchain().GetHeader(self.PrevHash)
        if prev_header == None:
            raise Exception('Invalid operation')
        return [prev_header.NextConsensus]
Exemple #23
0
    def ToJson(self):
        json = super(Block, self).ToJson()
        if self.__is_trimmed:
            json['tx'] = self.Transactions
        else:
            json['tx'] = [tx.ToJson() for tx in self.Transactions]

        json['sys_fee'] = GetBlockchain().GetSysFeeAmount(self.Hash)
        return json
Exemple #24
0
    def Verify(self, completely=False):
        """
        Verify the integrity of the block.

        Args:
            completely: (Not functional at this time).

        Returns:
            bool: True if valid. False otherwise.
        """
        res = super(Block, self).Verify()
        if not res:
            return False

        from neo.Blockchain import GetBlockchain, GetConsensusAddress

        # first TX has to be a miner transaction. other tx after that cant be miner tx
        if self.Transactions[0].Type != TransactionType.MinerTransaction:
            return False
        for tx in self.Transactions[1:]:
            if tx.Type == TransactionType.MinerTransaction:
                return False

        if completely:
            bc = GetBlockchain()

            if self.NextConsensus != GetConsensusAddress(
                    bc.GetValidators(self.Transactions).ToArray()):
                return False

            for tx in self.Transactions:
                if not tx.Verify():
                    pass
            logger.error(
                "Blocks cannot be fully validated at this moment.  please pass completely=False"
            )
            raise NotImplementedError()
            # do this below!
            # foreach(Transaction tx in Transactions)
            # if (!tx.Verify(Transactions.Where(p = > !p.Hash.Equals(tx.Hash)))) return false;
            # Transaction tx_gen = Transactions.FirstOrDefault(p= > p.Type == TransactionType.MinerTransaction);
            # if (tx_gen?.Outputs.Sum(p = > p.Value) != CalculateNetFee(Transactions)) return false;

        return True
    def __init__(self, verifiable, isMultiSig=False):

        self.Verifiable = verifiable
        if verifiable.raw_tx:
            self.ScriptHashes = verifiable.GetScriptHashesForVerifying()
        else:
            self.ScriptHashes = verifiable.GetScriptHashesForVerifying(
                GetBlockchain()._db.createSnapshot())
        self.ContextItems = {}
        self.IsMultiSig = isMultiSig
Exemple #26
0
    def __init__(self):

        try:
            self._db = GetBlockchain().Default().GetDB().cloneDatabaseStorage(
                DBFactory.getDebugStorageDB())
        except Exception as e:
            logger.info(
                "DEBUG leveldb unavailable, you may already be running this process: %s "
                % e)
            raise Exception('DEBUG Leveldb Unavailable %s ' % e)
Exemple #27
0
def TestInvokeContract(wallet, args):

    BC = GetBlockchain()

    contract = BC.GetContract(args[0])

    if contract:
        descripe_contract(contract)

        verbose = False

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

        print("VERBOSE %s " % verbose)

        params = args[1:] if len(args) > 1 else []

        if len(params) > 0 and params[0] == 'describe':
            return

        params.reverse()

        sb = ScriptBuilder()

        for p in params:

            item = parse_param(p)
            sb.push(item)

        sb.EmitAppCall(contract.Code.ScriptHash().Data)

        out = sb.ToArray()

        return test_invoke(out, wallet)

    else:

        print("Contract %s not found" % args[0])

    return None, None
Exemple #28
0
    def Blockchain_GetAsset(self, engine: ExecutionEngine):
        data = engine.CurrentContext.EvaluationStack.Pop().GetByteArray()
        asset = None

        if GetBlockchain() is not None:
            asset = self.Snapshot.Assets.TryGet(UInt256(data=data))
        if asset is None:
            return False
        engine.CurrentContext.EvaluationStack.PushT(
            StackItem.FromInterface(asset))
        return True
    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)

        snapshot = GetBlockchain()._db.createSnapshot()
        with self.assertRaises(Exception) as e:
            tx.GetScriptHashesForVerifying(snapshot)

        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

        snapshot = GetBlockchain()._db.createSnapshot()
        with self.assertRaises(Exception) as e:
            tx.GetScriptHashesForVerifying(snapshot)

        self.assertTrue("Invalid operation" in str(e.exception))
Exemple #30
0
    def Transaction_GetUnspentCoins(self, engine: ExecutionEngine):
        tx = engine.CurrentContext.EvaluationStack.Pop().GetInterface(
            Transaction)

        if tx is None:
            return False

        outputs = GetBlockchain().GetAllUnspent(tx.Hash)
        if len(outputs) > engine.maxArraySize:
            return False

        refs = [StackItem.FromInterface(unspent) for unspent in outputs]
        engine.CurrentContext.EvaluationStack.PushT(refs)
        return True
Exemple #31
0
 def clone_from_live(self):
     clone_db = GetBlockchain()._db.snapshot()
     for key, value in clone_db.iterator(prefix=DBPrefix.ST_Storage, include_value=True):
         self._db.put(key, value)