예제 #1
0
        public async Task Update_ZeroContract_Test()
        {
            var code = Codes.Single(kv => kv.Key.Contains("GenesisUpdate")).Value;
            var contractUpdateInput = new ContractUpdateInput
            {
                Address = BasicContractZeroAddress,
                Code    = ByteString.CopyFrom(code)
            };
            const string methodName = nameof(BasicContractZero.UpdateSmartContract);
            var          proposalId = await CreateProposalAsync(methodName, contractUpdateInput);

            var txResult1 = await ApproveWithMinersAsync(proposalId);

            txResult1.Status.ShouldBe(TransactionResultStatus.Mined);
            var txResult2 = await ReleaseProposalAsync(proposalId);

            txResult2.Status.ShouldBe(TransactionResultStatus.Mined);

            var contractAddress = CodeUpdated.Parser.ParseFrom(txResult2.Logs[0].Indexed[0]).Address;

            contractAddress.ShouldBe(BasicContractZeroAddress);
            var codeHash = Hash.FromRawBytes(code);
            var newHash  = CodeUpdated.Parser.ParseFrom(txResult2.Logs[0].NonIndexed).NewCodeHash;

            newHash.ShouldBe(codeHash);
        }
예제 #2
0
        public async Task UpdateSmartContractWithCodeCheck_Test()
        {
            var contractDeploymentInput = new ContractDeploymentInput
            {
                Category = KernelConstants.DefaultRunnerCategory, // test the default runner
                Code     = ByteString.CopyFrom(Codes.Single(kv => kv.Key.Contains("TokenConverter")).Value)
            };

            var newAddress = await DeployAsync(Tester, ParliamentAddress, contractDeploymentInput);

            var code = Codes.Single(kv => kv.Key.Contains("ReferendumAuth")).Value;
            var contractUpdateInput = new ContractUpdateInput
            {
                Address = newAddress,
                Code    = ByteString.CopyFrom(code)
            };

            var proposingTxResult = await Tester.ExecuteContractWithMiningAsync(BasicContractZeroAddress,
                                                                                nameof(BasicContractZero.ProposeUpdateContract), contractUpdateInput);

            proposingTxResult.Status.ShouldBe(TransactionResultStatus.Mined);

            var proposalId = ProposalCreated.Parser
                             .ParseFrom(proposingTxResult.Logs.First(l => l.Name.Contains(nameof(ProposalCreated))).NonIndexed)
                             .ProposalId;

            proposalId.ShouldNotBeNull();
            var proposedContractInputHash = ContractProposed.Parser
                                            .ParseFrom(proposingTxResult.Logs.First(l => l.Name.Contains(nameof(ContractProposed))).NonIndexed)
                                            .ProposedContractInputHash;

            await ApproveWithMinersAsync(Tester, ParliamentAddress, proposalId);

            var releaseApprovedContractTxResult = await Tester.ExecuteContractWithMiningAsync(BasicContractZeroAddress,
                                                                                              nameof(BasicContractZero.ReleaseApprovedContract), new ReleaseContractInput
            {
                ProposalId = proposalId,
                ProposedContractInputHash = proposedContractInputHash
            });

            releaseApprovedContractTxResult.Status.ShouldBe(TransactionResultStatus.Mined);
            var codeCheckProposalId = ProposalCreated.Parser
                                      .ParseFrom(releaseApprovedContractTxResult.Logs.First(l => l.Name.Contains(nameof(ProposalCreated)))
                                                 .NonIndexed).ProposalId;

            codeCheckProposalId.ShouldNotBeNull();

            // Wait for contract code check event handler to finish its job
            // Mine a block, should include approval transaction
            var block = await Tester.MineEmptyBlockAsync();

            var txs = await Tester.GetTransactionsAsync(block.TransactionIds);

            txs.First(tx => tx.To == ParliamentAddress).MethodName
            .ShouldBe(nameof(ParliamentAuthContractContainer.ParliamentAuthContractStub.ApproveMultiProposals));
        }
