Why I cannot send ftm with this simple code - vb.net

Private Async Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim privatekey = System.IO.File.ReadAllText("privatekey.txt")
'Dim publickey = "0x898568c58466957bedaE0e2A2457beb158a150de" ''
Dim destination = "0x7fD0Ec4d9908A712852d32d110839Fc1A9Ce55d5"
Dim rpcURL = "https://rpc.ftm.tools" ' where should I put this
Dim chainID = 250 'Where should I put this?
Dim account = New Nethereum.Web3.Accounts.Account(privatekey, chainID)
Dim web3 = New Nethereum.Web3.Web3(account, rpcURL)
Dim amount = New Nethereum.Hex.HexTypes.HexBigInteger(10)
Await web3.TransactionManager.SendTransactionAsync(account.Address, destination, amount)
End Sub
I am learning to use nethereum.
I make this simple code. Simple. I want to send 10 wei of fantom to another address. Simple right.
I got this error
It's very weird.
Index was outside the bound of the array? What bound?
Anyway, this is such a very simple program. I wonder where do I went wrong with this?
This is the right way to do it right?
Other minor related question while we're at it (should I ask this separately). Why the hell chainID is the property of account but rpcURL is the property of web3. I thought fantom chain, that uses https://rpc.ftm.tools uses chainID 250. So if we know the chain id, we kind of know the rpc url and if we know the rpc url we sort of know that it'll only work for one chain ID anyway.
How do I fix my code? What's wrong? And if anyone can explain the chainID rpcURL dilemma it'll be great.
I look further where the error happens. It seems that the error happen when nethereum tries to compute gas fees.
at
Nethereum.RPC.Fee1559Suggestions.TimePreferenceFeeSuggestionStrategy.SuggestFees(FeeHistoryResult feeHistory, BigInteger tip)
at Nethereum.RPC.Fee1559Suggestions.TimePreferenceFeeSuggestionStrategy.<SuggestFeesAsync>d__29.MoveNext()
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1.ConfiguredTaskAwaiter.GetResult()
at Nethereum.RPC.Fee1559Suggestions.TimePreferenceFeeSuggestionStrategy.<SuggestFeeAsync>d__27.MoveNext()
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1.ConfiguredTaskAwaiter.GetResult()
at Nethereum.RPC.TransactionManagers.TransactionManagerBase.<SetTransactionFeesOrPricingAsync>d__37.MoveNext()
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Nethereum.Web3.Accounts.AccountSignerTransactionManager.<SignTransactionRetrievingNextNonceAsync>d__14.MoveNext()
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1.ConfiguredTaskAwaiter.GetResult()
at Nethereum.Web3.Accounts.AccountSignerTransactionManager.<SignAndSendTransactionAsync>d__16.MoveNext()
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1.ConfiguredTaskAwaiter.GetResult()
at Nethereum.RPC.TransactionReceipts.TransactionReceiptPollingService.<SendRequestAndWaitForReceiptAsync>d__5.MoveNext()
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at testapp.Form1.VB$StateMachine_9_doSomething.MoveNext() in C:\Users\teguh\Dropbox\vb.net\testapp\testapp\Form1.vb:line 21
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
at testapp.Form1.VB$StateMachine_8_Button1_Click.MoveNext() in C:\Users\teguh\Dropbox\vb.net\testapp\testapp\Form1.vb:line 3
I plan to do this manually anyway. But how exactly I should do that?
I changed the code to
Dim privatekey = System.IO.File.ReadAllText("privatekey.txt")
'Dim publickey = "0x898568c58466957bedaE0e2A2457beb158a150de" ''
Dim destination = "0x7fD0Ec4d9908A712852d32d110839Fc1A9Ce55d5"
Dim rpcURL = "https://rpc.ftm.tools" ' where should I put this
Dim chainID = 250 'Where should I put this?
Dim account = New Nethereum.Web3.Accounts.Account(privatekey, chainID)
Dim web3Obj = New Nethereum.Web3.Web3(account, rpcURL)
'Dim amount = Nethereum.Web3.Web3.Convert.ToWei(0.1)
Dim balance = Await web3Obj.Eth.GetBalance.SendRequestAsync(account.Address)
Dim EtherBalance = Nethereum.Web3.Web3.Convert.FromWei(balance.Value) 'I got the correct value here
Dim result = Await web3Obj.Eth.GetEtherTransferService.TransferEtherAndWaitForReceiptAsync(destination, 1D, 1)
Basically, I am being stingy and say that the gas price should be 1 wei. I "deservedly" got this message
transaction underpriced
I think I should just code the gas price my self. How do I do so? What's the minimum gas price for fantom?

Your issue is that Fantom is a Fork of Ethereum and has not implemented yet the EIP-1559 pricing model. For this you have to either provide the gas price (to force legacy) or enable it in the web3.Eth.TransactionManager (Legacy)
Nethereum uses the eth_gasPrice call automatically to set the Gas Price if not provided and if it is in Legacy mode. But you should check with the Fantom chain what is the best way to get your prices.
Why do you need to pass the chainId? This is required to sign the transaction, and to ensure you know what chain you are using. (Prevent inputting the wrong url and get a replay attack).

