public void MockChain_NonFungibleToken()
        {
            using (PoWMockChain chain = new PoWMockChain(2))
            {
                MockChainNode node1 = chain.Nodes[0];
                MockChainNode node2 = chain.Nodes[1];

                node1.MineBlocks(1);

                ContractCompilationResult compilationResult = ContractCompiler.CompileFile("SmartContracts/NonFungibleToken.cs");
                Assert.True(compilationResult.Success);

                // Create contract and ensure code exists
                BuildCreateContractTransactionResponse response = node1.SendCreateContractTransaction(compilationResult.Compilation, 0);
                node2.WaitMempoolCount(1);
                node2.MineBlocks(1);
                Assert.NotNull(node2.GetCode(response.NewContractAddress));
                Assert.NotNull(node1.GetCode(response.NewContractAddress));

                string[] parameters = new string[]
                {
                    this.methodParameterStringSerializer.Serialize(1uL)
                };

                LocalExecutionResponse result  = node1.CallContractMethodLocally("OwnerOf", response.NewContractAddress, 0, parameters);
                uint160 senderAddressUint160   = node1.MinerAddress.Address.ToUint160(node1.CoreNode.FullNode.Network);
                uint160 returnedAddressUint160 = ((Address)result.Return).ToUint160();
                Assert.Equal(senderAddressUint160, returnedAddressUint160);

                // Send tokenId 1 to a new owner
                parameters = new string[]
                {
                    this.methodParameterStringSerializer.Serialize(node1.MinerAddress.Address.ToAddress(node1.CoreNode.FullNode.Network)),
                    this.methodParameterStringSerializer.Serialize(node2.MinerAddress.Address.ToAddress(node1.CoreNode.FullNode.Network)),
                    this.methodParameterStringSerializer.Serialize(1uL)
                };
                BuildCallContractTransactionResponse callResponse = node1.SendCallContractTransaction("TransferFrom", response.NewContractAddress, 0, parameters);
                node2.WaitMempoolCount(1);
                node2.MineBlocks(1);

                parameters = new string[]
                {
                    this.methodParameterStringSerializer.Serialize(1uL)
                };
                result = node1.CallContractMethodLocally("OwnerOf", response.NewContractAddress, 0, parameters);
                uint160 receiverAddressUint160 = node2.MinerAddress.Address.ToUint160(node1.CoreNode.FullNode.Network);
                returnedAddressUint160 = ((Address)result.Return).ToUint160();
                Assert.Equal(receiverAddressUint160, returnedAddressUint160);

                IList <ReceiptResponse> receipts = node1.GetReceipts(response.NewContractAddress, "Transfer2");
                Assert.Single(receipts);
            }
        }
Beispiel #2
0
        public void Token_Standards_Test()
        {
            const ulong totalSupply = 100_000;
            // Deploy contract
            ContractCompilationResult compilationResult = ContractCompiler.CompileFile("SmartContracts/StandardToken.cs");

            Assert.True(compilationResult.Success);
            string[] constructorParams = new string[] { string.Format("{0}#{1}", (int)MethodParameterDataType.UInt, totalSupply) };
            BuildCreateContractTransactionResponse preResponse = this.node1.SendCreateContractTransaction(compilationResult.Compilation, 0, constructorParams);

            this.mockChain.WaitAllMempoolCount(1);
            this.mockChain.MineBlocks(1);
            Assert.NotNull(this.node1.GetCode(preResponse.NewContractAddress));

            decimal amount = 0;

            // Send amount to contract, which will send to wallet address (address without code)
            var base58Address = this.node1.MinerAddress.Address;

            string[] parameters = new string[] { string.Format("{0}#{1}", (int)MethodParameterDataType.Address, base58Address) };
            BuildCallContractTransactionResponse response = this.node1.SendCallContractTransaction(
                nameof(StandardToken.GetBalance),
                preResponse.NewContractAddress,
                amount,
                parameters);

            this.mockChain.WaitAllMempoolCount(1);
            this.mockChain.MineBlocks(1);

            // Contract doesn't maintain any balance
            Assert.Equal((ulong)0, this.node1.GetContractBalance(preResponse.NewContractAddress));

            LocalExecutionResponse result = this.node1.CallContractMethodLocally("GetBalance", preResponse.NewContractAddress, 0, parameters);

            Assert.Equal(totalSupply, result.Return);

            // Receipt is correct
            ReceiptResponse receipt = this.node1.GetReceipt(response.TransactionId.ToString());

            Assert.Equal(response.TransactionId.ToString(), receipt.TransactionHash);
            Assert.Empty(receipt.Logs); // TODO: Could add logs to this test
            Assert.True(receipt.Success);
            Assert.True(receipt.GasUsed > GasPriceList.BaseCost);
            Assert.Null(receipt.NewContractAddress);
            Assert.Equal(this.node1.MinerAddress.Address, receipt.From);
            Assert.Null(receipt.Error);
            Assert.Equal(preResponse.NewContractAddress, receipt.To);
        }
Beispiel #3
0
        public IActionResult LocalCallSmartContractTransaction([FromBody] LocalCallContractRequest request)
        {
            if (!this.ModelState.IsValid)
            {
                return(ModelStateErrors.BuildErrorResponse(this.ModelState));
            }

            // Rewrite the method name to a property name
            this.RewritePropertyGetterName(request);

            try
            {
                ContractTxData txData = this.smartContractTransactionService.BuildLocalCallTxData(request);

                var height = request.BlockHeight.HasValue ? request.BlockHeight.Value : (ulong)this.chainIndexer.Height;

                ILocalExecutionResult result = this.localExecutor.Execute(
                    height,
                    request.Sender?.ToUint160(this.network) ?? new uint160(),
                    !string.IsNullOrWhiteSpace(request.Amount) ? (Money)request.Amount : 0,
                    txData);

                var deserializer = new ApiLogDeserializer(this.primitiveSerializer, this.network, result.StateRoot, this.contractAssemblyCache);

                var response = new LocalExecutionResponse
                {
                    InternalTransfers = deserializer.MapTransferInfo(result.InternalTransfers.ToArray()),
                    Logs         = deserializer.MapLogResponses(result.Logs.ToArray()),
                    GasConsumed  = result.GasConsumed,
                    Revert       = result.Revert,
                    ErrorMessage = result.ErrorMessage,
                    Return       = result.Return // All return values should be primitives, let default serializer handle.
                };

                return(this.Json(response, new JsonSerializerSettings
                {
                    ContractResolver = new ContractParametersContractResolver(this.network)
                }));
            }
            catch (MethodParameterStringSerializerException e)
            {
                return(this.Json(ErrorHelpers.BuildErrorResponse(HttpStatusCode.InternalServerError, e.Message,
                                                                 "Error deserializing method parameters")));
            }
        }