public void Create_WithFunds_Via_Controller()
        {
            using (NodeBuilder builder = NodeBuilder.Create(this))
            {
                CoreNode scSender   = builder.CreateSmartContractPowNode();
                CoreNode scReceiver = builder.CreateSmartContractPowNode();

                builder.StartAll();

                scSender.NotInIBD();
                scReceiver.NotInIBD();

                scSender.FullNode.Network.Consensus.CoinbaseMaturity   = 1L;
                scReceiver.FullNode.Network.Consensus.CoinbaseMaturity = 1L;
                int maturity = (int)scReceiver.FullNode.Network.Consensus.CoinbaseMaturity;

                scSender.FullNode.WalletManager().CreateWallet(Password, WalletName, Passphrase);
                scReceiver.FullNode.WalletManager().CreateWallet(Password, WalletName, Passphrase);
                HdAddress addr = scSender.FullNode.WalletManager().GetUnusedAddress(new WalletAccountReference(WalletName, AccountName));
                Features.Wallet.Wallet wallet = scSender.FullNode.WalletManager().GetWalletByName(WalletName);
                Key key = wallet.GetExtendedPrivateKeyForAddress(Password, addr).PrivateKey;

                scSender.SetDummyMinerSecret(new BitcoinSecret(key, scSender.FullNode.Network));
                scReceiver.SetDummyMinerSecret(new BitcoinSecret(key, scReceiver.FullNode.Network));

                scSender.GenerateStratisWithMiner(2);
                TestHelper.WaitLoop(() => TestHelper.IsNodeSynced(scSender));

                var total = scSender.FullNode.WalletManager().GetSpendableTransactionsInWallet(WalletName).Sum(s => s.Transaction.Amount);
                Assert.Equal(Money.COIN * (maturity + 1) * 50, total);

                SmartContractsController       senderSmartContractsController = scSender.FullNode.NodeService <SmartContractsController>();
                SmartContractWalletController  senderWalletController         = scSender.FullNode.NodeService <SmartContractWalletController>();
                SmartContractCompilationResult compilationResult = SmartContractCompiler.CompileFile("SmartContracts/StorageDemo.cs");
                Assert.True(compilationResult.Success);

                var buildRequest = new BuildCreateContractTransactionRequest
                {
                    AccountName  = AccountName,
                    Amount       = "30",
                    GasLimit     = "10000",
                    GasPrice     = "1",
                    ContractCode = compilationResult.Compilation.ToHexString(),
                    FeeAmount    = "0.001",
                    Password     = Password,
                    WalletName   = WalletName,
                    Sender       = addr.Address
                };

                JsonResult result   = (JsonResult)senderSmartContractsController.BuildCreateSmartContractTransaction(buildRequest);
                var        response = (BuildCreateContractTransactionResponse)result.Value;
                scSender.CreateRPCClient().AddNode(scReceiver.Endpoint, true);

                SmartContractSharedSteps.SendTransactionAndMine(scSender, scReceiver, senderWalletController, response.Hex);

                ContractStateRepositoryRoot senderState = scSender.FullNode.NodeService <ContractStateRepositoryRoot>();
                Assert.Equal((ulong)30 * 100_000_000, senderState.GetCurrentBalance(new Address(response.NewContractAddress).ToUint160(new SmartContractsRegTest())));
            }
        }
