public void SmartContracts_GasMeter_HasEnoughGasOperation()
        {
            var diff     = (Gas)100;
            var gas      = new Gas(1000);
            var consumed = (Gas)(gas - diff);
            var gasMeter = new GasMeter(gas);

            gasMeter.Spend(consumed);

            Assert.Equal(consumed, gasMeter.GasConsumed);
            Assert.Equal(diff, gasMeter.GasAvailable);
        }
Beispiel #2
0
        public void VM_ExecuteContract_OutOfGas()
        {
            ContractCompilationResult compilationResult = ContractCompiler.Compile(
                @"
using System;
using Stratis.SmartContracts;

public class Contract : SmartContract
{
    public Contract(ISmartContractState state) : base(state) {}
}
");

            Assert.True(compilationResult.Success);

            byte[] contractExecutionCode = compilationResult.Compilation;
            byte[] codeHash = HashHelper.Keccak256(contractExecutionCode);

            // Set up the state with an empty gasmeter so that out of gas occurs
            var contractState = Mock.Of <ISmartContractState>(s =>
                                                              s.Block == Mock.Of <IBlock>(b => b.Number == 1 && b.Coinbase == this.TestAddress) &&
                                                              s.Message == new Message(this.TestAddress, this.TestAddress, 0) &&
                                                              s.PersistentState == new PersistentState(
                                                                  new TestPersistenceStrategy(this.state),
                                                                  this.context.Serializer, this.TestAddress.ToUint160()) &&
                                                              s.Serializer == this.context.Serializer &&
                                                              s.ContractLogger == new ContractLogHolder() &&
                                                              s.InternalTransactionExecutor == Mock.Of <IInternalTransactionExecutor>() &&
                                                              s.InternalHashHelper == new InternalHashHelper() &&
                                                              s.GetBalance == new Func <ulong>(() => 0));

            var emptyGasMeter    = new GasMeter((RuntimeObserver.Gas) 0);
            var executionContext = new ExecutionContext(new Observer(emptyGasMeter, new MemoryMeter(100_000)));

            VmExecutionResult result = this.vm.Create(
                this.state,
                contractState,
                executionContext,
                contractExecutionCode,
                null);

            CachedAssemblyPackage cachedAssembly = this.context.ContractCache.Retrieve(new uint256(codeHash));

            // Check that it's been cached, even though we ran out of gas.
            Assert.NotNull(cachedAssembly);

            // Check that the observer has been reset.
            Assert.Null(cachedAssembly.Assembly.GetObserver());

            Assert.False(result.IsSuccess);
            Assert.Equal(VmExecutionErrorKind.OutOfGas, result.Error.ErrorKind);
        }
Beispiel #3
0
        public void TestGasInjector()
        {
            SmartContractCompilationResult compilationResult = SmartContractCompiler.Compile(TestSource);

            Assert.True(compilationResult.Success);

            byte[] originalAssemblyBytes = compilationResult.Compilation;

            var resolver = new DefaultAssemblyResolver();

            resolver.AddSearchDirectory(AppContext.BaseDirectory);
            int aimGasAmount;

            using (ModuleDefinition moduleDefinition = ModuleDefinition.ReadModule(
                       new MemoryStream(originalAssemblyBytes),
                       new ReaderParameters {
                AssemblyResolver = resolver
            }))
            {
                TypeDefinition   contractType = moduleDefinition.GetType(ContractName);
                MethodDefinition testMethod   = contractType.Methods.FirstOrDefault(x => x.Name == MethodName);
                aimGasAmount =
                    testMethod?.Body?.Instructions?
                    .Count ?? 10000000;
            }

            var gasLimit            = (Gas)500000;
            var gasMeter            = new GasMeter(gasLimit);
            var persistenceStrategy = new MeteredPersistenceStrategy(this.repository, gasMeter, this.keyEncodingStrategy);
            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 executionContext = new SmartContractExecutionContext(
                new Block(0, TestAddress),
                new Message(TestAddress, TestAddress, 0, (Gas)500000), TestAddress.ToUint160(this.network), 1, new object[] { 1 });

            var result = vm.ExecuteMethod(
                originalAssemblyBytes,
                MethodName,
                executionContext,
                gasMeter,
                persistentState,
                this.repository);

            Assert.Equal(aimGasAmount, Convert.ToInt32(result.GasConsumed));
        }
        public void TestGasInjector()
        {
            SmartContractCompilationResult compilationResult = SmartContractCompiler.Compile(TestSource);

            Assert.True(compilationResult.Success);

            byte[] originalAssemblyBytes = compilationResult.Compilation;

            var resolver = new DefaultAssemblyResolver();

            resolver.AddSearchDirectory(AppContext.BaseDirectory);
            int aimGasAmount;

            using (ModuleDefinition moduleDefinition = ModuleDefinition.ReadModule(
                       new MemoryStream(originalAssemblyBytes),
                       new ReaderParameters {
                AssemblyResolver = resolver
            }))
            {
                TypeDefinition   contractType = moduleDefinition.GetType(ContractName);
                MethodDefinition testMethod   = contractType.Methods.FirstOrDefault(x => x.Name == MethodName);
                aimGasAmount =
                    testMethod?.Body?.Instructions?
                    .Count ?? 10000000;
            }

            var gasLimit = (Gas)500000;
            var gasMeter = new GasMeter(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 callData = new CallData(gasLimit, address, "TestMethod", new object[] { 1 });

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

            this.repository.SetCode(callData.ContractAddress, originalAssemblyBytes);
            this.repository.SetContractType(callData.ContractAddress, "Test");

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

            Assert.Equal((ulong)aimGasAmount, result.GasConsumed);
        }
        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 internalTxExecutorFactory =
                new InternalTransactionExecutorFactory(this.keyEncodingStrategy, this.loggerFactory, this.network);

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

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

            VmExecutionResult result = 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 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));
        }
        /// <summary>
        /// 发送短信
        /// </summary>
        /// <param name="msg"></param>
        /// <param name="ip"></param>
        /// <param name="model"></param>
        private void SendMsg(string msg, string ip, GasMeter model)
        {
            string sendMsgApi    = ConfigurationHelper.GetAppSettings("SendMsgApi");
            string sendMgsApiUrl = TokenHelper.MsgCenterUrl + sendMsgApi + "?access_token=" + TokenHelper.Token;;
            string param         = JsonConvert.SerializeObject(new
            {
                sms = new
                {
                    type    = "general",
                    reply   = false,
                    general = new
                    {
                        content = msg
                    },
                    to       = model.Tel,
                    totype   = "id",
                    toname   = model.CustomerName,
                    schedule = ""
                },
                @event = "DEFAULT",
                from   = "System",
                cid    = model.CompanyId,
                cname  = "成都九门科技有限公司",
                ip     = ip
            });
            string result = HttpHelper.HttpPost(sendMgsApiUrl, param);
            var    DTO    = JsonConvert.DeserializeObject <SendMessageResponseDTO>(result);

            if (DTO.errcode == 0) // 成功
            {
                // 把发送时间写入配置
                ConfigurationHelper config = new ConfigurationHelper();
                config.SetAppSetting("SendTime", DateTime.Now.ToString());
                // 写入日志
                LogHelper.WriteLog("发送成功,发送成功的手机号:" + model.Tel + ";");
            }
            else
            {
                // 写入日志
                LogHelper.WriteLog("发送失败,发送失败的手机号:" + model.Tel + ";失败信息如下:" + DTO.errmsg);
            }
        }
        public void VM_ExecuteContract_OutOfGas()
        {
            ContractCompilationResult compilationResult = ContractCompiler.Compile(
                @"
using System;
using Stratis.SmartContracts;

public class Contract : SmartContract
{
    public Contract(ISmartContractState state) : base(state) {}
}
");

            Assert.True(compilationResult.Success);

            byte[] contractExecutionCode = compilationResult.Compilation;

            // Set up the state with an empty gasmeter so that out of gas occurs
            var contractState = Mock.Of <ISmartContractState>(s =>
                                                              s.Block == Mock.Of <IBlock>(b => b.Number == 1 && b.Coinbase == this.TestAddress) &&
                                                              s.Message == new Message(this.TestAddress, this.TestAddress, 0) &&
                                                              s.PersistentState == new PersistentState(
                                                                  new TestPersistenceStrategy(this.state),
                                                                  this.context.Serializer, this.TestAddress.ToUint160()) &&
                                                              s.Serializer == this.context.Serializer &&
                                                              s.ContractLogger == new ContractLogHolder() &&
                                                              s.InternalTransactionExecutor == Mock.Of <IInternalTransactionExecutor>() &&
                                                              s.InternalHashHelper == new InternalHashHelper() &&
                                                              s.GetBalance == new Func <ulong>(() => 0));

            var emptyGasMeter = new GasMeter((Gas)0);

            VmExecutionResult result = this.vm.Create(
                this.state,
                contractState,
                emptyGasMeter,
                contractExecutionCode,
                null);

            Assert.False(result.IsSuccess);
            Assert.Equal(VmExecutionErrorKind.OutOfGas, result.Error.ErrorKind);
        }
        static void Main(string[] args)
        {
            AbstractMeterCountMeasurementStrategy rpMeasurement = new RotaryPistonMeasurement();
            AbstractMeterCountMeasurementStrategy usMeasurement = new UltraSoundMeasurement();

            IMeterCountDisplayStrategy led   = new LEDDisplay();
            IMeterCountDisplayStrategy scale = new ScaleDisplay();

            IMeterCountTransmissionStrategy wlan  = new WLANTransmission();
            IMeterCountTransmissionStrategy cable = new CableTransmission();

            AbstractMeter meter = new GasMeter(rpMeasurement, led, cable);

            string meterCount = meter.ActualMeterCount;

            meter.DisplayMeterCount(meterCount);
            meter.TransmitMeterCount(meterCount);

            Console.ReadKey();
        }
Beispiel #10
0
 public ReflectionVirtualMachineTests()
 {
     // Take what's needed for these tests
     this.context       = new ContractExecutorTestContext();
     this.network       = this.context.Network;
     this.TestAddress   = "0x0000000000000000000000000000000000000001".HexToAddress();
     this.vm            = this.context.Vm;
     this.state         = this.context.State;
     this.contractState = new SmartContractState(
         new Block(1, this.TestAddress),
         new Message(this.TestAddress, this.TestAddress, 0),
         new PersistentState(
             new TestPersistenceStrategy(this.state),
             this.context.Serializer, this.TestAddress.ToUint160()),
         this.context.Serializer,
         new ContractLogHolder(),
         Mock.Of <IInternalTransactionExecutor>(),
         new InternalHashHelper(),
         () => 1000);
     this.gasMeter = new GasMeter((RuntimeObserver.Gas) 50_000);
 }
Beispiel #11
0
        public int createGasMeter(string serialNo, double meterCoefficient, int numDigits, string startDate, int propertyId)
        {
            GasMeter newMeter = new GasMeter
            {
                SerialNo         = serialNo,
                MeterCoefficient = meterCoefficient,    ///converts units of meter into m3 varies from meter to meter

                ///fixed conversion factors
                CorrectionFactor         = EMConverter.gasCorrectionFactor, ///corrects for temperature & pressure
                CalorificValue           = EMConverter.gasCalorificValue,   ///standard value representing the energy in 1m3 of natural gas
                KWhtoCO2ConversionFactor = EMConverter.gaskWhFactor,
                NumbDigits = numDigits,
                StartDate  = Convert.ToDateTime(startDate)
            };

            ///add meter to property
            int meterId = mediator.DataManager.saveMeter(newMeter);

            mediator.DataManager.addMeterToProperty(meterId, propertyId);

            return(meterId);
        }
        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")));
        }