예제 #3
0
        public override Address UpdateSmartContract(ContractUpdateInput input)
        {
            var contractAddress = input.Address;
            var code            = input.Code.ToByteArray();
            var info            = State.ContractInfos[contractAddress];

            Assert(info != null, "Contract not found.");
            RequireSenderAuthority(State.CodeCheckController.Value?.OwnerAddress);
            var inputHash = CalculateHashFromInput(input);

            if (!TryClearContractProposingData(inputHash, out _))
            {
                Assert(Context.Sender == info.Author, "No permission.");
            }

            var oldCodeHash = info.CodeHash;
            var newCodeHash = Hash.FromRawBytes(code);

            Assert(!oldCodeHash.Equals(newCodeHash), "Code is not changed.");

            Assert(State.SmartContractRegistrations[newCodeHash] == null, "Same code has been deployed before.");

            info.CodeHash = newCodeHash;
            info.Version++;
            State.ContractInfos[contractAddress] = info;

            var reg = new SmartContractRegistration
            {
                Category         = info.Category,
                Code             = ByteString.CopyFrom(code),
                CodeHash         = newCodeHash,
                IsSystemContract = info.IsSystemContract,
                Version          = info.Version
            };

            State.SmartContractRegistrations[reg.CodeHash] = reg;

            Context.UpdateContract(contractAddress, reg, null);

            Context.Fire(new CodeUpdated()
            {
                Address     = contractAddress,
                OldCodeHash = oldCodeHash,
                NewCodeHash = newCodeHash,
                Version     = info.Version
            });

            Context.LogDebug(() => "BasicContractZero - update success: " + contractAddress.GetFormatted());
            return(contractAddress);
        }
예제 #4
0
        public override Hash ProposeUpdateContract(ContractUpdateInput input)
        {
            var proposedContractInputHash = CalculateHashFromInput(input);

            Assert(State.ContractProposingInputMap[proposedContractInputHash] == null, "Already proposed.");
            State.ContractProposingInputMap[proposedContractInputHash] = new ContractProposingInput
            {
                Proposer = Context.Sender,
                Status   = ContractProposingInputStatus.Proposed
            };

            var contractAddress = input.Address;
            var info            = State.ContractInfos[contractAddress];

            Assert(info != null, "Contract does not exist.");
            AssertAuthorityByContractInfo(info, Context.Sender);

            // Create proposal for deployment
            RequireParliamentContractAddressSet();
            var proposalCreationInput = new CreateProposalBySystemContractInput
            {
                ProposalInput = new CreateProposalInput
                {
                    ToAddress          = Context.Self,
                    ContractMethodName =
                        nameof(BasicContractZeroContainer.BasicContractZeroBase.ProposeContractCodeCheck),
                    Params = new ContractCodeCheckInput
                    {
                        ContractInput        = input.ToByteString(),
                        IsContractDeployment = false
                    }.ToByteString(),
                    OrganizationAddress = State.ContractDeploymentController.Value.OwnerAddress,
                    ExpiredTime         = Context.CurrentBlockTime.AddSeconds(ContractProposalExpirationTimePeriod)
                },
                OriginProposer = Context.Sender
            };

            Context.SendInline(State.ContractDeploymentController.Value.ContractAddress,
                               nameof(AuthorizationContractContainer.AuthorizationContractReferenceState
                                      .CreateProposalBySystemContract), proposalCreationInput);

            // Fire event to trigger BPs checking contract code
            Context.Fire(new ContractProposed
            {
                ProposedContractInputHash = proposedContractInputHash
            });

            return(proposedContractInputHash);
        }
