public void MockChain_AuctionTest() { using (MockChain chain = new MockChain(2)) { MockChainNode sender = chain.Nodes[0]; MockChainNode receiver = chain.Nodes[1]; sender.MineBlocks(10); SmartContractCompilationResult compilationResult = SmartContractCompiler.CompileFile("SmartContracts/Auction.cs"); Assert.True(compilationResult.Success); // Create contract and ensure code exists BuildCreateContractTransactionResponse response = sender.SendCreateContractTransaction(compilationResult.Compilation, new string[] { "10#20" }); receiver.WaitMempoolCount(1); receiver.MineBlocks(2); Assert.NotNull(receiver.GetCode(response.NewContractAddress)); Assert.NotNull(sender.GetCode(response.NewContractAddress)); // Call contract and ensure owner is now highest bidder BuildCallContractTransactionResponse callResponse = sender.SendCallContractTransaction("Bid", response.NewContractAddress, 2); receiver.WaitMempoolCount(1); receiver.MineBlocks(2); Assert.Equal(sender.GetStorageValue(response.NewContractAddress, "Owner"), sender.GetStorageValue(response.NewContractAddress, "HighestBidder")); // Wait 20 blocks and end auction and check for transaction to victor sender.MineBlocks(20); sender.SendCallContractTransaction("AuctionEnd", response.NewContractAddress, 0); sender.WaitMempoolCount(1); sender.MineBlocks(1); NBitcoin.Block block = sender.GetLastBlock(); Assert.Equal(3, block.Transactions.Count); } }
public void Create_WithFunds() { using (MockChain chain = new MockChain(2)) { MockChainNode sender = chain.Nodes[0]; MockChainNode receiver = chain.Nodes[1]; // Mine some coins so we have balance int maturity = (int)chain.Network.Consensus.CoinbaseMaturity; TestHelper.MineBlocks(sender.CoreNode, sender.WalletName, sender.Password, sender.AccountName, maturity + 1); int spendable = GetSpendableBlocks(maturity + 1, maturity); Assert.Equal(Money.COIN * spendable * 50, (long)sender.WalletSpendableBalance); // Compile file SmartContractCompilationResult compilationResult = SmartContractCompiler.CompileFile("SmartContracts/StorageDemo.cs"); Assert.True(compilationResult.Success); // Send create with value, and ensure balance is stored. BuildCreateContractTransactionResponse sendResponse = sender.SendCreateContractTransaction(compilationResult.Compilation, 30); sender.WaitMempoolCount(1); TestHelper.MineBlocks(sender.CoreNode, sender.WalletName, sender.Password, sender.AccountName, 1); Assert.Equal((ulong)30 * 100_000_000, sender.GetContractBalance(sendResponse.NewContractAddress)); } }
public void SendAndReceiveCorrectly() { using (MockChain chain = new MockChain(2)) { MockChainNode scSender = chain.Nodes[0]; MockChainNode scReceiver = chain.Nodes[1]; // Mining adds coins to wallet. var maturity = (int)chain.Network.Consensus.CoinbaseMaturity; scSender.MineBlocks(maturity + 5); int spendable = GetSpendableBlocks(maturity + 5, maturity); Assert.Equal(Money.COIN * spendable * 50, (long)scSender.WalletSpendableBalance); // Send coins to receiver. HdAddress address = scReceiver.GetUnusedAddress(); scSender.SendTransaction(address.ScriptPubKey, Money.COIN * 100); scReceiver.WaitMempoolCount(1); Assert.Equal(Money.COIN * 100, (long)scReceiver.WalletSpendableBalance); // Balance is added (unconfirmed) // Transaction is in chain in last block. scReceiver.MineBlocks(1); var lastBlock = scReceiver.GetLastBlock(); Assert.Equal(scReceiver.SpendableTransactions.First().Transaction.BlockHash, lastBlock.GetHash()); } }
public void Test_CatCreation() { using (MockChain chain = new MockChain(2)) { MockChainNode sender = chain.Nodes[0]; MockChainNode receiver = chain.Nodes[1]; TestHelper.MineBlocks(sender.CoreNode, sender.WalletName, sender.Password, sender.AccountName, 1); SmartContractCompilationResult compilationResult = SmartContractCompiler.CompileFile("SmartContracts/ContractCreation.cs"); Assert.True(compilationResult.Success); // Create contract and ensure code exists BuildCreateContractTransactionResponse response = sender.SendCreateContractTransaction(compilationResult.Compilation, 0); receiver.WaitMempoolCount(1); TestHelper.MineBlocks(receiver.CoreNode, receiver.WalletName, receiver.Password, receiver.AccountName, 2); Assert.NotNull(receiver.GetCode(response.NewContractAddress)); Assert.NotNull(sender.GetCode(response.NewContractAddress)); // Call contract and ensure internal contract was created. BuildCallContractTransactionResponse callResponse = sender.SendCallContractTransaction("CreateCat", response.NewContractAddress, 0); receiver.WaitMempoolCount(1); TestHelper.MineBlocks(receiver.CoreNode, receiver.WalletName, receiver.Password, receiver.AccountName, 1); chain.WaitForAllNodesToSync(); Assert.Equal(1, BitConverter.ToInt32(sender.GetStorageValue(response.NewContractAddress, "CatCounter"))); uint160 lastCreatedCatAddress = new uint160(sender.GetStorageValue(response.NewContractAddress, "LastCreatedCat")); uint160 expectedCreatedCatAddress = this.addressGenerator.GenerateAddress(callResponse.TransactionId, 0); Assert.Equal(expectedCreatedCatAddress, lastCreatedCatAddress); // Test that the contract address, event name, and logging values are available in the bloom, from internal create. var scBlockHeader = receiver.GetLastBlock().Header as SmartContractBlockHeader; Assert.True(scBlockHeader.LogsBloom.Test(lastCreatedCatAddress.ToBytes())); Assert.True(scBlockHeader.LogsBloom.Test(Encoding.UTF8.GetBytes("CatCreated"))); Assert.True(scBlockHeader.LogsBloom.Test(BitConverter.GetBytes(0))); // And sanity test that a random value is not available in bloom. Assert.False(scBlockHeader.LogsBloom.Test(Encoding.UTF8.GetBytes("RandomValue"))); // Do a create that should transfer all funds sent now. const double amount = 20; BuildCallContractTransactionResponse callResponse2 = sender.SendCallContractTransaction("CreateCatWithFunds", response.NewContractAddress, amount); receiver.WaitMempoolCount(1); TestHelper.MineBlocks(receiver.CoreNode, receiver.WalletName, receiver.Password, receiver.AccountName, 1); // Check created contract has expected balance. lastCreatedCatAddress = new uint160(sender.GetStorageValue(response.NewContractAddress, "LastCreatedCat")); Assert.Equal(amount * Money.COIN, sender.GetContractBalance(lastCreatedCatAddress.ToAddress(chain.Network))); // Check block has 3 transactions. Coinbase, our tx, and then a condensing tx. var block = receiver.GetLastBlock(); Assert.Equal(3, block.Transactions.Count); // Condensing tx has 1 input and 1 output - FROM: real tx. TO: new contract address. Assert.Single(block.Transactions[2].Inputs); Assert.Single(block.Transactions[2].Outputs); Assert.Equal(block.Transactions[1].GetHash(), block.Transactions[2].Inputs[0].PrevOut.Hash); // References tx above. Assert.Equal(amount * Money.COIN, (ulong)block.Transactions[2].Outputs[0].Value); Assert.True(block.Transactions[2].Inputs[0].ScriptSig.IsSmartContractSpend()); Assert.True(block.Transactions[2].Outputs[0].ScriptPubKey.IsSmartContractInternalCall()); } }
public void MockChain_AuctionTest() { var network = new SmartContractsRegTest(); // ew hack. TODO: Expose from MockChain or MockChainNode. using (MockChain chain = new MockChain(2)) { MockChainNode sender = chain.Nodes[0]; MockChainNode receiver = chain.Nodes[1]; TestHelper.MineBlocks(sender.CoreNode, sender.WalletName, sender.Password, sender.AccountName, 1); SmartContractCompilationResult compilationResult = SmartContractCompiler.CompileFile("SmartContracts/Auction.cs"); Assert.True(compilationResult.Success); // Create contract and ensure code exists BuildCreateContractTransactionResponse response = sender.SendCreateContractTransaction(compilationResult.Compilation, 0, new string[] { "10#20" }); receiver.WaitMempoolCount(1); receiver.MineBlocks(1); Assert.NotNull(receiver.GetCode(response.NewContractAddress)); Assert.NotNull(sender.GetCode(response.NewContractAddress)); // Test that the contract address, event name, and logging values are available in the bloom. var scBlockHeader = receiver.GetLastBlock().Header as SmartContractBlockHeader; Assert.True(scBlockHeader.LogsBloom.Test(new Address(response.NewContractAddress).ToUint160(network).ToBytes())); Assert.True(scBlockHeader.LogsBloom.Test(Encoding.UTF8.GetBytes("Created"))); Assert.True(scBlockHeader.LogsBloom.Test(BitConverter.GetBytes((ulong)20))); // And sanity test that a non-indexed field and random value is not available in bloom. Assert.False(scBlockHeader.LogsBloom.Test(Encoding.UTF8.GetBytes(sender.MinerAddress.Address))); Assert.False(scBlockHeader.LogsBloom.Test(Encoding.UTF8.GetBytes("RandomValue"))); // Test that the event can be searched for... var receiptsFromSearch = sender.GetReceipts(response.NewContractAddress, "Created"); Assert.Single(receiptsFromSearch); // Call contract and ensure owner is now highest bidder BuildCallContractTransactionResponse callResponse = sender.SendCallContractTransaction("Bid", response.NewContractAddress, 2); receiver.WaitMempoolCount(1); TestHelper.MineBlocks(receiver.CoreNode, receiver.WalletName, receiver.Password, receiver.AccountName, 1); Assert.Equal(sender.GetStorageValue(response.NewContractAddress, "Owner"), sender.GetStorageValue(response.NewContractAddress, "HighestBidder")); // Wait 20 blocks and end auction and check for transaction to victor TestHelper.MineBlocks(sender.CoreNode, sender.WalletName, sender.Password, sender.AccountName, 20); sender.SendCallContractTransaction("AuctionEnd", response.NewContractAddress, 0); sender.WaitMempoolCount(1); TestHelper.MineBlocks(sender.CoreNode, sender.WalletName, sender.Password, sender.AccountName, 1); NBitcoin.Block block = sender.GetLastBlock(); Assert.Equal(3, block.Transactions.Count); } }
private void Test(int blockHeight, int txIndex, int txCount, int txOutIndex, int txOutCount) { var repo = new NoSqlBlockRepository(); var chain = new MockChain(); var block = new Block(); Transaction relevantTx = null; for (int i = 0; i < txCount; i++) { var tx = block.AddTransaction(new Transaction()); if (i == txIndex) { relevantTx = tx; for (int ii = 0; ii < txOutCount; ii++) { var txout = tx.AddOutput(new TxOut()); if (ii == txOutIndex) { txout.Value = Money.Coins(1.0m); } } } } block.UpdateMerkleRoot(); chain.Return(block.Header, blockHeight); repo.PutAsync(block).Wait(); var address = MnemonicReference.CreateAsync(chain, repo, blockHeight, txIndex, txOutIndex).Result; var address2 = MnemonicReference.ParseAsync(chain, repo, Wordlist.English, address.ToString()).Result; Assert.Equal(address.ToString(), address2.ToString()); Assert.Equal(Money.Coins(1.0m), address.Output.Value); Assert.Equal(Money.Coins(1.0m), address2.Output.Value); var merkleBlock = block.Filter(relevantTx.GetHash()); var address3 = MnemonicReference.Parse(chain, Wordlist.English, address.ToString(), relevantTx, merkleBlock); Assert.Equal(address.ToString(), address3.ToString()); }
public void Test_CatCreation() { using (MockChain chain = new MockChain(2)) { MockChainNode sender = chain.Nodes[0]; MockChainNode receiver = chain.Nodes[1]; sender.MineBlocks(10); SmartContractCompilationResult compilationResult = SmartContractCompiler.CompileFile("SmartContracts/ContractCreation.cs"); Assert.True(compilationResult.Success); // Create contract and ensure code exists BuildCreateContractTransactionResponse response = sender.SendCreateContractTransaction(compilationResult.Compilation); receiver.WaitMempoolCount(1); receiver.MineBlocks(2); Assert.NotNull(receiver.GetCode(response.NewContractAddress)); Assert.NotNull(sender.GetCode(response.NewContractAddress)); // Call contract and ensure internal contract was created. BuildCallContractTransactionResponse callResponse = sender.SendCallContractTransaction("CreateCat", response.NewContractAddress, 0); receiver.WaitMempoolCount(1); receiver.MineBlocks(1); Assert.Equal(1, BitConverter.ToInt32(sender.GetStorageValue(response.NewContractAddress, "CatCounter"))); uint160 lastCreatedCatAddress = new uint160(sender.GetStorageValue(response.NewContractAddress, "LastCreatedCat")); uint160 expectedCreatedCatAddress = this.addressGenerator.GenerateAddress(callResponse.TransactionId, 0); Assert.Equal(expectedCreatedCatAddress, lastCreatedCatAddress); // Test that the contract address, event name, and logging values are available in the bloom, from internal create. var scBlockHeader = receiver.GetLastBlock().Header as SmartContractBlockHeader; Assert.True(scBlockHeader.LogsBloom.Test(lastCreatedCatAddress.ToBytes())); Assert.True(scBlockHeader.LogsBloom.Test(Encoding.UTF8.GetBytes("CatCreated"))); Assert.True(scBlockHeader.LogsBloom.Test(BitConverter.GetBytes(0))); // And sanity test that a random value is not available in bloom. Assert.False(scBlockHeader.LogsBloom.Test(Encoding.UTF8.GetBytes("RandomValue"))); } }
private void Test(int blockHeight, int txIndex, int txCount, int txOutIndex, int txOutCount) { var repo = new NoSqlBlockRepository(); var chain = new MockChain(); var block = new Block(); Transaction relevantTx = null; for(int i = 0 ; i < txCount ; i++) { var tx = block.AddTransaction(new Transaction()); if(i == txIndex) { relevantTx = tx; for(int ii = 0 ; ii < txOutCount ; ii++) { var txout = tx.AddOutput(new TxOut()); if(ii == txOutIndex) txout.Value = Money.Coins(1.0m); } } } block.UpdateMerkleRoot(); chain.Return(block.Header, blockHeight); repo.PutAsync(block).Wait(); var address = MnemonicReference.CreateAsync(chain, repo, blockHeight, txIndex, txOutIndex).Result; var address2 = MnemonicReference.ParseAsync(chain, repo, Wordlist.English, address.ToString()).Result; Assert.Equal(address.ToString(), address2.ToString()); Assert.Equal(Money.Coins(1.0m), address.Output.Value); Assert.Equal(Money.Coins(1.0m), address2.Output.Value); var merkleBlock = block.Filter(relevantTx.GetHash()); var address3 = MnemonicReference.Parse(chain, Wordlist.English, address.ToString(), relevantTx, merkleBlock); Assert.Equal(address.ToString(), address3.ToString()); }