Exemplo n.º 1
0
 public SmartContractBlockDefinition(
     ICoinView coinView,
     IConsensusLoop consensusLoop,
     IDateTimeProvider dateTimeProvider,
     ISmartContractExecutorFactory executorFactory,
     ILoggerFactory loggerFactory,
     ITxMempool mempool,
     MempoolSchedulerLock mempoolLock,
     MinerSettings minerSettings,
     Network network,
     ContractStateRepositoryRoot stateRoot)
     : base(consensusLoop, dateTimeProvider, loggerFactory, mempool, mempoolLock, minerSettings, network)
 {
     this.coinView        = coinView;
     this.executorFactory = executorFactory;
     this.logger          = loggerFactory.CreateLogger(this.GetType());
     this.stateRoot       = stateRoot;
 }
        public void VM_CreateContract_WithParameters()
        {
            //Get the contract execution code------------------------
            SmartContractCompilationResult compilationResult =
                SmartContractCompiler.CompileFile("SmartContracts/Auction.cs");

            Assert.True(compilationResult.Success);
            byte[] contractExecutionCode = compilationResult.Compilation;
            //-------------------------------------------------------

            //Set the calldata for the transaction----------
            var methodParameters = new object[] { (ulong)5 };
            var callData         = new CreateData((Gas)5000000, contractExecutionCode, methodParameters);

            Money value = Money.Zero;
            //-------------------------------------------------------

            var repository = new ContractStateRepositoryRoot(new NoDeleteSource <byte[], byte[]>(new MemoryDictionarySource()));
            IContractStateRepository track = repository.StartTracking();

            var gasMeter = new GasMeter(callData.GasLimit);

            var transactionContext = new TransactionContext(
                txHash: uint256.One,
                blockHeight: 1,
                coinbase: TestAddress.ToUint160(this.network),
                sender: TestAddress.ToUint160(this.network),
                amount: value
                );

            VmExecutionResult result = this.vm.Create(gasMeter,
                                                      repository,
                                                      callData,
                                                      transactionContext);

            track.Commit();

            var endBlockValue = track.GetStorageValue(result.NewContractAddress,
                                                      Encoding.UTF8.GetBytes("EndBlock"));

            Assert.Equal(6, BitConverter.ToInt16(endBlockValue, 0));
            Assert.Equal(TestAddress.ToUint160(this.network).ToBytes(), track.GetStorageValue(result.NewContractAddress, Encoding.UTF8.GetBytes("Owner")));
        }
 public SmartContractConsensusRules(
     ConcurrentChain chain,
     ICheckpoints checkpoints,
     ConsensusSettings consensusSettings,
     IDateTimeProvider dateTimeProvider,
     ISmartContractExecutorFactory executorFactory,
     ILoggerFactory loggerFactory,
     Network network,
     NodeDeployments nodeDeployments,
     ContractStateRepositoryRoot originalStateRoot,
     ILookaheadBlockPuller puller,
     ICoinView utxoSet,
     ISmartContractReceiptStorage receiptStorage)
     : base(network, loggerFactory, dateTimeProvider, chain, nodeDeployments, consensusSettings, checkpoints, utxoSet, puller)
 {
     this.ExecutorFactory   = executorFactory;
     this.OriginalStateRoot = originalStateRoot;
     this.ReceiptStorage    = receiptStorage;
 }
        public void VM_ExecuteContract_WithParameters()
        {
            //Get the contract execution code------------------------
            SmartContractCompilationResult compilationResult = SmartContractCompiler.CompileFile("SmartContracts/StorageTestWithParameters.cs");

            Assert.True(compilationResult.Success);

            byte[] contractExecutionCode = compilationResult.Compilation;
            //-------------------------------------------------------

            //Set the calldata for the transaction----------
            var   methodParameters = new object[] { (short)5 };
            var   callData         = new CallData((Gas)5000000, new uint160(1), "StoreData", methodParameters);
            Money value            = Money.Zero;
            //-------------------------------------------------------

            var repository = new ContractStateRepositoryRoot(new NoDeleteSource <byte[], byte[]>(new MemoryDictionarySource()));
            IContractStateRepository track = repository.StartTracking();

            var gasMeter = new GasMeter(callData.GasLimit);

            var internalTxExecutorFactory =
                new InternalTransactionExecutorFactory(this.keyEncodingStrategy, this.loggerFactory, this.network);
            var vm = new ReflectionVirtualMachine(this.validator, internalTxExecutorFactory, this.loggerFactory, this.network, this.addressGenerator);

            uint160 address = TestAddress.ToUint160(this.network);

            var transactionContext = new TransactionContext(uint256.One, 1, address, address, value);

            repository.SetCode(callData.ContractAddress, contractExecutionCode);
            repository.SetContractType(callData.ContractAddress, "StorageTestWithParameters");

            VmExecutionResult result = vm.ExecuteMethod(gasMeter,
                                                        repository,
                                                        callData,
                                                        transactionContext);

            track.Commit();

            Assert.Equal(5, BitConverter.ToInt16(track.GetStorageValue(callData.ContractAddress, Encoding.UTF8.GetBytes("orders")), 0));
            Assert.Equal(5, BitConverter.ToInt16(repository.GetStorageValue(callData.ContractAddress, Encoding.UTF8.GetBytes("orders")), 0));
        }
 public SmartContractsController(
     IBroadcasterManager broadcasterManager,
     IConsensusLoop consensus,
     IDateTimeProvider dateTimeProvider,
     ILoggerFactory loggerFactory,
     Network network,
     ISmartContractReceiptStorage receiptStorage,
     ContractStateRepositoryRoot stateRoot,
     IWalletManager walletManager,
     IWalletTransactionHandler walletTransactionHandler)
 {
     this.receiptStorage           = receiptStorage;
     this.stateRoot                = stateRoot;
     this.walletTransactionHandler = walletTransactionHandler;
     this.logger             = loggerFactory.CreateLogger(this.GetType().FullName);
     this.network            = network;
     this.coinType           = (CoinType)network.Consensus.CoinType;
     this.walletManager      = walletManager;
     this.broadcasterManager = broadcasterManager;
 }
        public void SmartContractList_ListHasCountTest()
        {
            var listName = "testList";

            var source = new MemoryDictionarySource();
            var root   = new ContractStateRepositoryRoot(source);

            IContractStateRepository state = root.StartTracking();
            IPersistenceStrategy     persistenceStrategy = new PersistenceStrategy(state);

            var persistentState = new PersistentState(
                persistenceStrategy,
                uint160.One,
                this.network);

            var list = new SmartContractList <string>(persistentState, listName);

            Assert.Equal((uint)0, list.Count);
            list.Add("Test");
            Assert.Equal((uint)1, list.Count);
        }
        public void SmartContractList_ListHasMultipleValuesTest()
        {
            var listName = "testList";

            var source = new MemoryDictionarySource();
            var root   = new ContractStateRepositoryRoot(source);

            IContractStateRepository state = root.StartTracking();
            IPersistenceStrategy     persistenceStrategy = new PersistenceStrategy(state);

            var persistentState = new PersistentState(
                persistenceStrategy,
                uint160.One,
                this.network);

            var list = new SmartContractList <string>(persistentState, listName);

            Assert.Equal((uint)0, list.Count);

            var testItem  = "Test";
            var testItem2 = "Test2";
            var testItem3 = "Test3";

            // Set a value in the list
            list.Add(testItem);
            list.Add(testItem2);
            list.Add(testItem3);

            Assert.Equal((uint)3, list.Count);

            var item1 = list.GetValue(0);
            var item2 = list.GetValue(1);
            var item3 = list.GetValue(2);

            Assert.Equal(testItem, item1);
            Assert.Equal(testItem2, item2);
            Assert.Equal(testItem3, item3);
        }
        public void SmartContractList_ListEnumerationTest()
        {
            var listName = "testList";

            var source = new MemoryDictionarySource();
            var root   = new ContractStateRepositoryRoot(source);

            IContractStateRepository state = root.StartTracking();
            IPersistenceStrategy     persistenceStrategy = new PersistenceStrategy(state);
            var persistentState = new PersistentState(
                persistenceStrategy,
                uint160.One,
                this.network);

            var list = new SmartContractList <string>(persistentState, listName);

            Assert.Equal((uint)0, list.Count);

            var items = new List <string>
            {
                "this is a test",
                "we should try to find a way",
                "to paramaterize our tests"
            };

            foreach (var item in items)
            {
                // No AddRange
                list.Add(item);
            }

            Assert.Equal((uint)items.Count, list.Count);

            for (var i = 0; i < list.Count; i++)
            {
                Assert.Equal(items[i], list.GetValue((uint)i));
            }
        }
        public void VM_ExecuteContract_WithoutParameters()
        {
            //Get the contract execution code------------------------
            SmartContractCompilationResult compilationResult = SmartContractCompiler.CompileFile("SmartContracts/StorageTest.cs");

            Assert.True(compilationResult.Success);

            byte[] contractExecutionCode = compilationResult.Compilation;
            //-------------------------------------------------------

            //Set the calldata for the transaction----------
            var callData = new CallData((Gas)5000000, new uint160(1), "StoreData");

            Money value = Money.Zero;
            //-------------------------------------------------------

            var repository = new ContractStateRepositoryRoot(new NoDeleteSource <byte[], byte[]>(new MemoryDictionarySource()));
            IContractStateRepository stateRepository = repository.StartTracking();

            var gasMeter = new GasMeter(callData.GasLimit);

            uint160 address = TestAddress.ToUint160(this.network);

            var transactionContext = new TransactionContext(uint256.One, 1, address, address, 0);

            repository.SetCode(callData.ContractAddress, contractExecutionCode);
            repository.SetContractType(callData.ContractAddress, "StorageTest");

            VmExecutionResult result = this.vm.ExecuteMethod(gasMeter,
                                                             repository,
                                                             callData,
                                                             transactionContext);

            stateRepository.Commit();

            Assert.Equal(Encoding.UTF8.GetBytes("TestValue"), stateRepository.GetStorageValue(callData.ContractAddress, Encoding.UTF8.GetBytes("TestKey")));
            Assert.Equal(Encoding.UTF8.GetBytes("TestValue"), repository.GetStorageValue(callData.ContractAddress, Encoding.UTF8.GetBytes("TestKey")));
        }
        public void ReflectionVirtualMachineFeature_OnInitialize_RulesAdded()
        {
            Network network = KnownNetworks.StratisRegTest;

            var chain           = new ConcurrentChain(network);
            var contractState   = new ContractStateRepositoryRoot();
            var executorFactory = new Mock <ISmartContractExecutorFactory>();
            var loggerFactory   = new ExtendedLoggerFactory();

            var consensusRules = new SmartContractPowConsensusRuleEngine(
                chain, new Mock <ICheckpoints>().Object, new Configuration.Settings.ConsensusSettings(),
                DateTimeProvider.Default, executorFactory.Object, loggerFactory, network,
                new Base.Deployments.NodeDeployments(network, chain), contractState,
                new Mock <ILookaheadBlockPuller>().Object,
                new Mock <IReceiptRepository>().Object,
                new Mock <ICoinView>().Object);

            var feature = new ReflectionVirtualMachineFeature(loggerFactory, network);

            feature.Initialize();

            Assert.Single(network.Consensus.Rules.Where(r => r.GetType() == typeof(SmartContractFormatRule)));
        }