Beispiel #13
0
        public GasInjectorTests()
        {
            // Only take from context what these tests require.
            var context = new ContractExecutorTestContext();

            this.vm             = context.Vm;
            this.repository     = context.State;
            this.network        = context.Network;
            this.moduleReader   = new ContractModuleDefinitionReader();
            this.assemblyLoader = new ContractAssemblyLoader();
            this.gasMeter       = new GasMeter((Gas)5000000);
            this.state          = new SmartContractState(
                new Block(1, TestAddress),
                new Message(TestAddress, TestAddress, 0),
                new PersistentState(new MeteredPersistenceStrategy(this.repository, this.gasMeter, new BasicKeyEncodingStrategy()),
                                    context.ContractPrimitiveSerializer, TestAddress.ToUint160(this.network)),
                context.ContractPrimitiveSerializer,
                this.gasMeter,
                new ContractLogHolder(this.network),
                Mock.Of <IInternalTransactionExecutor>(),
                new InternalHashHelper(),
                () => 1000);
        }
Beispiel #14
0
        public void SmartContracts_GasInjector_SingleParamConstructorGasInjectedSuccess()
        {
            SmartContractCompilationResult compilationResult =
                SmartContractCompiler.Compile(TestSingleConstructorSource);

            Assert.True(compilationResult.Success);
            byte[] originalAssemblyBytes = compilationResult.Compilation;

            var gasLimit = (Gas)500000;
            var gasMeter = new GasMeter(gasLimit);
            var internalTxExecutorFactory =
                new InternalTransactionExecutorFactory(this.keyEncodingStrategy, this.loggerFactory, this.network);
            var vm = new ReflectionVirtualMachine(this.validator, internalTxExecutorFactory, this.loggerFactory, this.network);

            var callData = new CreateData(gasLimit, originalAssemblyBytes);

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

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

            // TODO: Un-hard-code this.
            // Basefee: 1000
            // Constructor: 15
            // Property setter: 12
            // Storage: 150
            Assert.Equal((Gas)1177, result.GasConsumed);
        }
        public MeterViewModel(Meter m)
        {
            ///populate fiel specific properties
            ///

            ElectricityMeter elecMeter = m as ElectricityMeter;
            GasMeter         gasMeter  = m as GasMeter;

            if (elecMeter != null)
            {
                this.ScalingFactor = elecMeter.ScalingFactor;
            }
            else if (gasMeter != null)
            {
                this.MeterCoefficient = gasMeter.MeterCoefficient;
                this.CorrectionFactor = gasMeter.CorrectionFactor;
                this.CalorificValue   = gasMeter.CalorificValue;

                if (gasMeter.MeterCoefficient == 0.028316846)
                {
                    this.MeterUnits = "cubic feet";
                }
                if (gasMeter.MeterCoefficient == 0.28316846)
                {
                    this.MeterUnits = "10s of cubic feet";
                }
                if (gasMeter.MeterCoefficient == 2.8316846)
                {
                    this.MeterUnits = "100s of cubic feet";
                }
                if (gasMeter.MeterCoefficient == 1)
                {
                    this.MeterUnits = "cubic meters";
                }
            }


            ///load tariff view model with data from meter
            ///

            Meter  = m;
            Tariff = new TariffViewModel();

            if (Meter.Tariffs.Count == 0)
            {
                ///no tariff set yet
                ///
                Tariff = null;
            }
            else
            {
                ///get most recent tariff
                ///
                Meter.Tariffs = Meter.Tariffs.OrderByDescending(t => t.StartDate).ToList();

                Tariff currentTariff = Meter.Tariffs.ElementAt(0);
                currentTariff.Bands = Meter.Tariffs.ElementAt(0).Bands.ToList();

                ///convert model to viewModel
                ///

                Tariff = TariffConverter.createTariffViewFromTariff(currentTariff, false);
            }
        }