예제 #5
0
        public async Task Update_ZeroContract_Test()
        {
            var code = Codes.Single(kv => kv.Key.Contains("GenesisUpdate")).Value;
            var contractUpdateInput = new ContractUpdateInput
            {
                Address = BasicContractZeroAddress,
                Code    = ByteString.CopyFrom(code)
            };

            var proposingTxResult = await Tester.ExecuteContractWithMiningAsync(BasicContractZeroAddress,
                                                                                nameof(BasicContractZero.ProposeUpdateContract), contractUpdateInput);

            proposingTxResult.Status.ShouldBe(TransactionResultStatus.Mined);

            var proposalId = ProposalCreated.Parser
                             .ParseFrom(proposingTxResult.Logs.First(l => l.Name.Contains(nameof(ProposalCreated))).NonIndexed)
                             .ProposalId;

            proposalId.ShouldNotBeNull();
            var proposedContractInputHash = ContractProposed.Parser
                                            .ParseFrom(proposingTxResult.Logs.First(l => l.Name.Contains(nameof(ContractProposed))).NonIndexed)
                                            .ProposedContractInputHash;

            await ApproveWithMinersAsync(Tester, ParliamentAddress, proposalId);

            var releaseApprovedContractTxResult = await Tester.ExecuteContractWithMiningAsync(BasicContractZeroAddress,
                                                                                              nameof(BasicContractZero.ReleaseApprovedContract), new ReleaseContractInput
            {
                ProposalId = proposalId,
                ProposedContractInputHash = proposedContractInputHash
            });

            releaseApprovedContractTxResult.Status.ShouldBe(TransactionResultStatus.Mined);
            var codeCheckProposalId = ProposalCreated.Parser
                                      .ParseFrom(releaseApprovedContractTxResult.Logs.First(l => l.Name.Contains(nameof(ProposalCreated)))
                                                 .NonIndexed).ProposalId;

            codeCheckProposalId.ShouldNotBeNull();

            await ApproveWithMinersAsync(Tester, ParliamentAddress, codeCheckProposalId);

            var result = await Tester.ExecuteContractWithMiningAsync(BasicContractZeroAddress,
                                                                     nameof(BasicContractZeroContainer.BasicContractZeroStub.ReleaseCodeCheckedContract),
                                                                     new ReleaseContractInput
                                                                     { ProposedContractInputHash = proposedContractInputHash, ProposalId = codeCheckProposalId });

            result.Status.ShouldBe(TransactionResultStatus.Mined);
        }
예제 #6
0
        public override Address UpdateSmartContract(ContractUpdateInput input)
        {
            var contractAddress = input.Address;
            var code            = input.Code.ToByteArray();
            var info            = State.ContractInfos[contractAddress];

            Assert(info != null, "Contract does not exist.");

            if (info.IsSystemContract)
            {
                RequireAuthority(State.GenesisOwner.Value);
            }
            else
            {
                RequireAuthority();
                Assert(info.Author == Context.Origin, "Only author can propose contract update.");
            }

            var oldCodeHash = info.CodeHash;
            var newCodeHash = Hash.FromRawBytes(code);

            Assert(!oldCodeHash.Equals(newCodeHash), "Code is not changed.");

            info.CodeHash = newCodeHash;
            State.ContractInfos[contractAddress] = info;

            var reg = new SmartContractRegistration
            {
                Category = info.Category,
                Code     = ByteString.CopyFrom(code),
                CodeHash = newCodeHash
            };

            State.SmartContractRegistrations[reg.CodeHash] = reg;

            Context.UpdateContract(contractAddress, reg, null);

            Context.Fire(new CodeUpdated()
            {
                Address     = contractAddress,
                OldCodeHash = oldCodeHash,
                NewCodeHash = newCodeHash
            });

            Context.LogDebug(() => "BasicContractZero - update success: " + contractAddress.GetFormatted());
            return(contractAddress);
        }
예제 #7
0
        public override Hash ProposeUpdateContract(ContractUpdateInput input)
        {
            var proposedContractInputHash = CalculateHashFromInput(input);

            RegisterContractProposingData(proposedContractInputHash);

            var contractAddress = input.Address;
            var info            = State.ContractInfos[contractAddress];

            Assert(info != null, "Contract not found.");
            AssertAuthorityByContractInfo(info, Context.Sender);

            // Create proposal for contract update
            var proposalCreationInput = new CreateProposalBySystemContractInput
            {
                ProposalInput = new CreateProposalInput
                {
                    ToAddress          = Context.Self,
                    ContractMethodName =
                        nameof(BasicContractZeroImplContainer.BasicContractZeroImplBase.ProposeContractCodeCheck),
                    Params = new ContractCodeCheckInput
                    {
                        ContractInput             = input.ToByteString(),
                        CodeCheckReleaseMethod    = nameof(UpdateSmartContract),
                        ProposedContractInputHash = proposedContractInputHash,
                        Category         = info.Category,
                        IsSystemContract = info.IsSystemContract
                    }.ToByteString(),
                    OrganizationAddress = State.ContractDeploymentController.Value.OwnerAddress,
                    ExpiredTime         = Context.CurrentBlockTime.AddSeconds(ContractProposalExpirationTimePeriod),
                },
                OriginProposer = Context.Sender
            };

            Context.SendInline(State.ContractDeploymentController.Value.ContractAddress,
                               nameof(AuthorizationContractContainer.AuthorizationContractReferenceState
                                      .CreateProposalBySystemContract), proposalCreationInput);

            Context.Fire(new ContractProposed
            {
                ProposedContractInputHash = proposedContractInputHash
            });

            return(proposedContractInputHash);
        }