Exemplo n.º 11
0
        /// <inheritdoc/>
        public override BlockTemplate Build(ChainedHeader chainTip, Script scriptPubKeyIn)
        {
            this.logger.LogTrace("()");

            GetSenderUtil.GetSenderResult getSenderResult = GetSenderUtil.GetAddressFromScript(scriptPubKeyIn);
            if (!getSenderResult.Success)
            {
                throw new ConsensusErrorException(new ConsensusError("sc-block-assembler-createnewblock", getSenderResult.Error));
            }

            this.coinbaseAddress = getSenderResult.Sender;

            this.stateSnapshot = this.stateRoot.GetSnapshotTo(((SmartContractBlockHeader)this.ConsensusLoop.Tip.Header).HashStateRoot.ToBytes());

            this.refundOutputs.Clear();

            base.OnBuild(chainTip, scriptPubKeyIn);

            this.coinbase.Outputs.AddRange(this.refundOutputs);

            this.logger.LogTrace("(-)");

            return(this.BlockTemplate);
        }
 public SmartContractFeature(IConsensusLoop consensusLoop, ILoggerFactory loggerFactory, ContractStateRepositoryRoot stateRoot)
 {
     this.logger        = loggerFactory.CreateLogger(this.GetType().FullName);
     this.stateRoot     = stateRoot;
     this.consensusLoop = consensusLoop;
 }