Just want to say that this code actually work
Private Async Function doSomething() As Task
Dim privatekey = System.IO.File.ReadAllText("privatekey.txt")
'Dim publickey = "0x898568c58466957bedaE0e2A2457beb158a150de" ''
Dim destination = "0x7fD0Ec4d9908A712852d32d110839Fc1A9Ce55d5"
Dim rpcURL = "https://rpc.ftm.tools" ' where should I put this
Dim chainID = 250 'Where should I put this?
Dim account = New Nethereum.Web3.Accounts.Account(privatekey, chainID)
Dim web3Obj = New Nethereum.Web3.Web3(account, rpcURL)
Dim transManager = web3Obj.TransactionManager
transManager.UseLegacyAsDefault = True
'Dim amount = Nethereum.Web3.Web3.Convert.ToWei(0.1)
Dim balance = Await web3Obj.Eth.GetBalance.SendRequestAsync(account.Address)
Dim EtherBalance = Nethereum.Web3.Web3.Convert.FromWei(balance.Value) 'I got the correct value here
Dim transInput = New Nethereum.RPC.Eth.DTOs.TransactionInput
transInput.From = account.Address
transInput.To = destination
Dim estimategas = Await web3Obj.TransactionManager.EstimateGasAsync(transInput)
'Dim result = Await web3Obj.TransactionManager.SendTransactionAsync(transInput) '
Dim result = Await web3Obj.Eth.GetEtherTransferService.TransferEtherAsync(destination, 0.1D,, estimategas)
End Function
This is the result
https://ftmscan.com/tx/0x014d668080f49bf4a86cfd79b944525dd3d6dd44902f4e7b76ee901e48e54202

Related

How do I use continueWith to continue a task with another task?

Dim listOfTask = New List(Of Task)
For Each account In uniqueAccounts().Values
Dim newtask = account.conditionalInitializeAsync()
Dim nexttask = account.getPairsPriceStepAsync()
listOfTask.Add(newtask)
listOfTask.Add(nexttask)
Dim nexttaskaftenewtask = newtask.ContinueWith(nexttask) 'compiler warning
Next
Instead of list
listOfTask.Add(newtask)
listOfTask.Add(nexttask)
I want to do
listOfTask.Add(nexttaskaftenewtask )
How do I do so?
I can compile the following without error or warning. Hope this helps.
Dim nexttaskaftenewtask = newtask.ContinueWith(New Action(Of Task)(Function() nexttask))

How to do something on

Public Shared Async Function getMarketDetailFromAllExchangesAsync() As Task
Dim taskList = New List(Of Task)
For Each account In uniqueAccounts()
Dim newtask = account.Value.getMarketInfoAsync()
taskList.Add(newtask)
Next
Await Task.WhenAll(taskList.ToArray)
Dim b = 1
End Function
The code work just fine.
However, I want to log every time a task is done
So I did
newtask.ContinueWith(Async Function(x) LogEvents(account.ToString))
LogEvents is a normal function. I got 2 error
How exactly should I do that?
I did it this way
Public Shared Async Function getMarketDetailFromAllExchangesAsync() As Task
Dim taskList = New List(Of Task)
Dim starttime = jsonHelper.currentTimeStamp
LogEvents("Start Getting Market Detail of All")
For Each account In uniqueAccounts().Values
Dim newtask = account.getMarketInfoAsync().ContinueWith(Sub() account.LogFinishTask("GetMarketDetail", starttime))
taskList.Add(newtask)
'newtask.ContinueWith(Sub() LogEvents(account.ToString))
Next
Await Task.WhenAll(taskList.ToArray)
Dim b = 1
End Function
If anyone knows how to do so without a lambda that'll be great.

How to do this without lambda?

Public Shared Async Function getMarketDetailFromAllExchangesAsync() As Task
Dim taskList = New List(Of Task)
Dim starttime = jsonHelper.currentTimeStamp
LogEvents("Start Getting Market Detail of All")
For Each account In uniqueAccounts().Values
Dim newtask = account.getMarketInfoAsync().ContinueWith(Sub() account.LogFinishTask("GetMarketDetail", starttime))
taskList.Add(newtask)
'newtask.ContinueWith(Sub() LogEvents(account.ToString))
Next
Await Task.WhenAll(taskList.ToArray)
Dim b = 1
End Function
Is there a way to do .ContinueWith(Sub() account.LogFinishTask("GetMarketDetail", starttime)) with addressOf instead?
How?
You need to create a method which satisfies any of existed ContinueWith overloads.
In your particular case it should satisfy a signature of Action(Of Task).
But because in ConitnuesWith you are using account instance, you will not be able to use AddressOf with method of the class where loop is executed.
As workaround you can create required method in class of account
Public Class Account
Public Sub LogFinishedMarketDetail(task As Task)
Dim starttime = jsonHelper.currentTimeStamp
Me.LogFinishTask("GetMarketDetail, starttime")
End Sub
End Class
Usage
For Each account In uniqueAccounts().Values
Dim newtask =
account.getMarketInfoAsync().ContinueWith(AddressOf account.LogFinishedMarketDetail)
taskList.Add(newtask)
Next
Suggestion - set Option Strict to On - will saves developer time by displaying possibly errors during compile time, instead of run-time.