예제 #8
0
        public override Hash ProposeUpdateContract(ContractUpdateInput input)
        {
            var proposedContractInputHash = CalculateHashFromInput(input);

            Assert(State.ContractProposingInputMap[proposedContractInputHash] == null, "Already proposed.");
            State.ContractProposingInputMap[proposedContractInputHash] = new ContractProposingInput
            {
                Proposer = Context.Sender,
                Status   = ContractProposingInputStatus.Proposed
            };

            var contractAddress = input.Address;
            var info            = State.ContractInfos[contractAddress];

            Assert(info != null, "Contract does not exist.");
            RequireAuthorityByContractInfo(info);

            // Create proposal for deployment
            RequireParliamentAuthAddressSet();
            State.ParliamentAuthContract.CreateProposal.Send(new CreateProposalInput
            {
                ToAddress          = Context.Self,
                ContractMethodName = nameof(BasicContractZeroContainer.BasicContractZeroBase.ProposeContractCodeCheck),
                Params             = new ContractCodeCheckInput
                {
                    ContractInput        = input.ToByteString(),
                    IsContractDeployment = false
                }.ToByteString(),
                OrganizationAddress = State.GenesisOwner.Value,
                ExpiredTime         = Context.CurrentBlockTime.AddMinutes(10) // Maybe, get the interval from configuration
            });

            // Fire event to trigger BPs checking contract code
            Context.Fire(new ContractProposed
            {
                ProposedContractInputHash = proposedContractInputHash
            });

            return(proposedContractInputHash);
        }
예제 #9
0
        public async Task UpdateContract_Attach_After_ReadOnly_Transaction()
        {
            var chain = await _blockchainService.GetChainAsync();

            var blockHeight = chain.BestChainHeight;
            var blockHash   = chain.BestChainHash;

            var input = new ContractUpdateInput
            {
                Address = BasicFunctionContractAddress,
                Code    = ByteString.CopyFrom(Codes.Single(kv => kv.Key.EndsWith("BasicUpdate")).Value)
            }.ToByteString();
            var transaction = CreateTransaction(DefaultSender, ContractZeroAddress,
                                                nameof(BasicContractZeroStub.UpdateSmartContract), input, blockHeight, blockHash);
            var block = await ExecuteAsync(transaction, blockHeight, blockHash);

            var transactionResult =
                await _transactionResultManager.GetTransactionResultAsync(transaction.GetHash(),
                                                                          block.Header.GetDisambiguatingHash());

            var basicFunctionContractStub = GetTestBasicFunctionContractStub(DefaultSenderKeyPair);
            await basicFunctionContractStub.QueryWinMoney.CallAsync(new Empty());

            await _blockAttachService.AttachBlockAsync(block);

            var basic11ContractStub = GetTestBasicUpdateContractStub(DefaultSenderKeyPair);
//            //execute new action method
            var transactionResult1 = (await basic11ContractStub.UpdateStopBet.SendAsync(
                                          new Empty())).TransactionResult;

            transactionResult1.Status.ShouldBe(TransactionResultStatus.Mined);

            //call new view method
            var result = (await basic11ContractStub.QueryBetStatus.CallAsync(
                              new Empty())).BoolValue;

            result.ShouldBeTrue();

            await _blockchainService.SetIrreversibleBlockAsync(chain, block.Height, block.GetHash());
        }
예제 #10
0
        public override Address UpdateSmartContract(ContractUpdateInput input)
        {
            var contractAddress = input.Address;
            var code            = input.Code.ToByteArray();
            var info            = State.ContractInfos[contractAddress];

            Assert(info != null, "Contract does not exist.");
            Assert(info.Owner.Equals(Context.Sender), "Only owner is allowed to update code.");

            var oldCodeHash = info.CodeHash;
            var newCodeHash = Hash.FromRawBytes(code);

            Assert(!oldCodeHash.Equals(newCodeHash), "Code is not changed.");

            info.CodeHash = newCodeHash;
            State.ContractInfos[contractAddress] = info;

            var reg = new SmartContractRegistration
            {
                Category = info.Category,
                Code     = ByteString.CopyFrom(code),
                CodeHash = newCodeHash
            };

            State.SmartContractRegistrations[reg.CodeHash] = reg;

            Context.UpdateContract(contractAddress, reg, null);

            Context.Fire(new CodeUpdated()
            {
                Address     = contractAddress,
                OldCodeHash = oldCodeHash,
                NewCodeHash = newCodeHash
            });

            Context.LogDebug(() => "BasicContractZero - update success: " + contractAddress.GetFormatted());
            return(contractAddress);
        }