Exemplo n.º 13
0
        public void SendAndReceiveSmartContractTransactions()
        {
            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));
                var maturity = (int)scSender.FullNode.Network.Consensus.CoinbaseMaturity;
                scSender.GenerateStratisWithMiner(maturity + 5);

                // Wait for block repo for block sync to work.
                TestHelper.WaitLoop(() => TestHelper.IsNodeSynced(scSender));

                // The mining should add coins to the wallet.
                var total = scSender.FullNode.WalletManager().GetSpendableTransactionsInWallet(WalletName).Sum(s => s.Transaction.Amount);
                Assert.Equal(Money.COIN * (maturity + 5) * 50, total);

                // Create a token contract
                ulong gasPrice  = 1;
                int   vmVersion = 1;
                Gas   gasLimit  = (Gas)2000;
                SmartContractCompilationResult compilationResult = SmartContractCompiler.CompileFile("SmartContracts/TransferTest.cs");
                Assert.True(compilationResult.Success);

                var contractCarrier = SmartContractCarrier.CreateContract(vmVersion, compilationResult.Compilation, gasPrice, gasLimit);

                var contractCreateScript = new Script(contractCarrier.Serialize());
                var txBuildContext       = new TransactionBuildContext(scSender.FullNode.Network)
                {
                    AccountReference = new WalletAccountReference(WalletName, AccountName),
                    MinConfirmations = maturity,
                    FeeType          = FeeType.High,
                    WalletPassword   = Password,
                    Recipients       = new[] { new Recipient {
                                                   Amount = 0, ScriptPubKey = contractCreateScript
                                               } }.ToList()
                };

                Transaction transferContractTransaction = (scSender.FullNode.NodeService <IWalletTransactionHandler>() as SmartContractWalletTransactionHandler).BuildTransaction(txBuildContext);

                // Broadcast the token transaction to the network
                scSender.FullNode.NodeService <IBroadcasterManager>().BroadcastTransactionAsync(transferContractTransaction);

                // Wait for the token transaction to be picked up by the mempool
                TestHelper.WaitLoop(() => scSender.CreateRPCClient().GetRawMempool().Length > 0);

                // Mine the token transaction and wait for it sync
                scSender.GenerateStratisWithMiner(1);
                TestHelper.WaitLoop(() => TestHelper.IsNodeSynced(scSender));

                // Sync to the receiver node
                scSender.CreateRPCClient().AddNode(scReceiver.Endpoint, true);
                TestHelper.WaitLoop(() => TestHelper.AreNodesSynced(scReceiver, scSender));

                // Ensure that boths nodes has the contract
                ContractStateRepositoryRoot senderState      = scSender.FullNode.NodeService <ContractStateRepositoryRoot>();
                ContractStateRepositoryRoot receiverState    = scReceiver.FullNode.NodeService <ContractStateRepositoryRoot>();
                IAddressGenerator           addressGenerator = scSender.FullNode.NodeService <IAddressGenerator>();

                uint160 tokenContractAddress = addressGenerator.GenerateAddress(transferContractTransaction.GetHash(), 0);
                Assert.NotNull(senderState.GetCode(tokenContractAddress));
                Assert.NotNull(receiverState.GetCode(tokenContractAddress));
                scSender.FullNode.MempoolManager().Clear();

                // Create a transfer token contract
                compilationResult = SmartContractCompiler.CompileFile("SmartContracts/TransferTest.cs");
                Assert.True(compilationResult.Success);
                contractCarrier      = SmartContractCarrier.CreateContract(vmVersion, compilationResult.Compilation, gasPrice, gasLimit);
                contractCreateScript = new Script(contractCarrier.Serialize());
                txBuildContext       = new TransactionBuildContext(scSender.FullNode.Network)
                {
                    AccountReference = new WalletAccountReference(WalletName, AccountName),
                    MinConfirmations = maturity,
                    FeeType          = FeeType.High,
                    WalletPassword   = Password,
                    Recipients       = new[] { new Recipient {
                                                   Amount = 0, ScriptPubKey = contractCreateScript
                                               } }.ToList()
                };

                // Broadcast the token transaction to the network
                transferContractTransaction = (scSender.FullNode.NodeService <IWalletTransactionHandler>() as SmartContractWalletTransactionHandler).BuildTransaction(txBuildContext);
                scSender.FullNode.NodeService <IBroadcasterManager>().BroadcastTransactionAsync(transferContractTransaction);

                // Wait for the token transaction to be picked up by the mempool
                TestHelper.WaitLoop(() => scSender.CreateRPCClient().GetRawMempool().Length > 0);
                scSender.GenerateStratisWithMiner(1);

                // Ensure the node is synced
                TestHelper.WaitLoop(() => TestHelper.IsNodeSynced(scSender));

                // Ensure both nodes are synced with each other
                TestHelper.WaitLoop(() => TestHelper.AreNodesSynced(scReceiver, scSender));

                // Ensure that boths nodes has the contract
                senderState          = scSender.FullNode.NodeService <ContractStateRepositoryRoot>();
                receiverState        = scReceiver.FullNode.NodeService <ContractStateRepositoryRoot>();
                tokenContractAddress = addressGenerator.GenerateAddress(transferContractTransaction.GetHash(), 0);
                Assert.NotNull(senderState.GetCode(tokenContractAddress));
                Assert.NotNull(receiverState.GetCode(tokenContractAddress));
                scSender.FullNode.MempoolManager().Clear();

                // Create a call contract transaction which will transfer funds
                contractCarrier = SmartContractCarrier.CallContract(1, tokenContractAddress, "Test", gasPrice, gasLimit);
                Script contractCallScript = new Script(contractCarrier.Serialize());
                txBuildContext = new TransactionBuildContext(scSender.FullNode.Network)
                {
                    AccountReference = new WalletAccountReference(WalletName, AccountName),
                    MinConfirmations = maturity,
                    FeeType          = FeeType.High,
                    WalletPassword   = Password,
                    Recipients       = new[] { new Recipient {
                                                   Amount = 1000, ScriptPubKey = contractCallScript
                                               } }.ToList()
                };

                // Broadcast the token transaction to the network
                transferContractTransaction = (scSender.FullNode.NodeService <IWalletTransactionHandler>() as SmartContractWalletTransactionHandler).BuildTransaction(txBuildContext);
                scSender.FullNode.NodeService <IBroadcasterManager>().BroadcastTransactionAsync(transferContractTransaction);
                TestHelper.WaitLoop(() => scSender.CreateRPCClient().GetRawMempool().Length > 0);

                // Mine the transaction
                scSender.GenerateStratisWithMiner(1);

                // Ensure the nodes are synced
                TestHelper.WaitLoop(() => TestHelper.IsNodeSynced(scSender));
                TestHelper.WaitLoop(() => TestHelper.AreNodesSynced(scReceiver, scSender));

                // The balance should now reflect the transfer
                Assert.Equal((ulong)900, senderState.GetCurrentBalance(tokenContractAddress));
            }
        }
        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);
            }
        }