Unable to cast object of type System.Collections.Generic.IEnumerable - Web API issue

So I am trying to create a simple web API 2 with VB in VS2015. However the code I did get working only returns a simple string, where the Web Api expects serialized data so XML or JSON could be returned.
'Here I initialize and populate my object
Public widgetObj As New widgetModelClass("bottle", 1)
' Below kind of works, but simply returns a string **instead** of
' the serialized data for XML or JSON the Web API should return.
' it returns: {"Name":"bottle","ID":1}
Public Function GetValues() As widgetModelClass
Return widgetObj
End Function
The below code fails with the exception:
Unable to cast object of type System.Collections.Generic.IEnumerable
Public Function GetValues() As IEnumerable(Of widgetModelClass)
Return widgetObj
End Function
I have defined my model class as follows
Public Class widgetModelClass
Public Sub New(ByVal name As String, ByVal id As Integer)
Me.Name = name
Me.ID = id
End Sub
Private m_Name As String
Public Property Name() As String
Get
Return m_Name
End Get
Set
m_Name = Value
End Set
End Property
Private m_ID As Integer
Public Property ID() As Integer
Get
Return m_ID
End Get
Set
m_ID = Value
End Set
End Property
End Class
The full error message:
An error has
occurred.Unable to cast object of type
'TestApp.widgetModelClass' to type
'System.Collections.Generic.IEnumerable1[TestApp.widgetModelClass]'.</ExceptionMessage><ExceptionType>System.InvalidCastException</ExceptionType><StackTrace>
at lambda_method(Closure , Object , Object[] ) at
System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.<>c__DisplayClass10.<GetExecutor>b__9(Object
instance, Object[] methodParameters) at
System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.Execute(Object
instance, Object[] arguments) at
System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ExecuteAsync(HttpControllerContext
controllerContext, IDictionary2 arguments, CancellationToken
cancellationToken)
--- End of stack trace from previous location where exception was thrown --- at
System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task
task) at
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task
task) at
System.Web.Http.Controllers.ApiControllerActionInvoker.d__0.MoveNext()
--- End of stack trace from previous location where exception was thrown --- at
System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task
task) at
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task
task) at
System.Web.Http.Controllers.ActionFilterResult.d__2.MoveNext()
--- End of stack trace from previous location where exception was thrown --- at
System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task
task) at
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task
task) at
System.Web.Http.Dispatcher.HttpControllerDispatcher.d__1.MoveNext()
In your sample you return widgetObj but it is not of an instanse of the IEnumerable(Of widgetModelClass) as you want.
You have to change declaration to return one instanse of the widgetModelClass:
Public Function GetValues() As widgetModelClass
Return widgetObj
End Function
or your return statement to return IEnumerable(Of widgetModelClass):
Public Function GetValues() As IEnumerable(Of widgetModelClass)
Return New List(Of widgetModelClass)(New widgetModelClass() { widgetObj } )
End Function

WP8 GifRenderer ArgumentException: Value does not fall within the expected range

I have a problem with GifRenderer class.
In an Windows Phone 8 app, my scope is generate an animated gif starting from a list of png images stored in isolated storage of app and then save it and share it.
When in my code I call GifRenderer.RenderAsync method, I have an ArgumentException, Value does not fall within the expected range, as you can see in following VB code.
Where am I doing wrong?
Dim images = New List(Of IImageProvider)
Dim image As Picture
Try
For Each fileName In fileNames
images.Add(New StorageFileImageSource(Await StorageFile.GetFileFromPathAsync(IO.Path.Combine(ApplicationData.Current.LocalFolder.Path, fileName))))
Next
Dim info = Await images(0).GetInfoAsync()
Using renderer = New GifRenderer()
renderer.Size = info.ImageSize
renderer.Sources = images
renderer.Duration = 1000
Dim gifBuffer = Await renderer.RenderAsync()
Dim stream = gifBuffer.AsStream()
Using library = New MediaLibrary()
Dim filename = String.Format("{0}+{1}.gif", IO.Path.GetFileNameWithoutExtension(fileNames(0)), fileNames.Count)
image = library.SavePicture(IO.Path.GetFileName(filename), stream)
End Using
End Using
Dim task = New ShareMediaTask()
task.FilePath = image.GetPath()
task.Show()
Catch ex As Exception
Debug.WriteLine(ex)
'renderer.RenderAsync() ->
'System.ArgumentException: Value does not fall within the expected range.
' at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
' at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
' at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
' at WP8.App.VB$StateMachine_0_ShareAnimation.MoveNext()
End Try