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); } }
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); }
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"))); } }