Exemplo n.º 15
0
        public void VM_ExecuteContract_WithoutParameters()
        {
            //Get the contract execution code------------------------
            SmartContractCompilationResult compilationResult = SmartContractCompiler.CompileFile("SmartContracts/StorageTest.cs");

            Assert.True(compilationResult.Success);

            byte[] contractExecutionCode = compilationResult.Compilation;
            //-------------------------------------------------------

            //Call smart contract and add to transaction-------------
            var carrier         = SmartContractCarrier.CallContract(1, new uint160(1), "StoreData", 1, (Gas)500000);
            var transactionCall = new Transaction();

            transactionCall.AddInput(new TxIn());
            TxOut callTxOut = transactionCall.AddOutput(0, new Script(carrier.Serialize()));
            //-------------------------------------------------------

            //Deserialize the contract from the transaction----------
            var deserializedCall = SmartContractCarrier.Deserialize(transactionCall);
            //-------------------------------------------------------

            var repository = new ContractStateRepositoryRoot(new NoDeleteSource <byte[], byte[]>(new MemoryDictionarySource()));
            IContractStateRepository stateRepository = repository.StartTracking();

            var gasMeter = new GasMeter(deserializedCall.CallData.GasLimit);

            var persistenceStrategy = new MeteredPersistenceStrategy(repository, gasMeter, this.keyEncodingStrategy);
            var persistentState     = new PersistentState(persistenceStrategy, deserializedCall.CallData.ContractAddress, this.network);

            var internalTxExecutorFactory =
                new InternalTransactionExecutorFactory(this.keyEncodingStrategy, this.loggerFactory, this.network);
            var vm = new ReflectionVirtualMachine(internalTxExecutorFactory, this.loggerFactory);

            var sender = deserializedCall.Sender?.ToString() ?? TestAddress.ToString();

            var context = new SmartContractExecutionContext(
                new Block(1, new Address("2")),
                new Message(
                    new Address(deserializedCall.CallData.ContractAddress.ToString()),
                    new Address(sender),
                    deserializedCall.Value,
                    deserializedCall.CallData.GasLimit
                    ),
                TestAddress.ToUint160(this.network),
                deserializedCall.CallData.GasPrice
                );

            var result = vm.ExecuteMethod(
                contractExecutionCode,
                "StoreData",
                context,
                gasMeter,
                persistentState,
                repository);

            stateRepository.Commit();

            Assert.Equal(Encoding.UTF8.GetBytes("TestValue"), stateRepository.GetStorageValue(deserializedCall.CallData.ContractAddress, Encoding.UTF8.GetBytes("TestKey")));
            Assert.Equal(Encoding.UTF8.GetBytes("TestValue"), repository.GetStorageValue(deserializedCall.CallData.ContractAddress, Encoding.UTF8.GetBytes("TestKey")));
        }