예제 #11
0
        public async Task UpdateSmartContract_Test()
        {
            var contractDeploymentInput = new ContractDeploymentInput
            {
                Category = KernelConstants.DefaultRunnerCategory, // test the default runner
                Code     = ByteString.CopyFrom(Codes.Single(kv => kv.Key.Contains("TokenConverter")).Value)
            };

            var newAddress = await DeployAsync(Tester, ParliamentAddress, contractDeploymentInput);

            var code = Codes.Single(kv => kv.Key.Contains("Treasury")).Value;
            var contractUpdateInput = new ContractUpdateInput
            {
                Address = newAddress,
                Code    = ByteString.CopyFrom(code)
            };

            var proposingTxResult = await Tester.ExecuteContractWithMiningAsync(BasicContractZeroAddress,
                                                                                nameof(BasicContractZero.ProposeUpdateContract), contractUpdateInput);

            proposingTxResult.Status.ShouldBe(TransactionResultStatus.Mined);

            var proposalId = ProposalCreated.Parser
                             .ParseFrom(proposingTxResult.Logs.First(l => l.Name.Contains(nameof(ProposalCreated))).NonIndexed)
                             .ProposalId;

            proposalId.ShouldNotBeNull();
            var proposedContractInputHash = ContractProposed.Parser
                                            .ParseFrom(proposingTxResult.Logs.First(l => l.Name.Contains(nameof(ContractProposed))).NonIndexed)
                                            .ProposedContractInputHash;

            await ApproveWithMinersAsync(Tester, ParliamentAddress, proposalId);

            var releaseApprovedContractTxResult = await Tester.ExecuteContractWithMiningAsync(BasicContractZeroAddress,
                                                                                              nameof(BasicContractZero.ReleaseApprovedContract), new ReleaseContractInput
            {
                ProposalId = proposalId,
                ProposedContractInputHash = proposedContractInputHash
            });

            releaseApprovedContractTxResult.Status.ShouldBe(TransactionResultStatus.Mined);
            var codeCheckProposalId = ProposalCreated.Parser
                                      .ParseFrom(releaseApprovedContractTxResult.Logs.First(l => l.Name.Contains(nameof(ProposalCreated)))
                                                 .NonIndexed).ProposalId;

            codeCheckProposalId.ShouldNotBeNull();

            await ApproveWithMinersAsync(Tester, ParliamentAddress, codeCheckProposalId);

            var updateResult = await Tester.ExecuteContractWithMiningAsync(BasicContractZeroAddress,
                                                                           nameof(BasicContractZeroContainer.BasicContractZeroStub.ReleaseCodeCheckedContract),
                                                                           new ReleaseContractInput
                                                                           { ProposedContractInputHash = proposedContractInputHash, ProposalId = codeCheckProposalId });

            updateResult.Status.ShouldBe(TransactionResultStatus.Mined);
            var contractAddress = CodeUpdated.Parser
                                  .ParseFrom(updateResult.Logs.First(l => l.Name.Contains(nameof(CodeUpdated))).Indexed[0]).Address;

            contractAddress.ShouldBe(newAddress);
            var codeHash = Hash.FromRawBytes(code);
            var newHash  = CodeUpdated.Parser
                           .ParseFrom(updateResult.Logs.First(l => l.Name.Contains(nameof(CodeUpdated))).NonIndexed).NewCodeHash;

            newHash.ShouldBe(codeHash);
        }