Example #2
0
        public void SendAndReceiveSmartContractTransactionsUsingController()
        {
            using (NodeBuilder builder = NodeBuilder.Create(this))
            {
                CoreNode scSender   = builder.CreateSmartContractPowNode();
                CoreNode scReceiver = builder.CreateSmartContractPowNode();

                builder.StartAll();

                scSender.NotInIBD();
                scReceiver.NotInIBD();

                scSender.FullNode.WalletManager().CreateWallet(Password, WalletName);
                scReceiver.FullNode.WalletManager().CreateWallet(Password, WalletName);
                HdAddress addr = scSender.FullNode.WalletManager().GetUnusedAddress(new WalletAccountReference(WalletName, AccountName));
                Features.Wallet.Wallet wallet = scSender.FullNode.WalletManager().GetWalletByName(WalletName);
                Key key = wallet.GetExtendedPrivateKeyForAddress(Password, addr).PrivateKey;

                scSender.SetDummyMinerSecret(new BitcoinSecret(key, scSender.FullNode.Network));
                scReceiver.SetDummyMinerSecret(new BitcoinSecret(key, scReceiver.FullNode.Network));
                var maturity = (int)scSender.FullNode.Network.Consensus.CoinbaseMaturity;
                scSender.GenerateStratisWithMiner(maturity + 5);
                TestHelper.WaitLoop(() => TestHelper.IsNodeSynced(scSender));

                var total = scSender.FullNode.WalletManager().GetSpendableTransactionsInWallet(WalletName).Sum(s => s.Transaction.Amount);
                Assert.Equal(Money.COIN * (maturity + 5) * 50, total);

                SmartContractsController       senderSmartContractsController = scSender.FullNode.NodeService <SmartContractsController>();
                SmartContractWalletController  senderWalletController         = scSender.FullNode.NodeService <SmartContractWalletController>();
                SmartContractCompilationResult compilationResult = SmartContractCompiler.CompileFile("SmartContracts/StorageDemo.cs");
                Assert.True(compilationResult.Success);

                var buildRequest = new BuildCreateContractTransactionRequest
                {
                    AccountName  = AccountName,
                    GasLimit     = "10000",
                    GasPrice     = "1",
                    ContractCode = compilationResult.Compilation.ToHexString(),
                    FeeAmount    = "0.001",
                    Password     = Password,
                    WalletName   = WalletName,
                    Sender       = addr.Address
                };

                JsonResult result   = (JsonResult)senderSmartContractsController.BuildCreateSmartContractTransaction(buildRequest);
                var        response = (BuildCreateContractTransactionResponse)result.Value;
                scSender.CreateRPCClient().AddNode(scReceiver.Endpoint, true);

                SmartContractSharedSteps.SendTransactionAndMine(scSender, scReceiver, senderWalletController, response.Hex);

                var receiptStorage = scReceiver.FullNode.NodeService <ISmartContractReceiptStorage>();
                Assert.NotNull(receiptStorage.GetReceipt(response.TransactionId));

                // Check wallet history is updating correctly
                result = (JsonResult)senderWalletController.GetHistory(new WalletHistoryRequest
                {
                    AccountName = AccountName,
                    WalletName  = WalletName
                });
                var walletHistoryModel = (WalletHistoryModel)result.Value;
                Assert.Single(walletHistoryModel.AccountsHistoryModel.First().TransactionsHistory.Where(x => x.Type == TransactionItemType.Send));

                string storageRequestResult = (string)((JsonResult)senderSmartContractsController.GetStorage(new GetStorageRequest
                {
                    ContractAddress = response.NewContractAddress.ToString(),
                    StorageKey = "TestSave",
                    DataType = SmartContractDataType.String
                })).Value;
                Assert.Equal("Hello, smart contract world!", storageRequestResult);

                string ownerRequestResult = (string)((JsonResult)senderSmartContractsController.GetStorage(new GetStorageRequest
                {
                    ContractAddress = response.NewContractAddress.ToString(),
                    StorageKey = "Owner",
                    DataType = SmartContractDataType.Address
                })).Value;
                Assert.NotEmpty(ownerRequestResult);

                string counterRequestResult = (string)((JsonResult)senderSmartContractsController.GetStorage(new GetStorageRequest
                {
                    ContractAddress = response.NewContractAddress.ToString(),
                    StorageKey = "Counter",
                    DataType = SmartContractDataType.Int
                })).Value;
                Assert.Equal("12345", counterRequestResult);

                var callRequest = new BuildCallContractTransactionRequest
                {
                    AccountName     = AccountName,
                    GasLimit        = "10000",
                    GasPrice        = "1",
                    Amount          = "0",
                    MethodName      = "Increment",
                    ContractAddress = response.NewContractAddress,
                    FeeAmount       = "0.001",
                    Password        = Password,
                    WalletName      = WalletName,
                    Sender          = addr.Address
                };
                result = (JsonResult)senderSmartContractsController.BuildCallSmartContractTransaction(callRequest);
                var callResponse = (BuildCallContractTransactionResponse)result.Value;

                SmartContractSharedSteps.SendTransactionAndMine(scSender, scReceiver, senderWalletController, callResponse.Hex);

                counterRequestResult = (string)((JsonResult)senderSmartContractsController.GetStorage(new GetStorageRequest
                {
                    ContractAddress = response.NewContractAddress.ToString(),
                    StorageKey = "Counter",
                    DataType = SmartContractDataType.Int
                })).Value;
                Assert.Equal("12346", counterRequestResult);

                // Check wallet history again
                result = (JsonResult)senderWalletController.GetHistory(new WalletHistoryRequest
                {
                    AccountName = AccountName,
                    WalletName  = WalletName
                });
                walletHistoryModel = (WalletHistoryModel)result.Value;
                Assert.Equal(2, walletHistoryModel.AccountsHistoryModel.First().TransactionsHistory.Where(x => x.Type == TransactionItemType.Send).Count());

                // Check receipts
                var receiptResponse = (JsonResult)senderSmartContractsController.GetReceipt(callResponse.TransactionId.ToString());
                var receiptModel    = (ReceiptModel)receiptResponse.Value;
                Assert.True(receiptModel.Successful);
            }
        }
        public void SendAndReceiveSmartContractTransactionsUsingController()
        {
            using (NodeBuilder builder = NodeBuilder.Create(this))
            {
                CoreNode scSender   = builder.CreateSmartContractPowNode();
                CoreNode scReceiver = builder.CreateSmartContractPowNode();

                builder.StartAll();

                scSender.NotInIBD();
                scReceiver.NotInIBD();

                int maturity = (int)scReceiver.FullNode.Network.Consensus.CoinbaseMaturity;

                scSender.FullNode.WalletManager().CreateWallet(Password, WalletName, Passphrase);
                scReceiver.FullNode.WalletManager().CreateWallet(Password, WalletName, Passphrase);

                HdAddress addr = TestHelper.MineBlocks(scSender, WalletName, Password, AccountName, maturity + 5).AddressUsed;
                TestHelper.WaitLoop(() => TestHelper.IsNodeSynced(scSender));

                int spendable = GetSpendableBlocks(maturity + 5, maturity);
                var total     = scSender.FullNode.WalletManager().GetSpendableTransactionsInWallet(WalletName).Sum(s => s.Transaction.Amount);
                Assert.Equal(Money.COIN * spendable * 50, total);

                SmartContractsController       senderSmartContractsController = scSender.FullNode.NodeService <SmartContractsController>();
                SmartContractWalletController  senderWalletController         = scSender.FullNode.NodeService <SmartContractWalletController>();
                SmartContractCompilationResult compilationResult = SmartContractCompiler.CompileFile("SmartContracts/StorageDemo.cs");
                Assert.True(compilationResult.Success);

                var buildRequest = new BuildCreateContractTransactionRequest
                {
                    AccountName  = AccountName,
                    GasLimit     = "10000",
                    GasPrice     = "1",
                    ContractCode = compilationResult.Compilation.ToHexString(),
                    FeeAmount    = "0.001",
                    Password     = Password,
                    WalletName   = WalletName,
                    Sender       = addr.Address
                };

                JsonResult result   = (JsonResult)senderSmartContractsController.BuildCreateSmartContractTransaction(buildRequest);
                var        response = (BuildCreateContractTransactionResponse)result.Value;
                scSender.CreateRPCClient().AddNode(scReceiver.Endpoint, true);

                SmartContractSharedSteps.SendTransaction(scSender, scReceiver, senderWalletController, response.Hex);
                TestHelper.MineBlocks(scReceiver, WalletName, Password, AccountName, 2);
                TestHelper.WaitLoop(() => TestHelper.AreNodesSynced(scReceiver, scSender));

                // Check wallet history is updating correctly.

                result = (JsonResult)senderWalletController.GetHistory(new WalletHistoryRequest
                {
                    AccountName = AccountName,
                    WalletName  = WalletName
                });
                var walletHistoryModel = (WalletHistoryModel)result.Value;
                Assert.Single(walletHistoryModel.AccountsHistoryModel.First().TransactionsHistory.Where(x => x.Type == TransactionItemType.Send));

                // Check receipt was stored and can be retrieved.
                var receiptResponse = (ReceiptResponse)((JsonResult)senderSmartContractsController.GetReceipt(response.TransactionId.ToString())).Value;
                Assert.True(receiptResponse.Success);
                Assert.Equal(response.NewContractAddress, receiptResponse.NewContractAddress);
                Assert.Null(receiptResponse.To);
                Assert.Equal(addr.Address, receiptResponse.From);

                string storageRequestResult = (string)((JsonResult)senderSmartContractsController.GetStorage(new GetStorageRequest
                {
                    ContractAddress = response.NewContractAddress.ToString(),
                    StorageKey = "TestSave",
                    DataType = SmartContractDataType.String
                })).Value;
                Assert.Equal("Hello, smart contract world!", storageRequestResult);

                string ownerRequestResult = (string)((JsonResult)senderSmartContractsController.GetStorage(new GetStorageRequest
                {
                    ContractAddress = response.NewContractAddress.ToString(),
                    StorageKey = "Owner",
                    DataType = SmartContractDataType.Address
                })).Value;
                Assert.NotEmpty(ownerRequestResult);

                string counterRequestResult = (string)((JsonResult)senderSmartContractsController.GetStorage(new GetStorageRequest
                {
                    ContractAddress = response.NewContractAddress.ToString(),
                    StorageKey = "Counter",
                    DataType = SmartContractDataType.Int
                })).Value;
                Assert.Equal("12345", counterRequestResult);

                var callRequest = new BuildCallContractTransactionRequest
                {
                    AccountName     = AccountName,
                    GasLimit        = "10000",
                    GasPrice        = "1",
                    Amount          = "0",
                    MethodName      = "Increment",
                    ContractAddress = response.NewContractAddress,
                    FeeAmount       = "0.001",
                    Password        = Password,
                    WalletName      = WalletName,
                    Sender          = addr.Address
                };
                result = (JsonResult)senderSmartContractsController.BuildCallSmartContractTransaction(callRequest);
                var callResponse = (BuildCallContractTransactionResponse)result.Value;

                SmartContractSharedSteps.SendTransaction(scSender, scReceiver, senderWalletController, callResponse.Hex);
                TestHelper.MineBlocks(scReceiver, WalletName, Password, AccountName, 2);
                TestHelper.WaitLoop(() => TestHelper.AreNodesSynced(scReceiver, scSender));


                counterRequestResult = (string)((JsonResult)senderSmartContractsController.GetStorage(new GetStorageRequest
                {
                    ContractAddress = response.NewContractAddress.ToString(),
                    StorageKey = "Counter",
                    DataType = SmartContractDataType.Int
                })).Value;
                Assert.Equal("12346", counterRequestResult);

                // Check receipt was stored and can be retrieved.
                receiptResponse = (ReceiptResponse)((JsonResult)senderSmartContractsController.GetReceipt(callResponse.TransactionId.ToString())).Value;
                Assert.True(receiptResponse.Success);
                Assert.Null(receiptResponse.NewContractAddress);
                Assert.Equal(response.NewContractAddress, receiptResponse.To);
                Assert.Equal(addr.Address, receiptResponse.From);

                // Check wallet history again
                result = (JsonResult)senderWalletController.GetHistory(new WalletHistoryRequest
                {
                    AccountName = AccountName,
                    WalletName  = WalletName
                });
                walletHistoryModel = (WalletHistoryModel)result.Value;
                Assert.Equal(2, walletHistoryModel.AccountsHistoryModel.First().TransactionsHistory.Where(x => x.Type == TransactionItemType.Send).Count());

                // Test serialization
                // TODO: When refactoring integration tests, move this to the one place and test all types, from method param to storage to serialization.

                var serializationRequest = new BuildCallContractTransactionRequest
                {
                    AccountName     = AccountName,
                    GasLimit        = "10000",
                    GasPrice        = "1",
                    Amount          = "0",
                    MethodName      = "TestSerializer",
                    ContractAddress = response.NewContractAddress,
                    FeeAmount       = "0.001",
                    Password        = Password,
                    WalletName      = WalletName,
                    Sender          = addr.Address
                };
                result = (JsonResult)senderSmartContractsController.BuildCallSmartContractTransaction(serializationRequest);
                var serializationResponse = (BuildCallContractTransactionResponse)result.Value;
                SmartContractSharedSteps.SendTransaction(scSender, scReceiver, senderWalletController, serializationResponse.Hex);
                TestHelper.MineBlocks(scReceiver, WalletName, Password, AccountName, 2);
                TestHelper.WaitLoop(() => TestHelper.AreNodesSynced(scReceiver, scSender));

                // Would have only saved if execution completed successfully
                counterRequestResult = (string)((JsonResult)senderSmartContractsController.GetStorage(new GetStorageRequest
                {
                    ContractAddress = response.NewContractAddress.ToString(),
                    StorageKey = "Int32",
                    DataType = SmartContractDataType.Int
                })).Value;
                Assert.Equal("12345", counterRequestResult);
            }
        }
        public void AuctionTest()
        {
            using (NodeBuilder builder = NodeBuilder.Create(this))
            {
                CoreNode scSender   = builder.CreateSmartContractNode();
                CoreNode scReceiver = builder.CreateSmartContractNode();

                builder.StartAll();

                scSender.NotInIBD();
                scReceiver.NotInIBD();

                scSender.FullNode.WalletManager().CreateWallet(Password, WalletName);
                scReceiver.FullNode.WalletManager().CreateWallet(Password, WalletName);
                HdAddress addr = scSender.FullNode.WalletManager().GetUnusedAddress(new WalletAccountReference(WalletName, AccountName));
                Features.Wallet.Wallet wallet = scSender.FullNode.WalletManager().GetWalletByName(WalletName);
                Key key = wallet.GetExtendedPrivateKeyForAddress(Password, addr).PrivateKey;

                scSender.SetDummyMinerSecret(new BitcoinSecret(key, scSender.FullNode.Network));
                scReceiver.SetDummyMinerSecret(new BitcoinSecret(key, scReceiver.FullNode.Network));

                var maturity = (int)scSender.FullNode.Network.Consensus.CoinbaseMaturity;
                scSender.GenerateStratisWithMiner(maturity + 5);

                TestHelper.WaitLoop(() => TestHelper.IsNodeSynced(scSender));
                var total = scSender.FullNode.WalletManager().GetSpendableTransactionsInWallet(WalletName).Sum(s => s.Transaction.Amount);
                Assert.Equal(Money.COIN * (maturity + 5) * 50, total);

                SmartContractsController       senderSmartContractsController = scSender.FullNode.NodeService <SmartContractsController>();
                WalletController               senderWalletController         = scSender.FullNode.NodeService <WalletController>();
                SmartContractCompilationResult compilationResult = SmartContractCompiler.CompileFile("SmartContracts/Auction.cs");
                Assert.True(compilationResult.Success);

                var buildRequest = new BuildCreateContractTransactionRequest
                {
                    AccountName  = AccountName,
                    GasLimit     = "10000",
                    GasPrice     = "1",
                    ContractCode = compilationResult.Compilation.ToHexString(),
                    FeeAmount    = "0.001",
                    Password     = Password,
                    WalletName   = WalletName,
                    Sender       = addr.Address,
                    Parameters   = new string[] { "10#20" }
                };

                JsonResult result   = (JsonResult)senderSmartContractsController.BuildCreateSmartContractTransaction(buildRequest);
                var        response = (BuildCreateContractTransactionResponse)result.Value;
                scSender.CreateRPCClient().AddNode(scReceiver.Endpoint, true);

                SmartContractSharedSteps.SendTransactionAndMine(scSender, scReceiver, senderWalletController, response.Hex);

                // Contract deployed.
                ContractStateRepositoryRoot senderState = scSender.FullNode.NodeService <ContractStateRepositoryRoot>();
                string  contractAddress        = response.NewContractAddress.ToString();
                uint160 contractAddressUint160 = new Address(contractAddress).ToUint160(scSender.FullNode.Network);
                Assert.NotNull(senderState.GetCode(contractAddressUint160));

                var callRequest = new BuildCallContractTransactionRequest
                {
                    AccountName     = AccountName,
                    GasLimit        = "10000",
                    GasPrice        = "1",
                    Amount          = "2",
                    MethodName      = "Bid",
                    ContractAddress = response.NewContractAddress,
                    FeeAmount       = "0.001",
                    Password        = Password,
                    WalletName      = WalletName,
                    Sender          = addr.Address
                };
                result = (JsonResult)senderSmartContractsController.BuildCallSmartContractTransaction(callRequest);
                var callResponse = (BuildCallContractTransactionResponse)result.Value;

                SmartContractSharedSteps.SendTransactionAndMine(scSender, scReceiver, senderWalletController, callResponse.Hex);

                // Here, test that Sender and HighestBidder are the same.
                var ownerBytes         = senderState.GetStorageValue(contractAddressUint160, Encoding.UTF8.GetBytes("Owner"));
                var highestBidderBytes = senderState.GetStorageValue(contractAddressUint160, Encoding.UTF8.GetBytes("HighestBidder"));
                Assert.Equal(new uint160(ownerBytes), new uint160(highestBidderBytes));
                var   hasEndedBytes = senderState.GetStorageValue(contractAddressUint160, Encoding.UTF8.GetBytes("HasEnded"));
                var   endBlockBytes = senderState.GetStorageValue(contractAddressUint160, Encoding.UTF8.GetBytes("EndBlock"));
                bool  hasEnded      = BitConverter.ToBoolean(hasEndedBytes, 0);
                ulong endBlock      = BitConverter.ToUInt64(endBlockBytes, 0);

                // Wait 20 blocks to end auction
                scReceiver.GenerateStratisWithMiner(20);
                TestHelper.WaitLoop(() => TestHelper.AreNodesSynced(scReceiver, scSender));

                var endAuctionRequest = new BuildCallContractTransactionRequest
                {
                    AccountName     = AccountName,
                    GasLimit        = "10000",
                    GasPrice        = "1",
                    Amount          = "0",
                    MethodName      = "AuctionEnd",
                    ContractAddress = response.NewContractAddress,
                    FeeAmount       = "0.001",
                    Password        = Password,
                    WalletName      = WalletName,
                    Sender          = addr.Address
                };

                var endAuctionResult   = (JsonResult)senderSmartContractsController.BuildCallSmartContractTransaction(endAuctionRequest);
                var endAuctionResponse = (BuildCallContractTransactionResponse)endAuctionResult.Value;

                SmartContractSharedSteps.SendTransactionAndMine(scSender, scReceiver, senderWalletController, endAuctionResponse.Hex);

                // Check that transaction did in fact go through with condensing tx as well
                var blockStoreCache = scSender.FullNode.NodeService <IBlockStoreCache>();
                var secondLastBlock = blockStoreCache.GetBlockAsync(scSender.FullNode.Chain.Tip.Previous.HashBlock).Result;
                Assert.Equal(3, secondLastBlock.Transactions.Count);
            }
        }