Beispiel #16
0
        public void VM_ExecuteContract_CachedAssembly_WithExistingObserver()
        {
            ContractCompilationResult compilationResult = ContractCompiler.Compile(
                @"
using System;
using Stratis.SmartContracts;

public class Contract : SmartContract
{
    public Contract(ISmartContractState state) : base(state) {}

    public void Test() {}
}
");

            Assert.True(compilationResult.Success);

            byte[] contractExecutionCode = compilationResult.Compilation;
            byte[] codeHash = HashHelper.Keccak256(contractExecutionCode);

            byte[] rewrittenCode;

            // Rewrite the assembly to have an observer.
            using (IContractModuleDefinition moduleDefinition = this.context.ModuleDefinitionReader.Read(contractExecutionCode).Value)
            {
                var rewriter = new ObserverInstanceRewriter();

                moduleDefinition.Rewrite(rewriter);

                rewrittenCode = moduleDefinition.ToByteCode().Value;
            }

            var contractAssembly = new ContractAssembly(Assembly.Load(rewrittenCode));

            // Cache the assembly.
            this.context.ContractCache.Store(new uint256(codeHash), new CachedAssemblyPackage(contractAssembly));

            // Set an observer on the cached rewritten assembly.
            var initialObserver = new Observer(new GasMeter((Gas)(this.gasMeter.GasAvailable + 1000)), new MemoryMeter(100_000));

            Assert.True(contractAssembly.SetObserver(initialObserver));

            var callData = new MethodCall("Test");

            // Run the execution with an empty gas meter, which means it should fail if the correct observer is used.
            var emptyGasMeter = new GasMeter((Gas)0);

            var executionContext = new ExecutionContext(new Observer(emptyGasMeter, new MemoryMeter(100_000)));

            VmExecutionResult result = this.vm.ExecuteMethod(this.contractState,
                                                             executionContext,
                                                             callData,
                                                             contractExecutionCode,
                                                             "Contract");

            CachedAssemblyPackage cachedAssembly = this.context.ContractCache.Retrieve(new uint256(codeHash));

            // Check that it's still cached.
            Assert.NotNull(cachedAssembly);

            // Check that the observer has been reset to the original.
            Assert.Same(initialObserver, cachedAssembly.Assembly.GetObserver());
            Assert.False(result.IsSuccess);
            Assert.Equal(VmExecutionErrorKind.OutOfGas, result.Error.ErrorKind);
        }
Beispiel #17
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")));
        }
Beispiel #18
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")));
        }