예제 #12
0
        public async Task UpdateContract_With_Two_Branch()
        {
            var blockHeader = await _blockchainService.GetBestChainLastBlockHeaderAsync();

            var startBlockHeight = blockHeader.Height;
            var startBlockHash   = blockHeader.GetHash();

            var transactionResult = (await BasicContractZeroStub.UpdateSmartContract.SendAsync(
                                         new ContractUpdateInput
            {
                Address = BasicFunctionContractAddress,
                Code = ByteString.CopyFrom(Codes.Single(kv => kv.Key.EndsWith("BasicUpdate")).Value)
            }
                                         )).TransactionResult;

            transactionResult.Status.ShouldBe(TransactionResultStatus.Mined);

            var basic11ContractStub = GetTestBasicUpdateContractStub(DefaultSenderKeyPair);
//            //execute new action method
            var transactionResult1 = (await basic11ContractStub.UpdateStopBet.SendAsync(
                                          new Empty())).TransactionResult;

            transactionResult1.Status.ShouldBe(TransactionResultStatus.Mined);

            var transaction = CreateTransaction(DefaultSender, BasicFunctionContractAddress,
                                                nameof(TestBasicFunctionContractStub.QueryWinMoney), new Empty().ToByteString(), startBlockHeight,
                                                startBlockHash);
            var block = await ExecuteAsync(transaction, startBlockHeight, startBlockHash);

            await _blockAttachService.AttachBlockAsync(block);

            transaction = CreateTransaction(DefaultSender, BasicFunctionContractAddress,
                                            nameof(TestBasicFunctionContractStub.QueryWinMoney), new Empty().ToByteString(), block.Height,
                                            block.GetHash());
            block = await ExecuteAsync(transaction, block.Height, block.GetHash());

            await _blockAttachService.AttachBlockAsync(block);

            var input             = new Empty().ToByteString();
            var failedTransaction = CreateTransaction(DefaultSender, BasicFunctionContractAddress,
                                                      nameof(basic11ContractStub.UpdateStopBet), input, block.Height, block.GetHash());

            block = await ExecuteAsync(failedTransaction, block.Height, block.GetHash());

            await _blockAttachService.AttachBlockAsync(block);

            transactionResult =
                await _transactionResultManager.GetTransactionResultAsync(failedTransaction.GetHash(),
                                                                          block.Header.GetDisambiguatingHash());

            transactionResult.Status.ShouldBe(TransactionResultStatus.Failed);
            transactionResult.Error.ShouldContain("Failed to find handler for UpdateStopBet.");

            input = new ContractUpdateInput
            {
                Address = BasicFunctionContractAddress,
                Code    = ByteString.CopyFrom(Codes.Single(kv => kv.Key.EndsWith("BasicFunction")).Value)
            }.ToByteString();
            var updateTransaction = CreateTransaction(DefaultSender, ContractZeroAddress,
                                                      nameof(BasicContractZeroStub.UpdateSmartContract), input, block.Height, block.GetHash());
            var updateBlock = await ExecuteAsync(updateTransaction, block.Height, block.GetHash());

            await _blockAttachService.AttachBlockAsync(updateBlock);

//
            transactionResult =
                await _transactionResultManager.GetTransactionResultAsync(updateTransaction.GetHash(),
                                                                          updateBlock.Header.GetDisambiguatingHash());

            transactionResult.Status.ShouldBe(TransactionResultStatus.Failed);
            transactionResult.Error.Contains("Code is not changed").ShouldBeTrue();

            input = new ContractUpdateInput
            {
                Address = BasicFunctionContractAddress,
                Code    = ByteString.CopyFrom(Codes.Single(kv => kv.Key.EndsWith("BasicUpdate")).Value)
            }.ToByteString();
            updateTransaction = CreateTransaction(DefaultSender, ContractZeroAddress,
                                                  nameof(BasicContractZeroStub.UpdateSmartContract), input, updateBlock.Height, updateBlock.GetHash());
            updateBlock = await ExecuteAsync(updateTransaction, updateBlock.Height, updateBlock.GetHash());

            await _blockAttachService.AttachBlockAsync(updateBlock);

            transactionResult =
                await _transactionResultManager.GetTransactionResultAsync(updateTransaction.GetHash(),
                                                                          updateBlock.Header.GetDisambiguatingHash());

            transactionResult.Status.ShouldBe(TransactionResultStatus.Mined);

            basic11ContractStub = GetTestBasicUpdateContractStub(DefaultSenderKeyPair);
            //execute new action method
            transactionResult = (await basic11ContractStub.UpdateStopBet.SendAsync(
                                     new Empty())).TransactionResult;
            transactionResult.Status.ShouldBe(TransactionResultStatus.Mined);

            //call new view method
            var result = (await basic11ContractStub.QueryBetStatus.CallAsync(
                              new Empty())).BoolValue;

            result.ShouldBeTrue();
        }