Exemplo n.º 16
0
        public void VM_CreateContract_WithParameters()
        {
            //Get the contract execution code------------------------
            SmartContractCompilationResult compilationResult =
                SmartContractCompiler.CompileFile("SmartContracts/Auction.cs");

            Assert.True(compilationResult.Success);
            byte[] contractExecutionCode = compilationResult.Compilation;
            //-------------------------------------------------------

            //    //Call smart contract and add to transaction-------------
            string[] methodParameters = new string[]
            {
                string.Format("{0}#{1}", (int)SmartContractCarrierDataType.ULong, 5),
            };

            var carrier         = SmartContractCarrier.CreateContract(1, contractExecutionCode, 1, (Gas)500000, methodParameters);
            var transactionCall = new Transaction();

            transactionCall.AddInput(new TxIn());
            TxOut callTxOut = transactionCall.AddOutput(0, new Script(carrier.Serialize()));
            //-------------------------------------------------------

            //Deserialize the contract from the transaction----------
            var deserializedCall = SmartContractCarrier.Deserialize(transactionCall);
            //-------------------------------------------------------

            var repository = new ContractStateRepositoryRoot(new NoDeleteSource <byte[], byte[]>(new MemoryDictionarySource()));
            IContractStateRepository track = repository.StartTracking();

            var gasMeter                  = new GasMeter(deserializedCall.CallData.GasLimit);
            var persistenceStrategy       = new MeteredPersistenceStrategy(repository, gasMeter, new BasicKeyEncodingStrategy());
            var persistentState           = new PersistentState(persistenceStrategy, TestAddress.ToUint160(this.network), this.network);
            var internalTxExecutorFactory =
                new InternalTransactionExecutorFactory(this.keyEncodingStrategy, this.loggerFactory, this.network);
            var vm = new ReflectionVirtualMachine(internalTxExecutorFactory, this.loggerFactory);

            var context = new SmartContractExecutionContext(
                new Block(1, TestAddress),
                new Message(
                    TestAddress,
                    TestAddress,
                    deserializedCall.Value,
                    deserializedCall.CallData.GasLimit
                    ),
                TestAddress.ToUint160(this.network),
                deserializedCall.CallData.GasPrice,
                deserializedCall.MethodParameters
                );

            var result = vm.Create(
                contractExecutionCode,
                context,
                gasMeter,
                persistentState,
                repository);

            track.Commit();

            Assert.Equal(6, BitConverter.ToInt16(track.GetStorageValue(context.Message.ContractAddress.ToUint160(this.network), Encoding.UTF8.GetBytes("EndBlock")), 0));
            Assert.Equal(TestAddress.ToUint160(this.network).ToBytes(), track.GetStorageValue(context.Message.ContractAddress.ToUint160(this.network), Encoding.UTF8.GetBytes("Owner")));
        }