ABI string not working - c#

I am writing a program which takes an ethereum contract ABI string in C# and uses it to call a function which allows me to interact with the smart contract using nethereum. When I use a smaller ABI string I am able to make it work but for some reason it won't work with this longer string or any other ABI which exceeds the length of a small example ABI. When I compile the code below I get the error message (bare in mind that I have tried JSON deserializing but that still makes the same error):
An exception of type 'Newtonsoft.Json.JsonReaderException' occurred in Newtonsoft.Json.dll but was not handled in user code
Additional information: After parsing a value an unexpected character was encountered: t. Path '[0].outputs[0].name', line 3, position 20.
protected void init()
{
web3 = new Nethereum.Web3.Web3();
string abi = #"[{'constant':false,'inputs':[{'name':'username','type':'string'},
{'name':'location','type':'string'}],'name':'addUser','outputs':
[{'name':','type':'string'}],'type':'function'},{'constant':false,'inputs'
:[],'name':'burnCoins','outputs':[{'name':','type':'uint256'}],'type':'function'},
{'constant':false,'inputs':[{'name':'vendor','type':'address'},
{'name':'recipient','type':'address'}],'name':'trade','outputs':[],
'type':'function'},{'constant':false,'inputs':[{'name':'vendor','type':'address'},
{'name':'isPositive','type':'bool'},{'name':'message','type':'string'}],
'name':'giveReputation','outputs':[],'type':'function'},{'constant':false,'inputs':
[{'name':'user','type':'address'}],'name':'showBurnedCoins','outputs':[{'name':
','type':'uint256'}],'type':'function'},{'constant':false,'inputs':[{'name':'user',
'type':'address'}],'name':'viewReputation','outputs':[{'name':','type':'uint256'},
{'name':','type':'uint256'},{'name':','type':'uint256'}],'type':'function'},
{'anonymous':false,'inputs':[{'indexed':true,'name':'user','type':'address'},
{'indexed':true,'name':'amountBurned','type':'uint256'}],'name':'_coinsBurned',
'type':'event'},{'anonymous':false,'inputs':[{'indexed':true,'name':'user',
'type':'address'},{'indexed':true,'name':'message','type':'string'}],'
name':'_positiveReputation','type':'event'},{'anonymous':false,'inputs'
:[{'indexed':true,'name':'user','type':'address'},{'indexed':true,'name':'message'
,'type':'string'}],'name':'_negativeReputation','type':'event'},
{'anonymous':false,'inputs':[{'indexed':true,'name':'username','type':'string'},
{'indexed':true,'name':'location','type':'string'},{'indexed':true,'name':
'user','type':'address'}],'name':'_addUser','type':'event'},{'anonymous':false,
'inputs':[{'indexed':true,'name':'vendor','type':'address'},{'indexed':true,
'name':'buyer','type':'address'}],'name':'_newTrade','type':'event'},{'anonymous':
false,'inputs':[{'indexed':true,'name':'user','type':'address'},{'indexed':true,
'name':'positive','type':'uint256'},{'indexed':true,'name':'negative','type':'uint256'},
{'indexed':false,'name':'total','type':'uint256'}],'name':'_viewedReputation',
'type':'event'}]";
string contractAddress = "0xd53c3dc2f3fcf1779b68ea8e441d857b4af5a413";
Reputation = web3.Eth.GetContract(abi, contractAddress);
}

From my comment:
The error is because of the line 'name':'showBurnedCouns', 'outputs':[{'name':','type':'uint256'}]. A ' is missing inside the outputs block.

See diiN_ comment on my question as this answers the question. Silly me!

Related

ICE: trying to add a local var with the same name, but different types. during [_RegisterClipboardFormat]

I have a PoC to use some existing Java-codebase in some UWP-app using the most current Visual Studio Community 19 version 16.3.2 and the latest released IKVM 8.1.7195.0. The app builds and runs fine in Debug-mode, but fails to build already in Release-mode with the following error:
MCG0004:InternalAssert Assert Failed: ICE: trying to add a local var
with the same name, but different types. during
[_RegisterClipboardFormat] Ams.Oms.Poc
RegisterClipboardFormat is part of IKVM:
#DllImportAttribute.Annotation(value = "user32.dll", EntryPoint = "RegisterClipboardFormat")
private native static int _RegisterClipboardFormat(String format);
#cli.System.Security.SecuritySafeCriticalAttribute.Annotation
private static int RegisterClipboardFormat(String format)
{
return _RegisterClipboardFormat(format);
}
https://github.com/ikvm-revived/ikvm/blob/master/openjdk/sun/awt/IkvmDataTransferer.java#L95
What I'm wondering is which local variable the error message is referring to? Might be something added implicitly or might have to do with String in Java vs. string in C#? OTOH that file is clearly named .java.
Didn't find much about the error message in general, only the following two links seems to be more interesting:
Variables having same name but different type
Why doesn't C# allow me to use the same variable name in different scopes?
So I'm currently even unsure where the message comes from, Visual Studio/C# directly or IKVM during running code during building Release-mode. I strongly suspect the error is coming from Visual Studio/C#, though.
Searching for the function itself doesn't reveal much of help as well:
Sorry, AWT is not a supported part of IKVM.
https://sourceforge.net/p/ikvm/bugs/225/
Others seemed to have the same problem, because CN1 simply disabled that code entirely in their fork of IKVM:
//#DllImportAttribute.Annotation(value = "user32.dll", EntryPoint = "RegisterClipboardFormat")
//private native static int _RegisterClipboardFormat(String format);
#cli.System.Security.SecuritySafeCriticalAttribute.Annotation
private static int RegisterClipboardFormat(String format)
{
throw new Error("Not implemented");
//return _RegisterClipboardFormat(format);
}
https://github.com/ams-ts-ikvm/cn1-ikvm-uwp/blob/master/openjdk/sun/awt/IkvmDataTransferer.java#L95
Any ideas? Thanks!
There seems to be a workaround by not changing any code at all: The settings of the Release-build contain a checkbox if to use the .NET native toolbox for the build, which is enabled by default. By disabling that the build succeeds without any code change and is as fast as the Debug-build again. Before changing that, the Release-build took a lot longer as well.
Don't know what that means regarding actually calling native code, if that fails or not, because my app doesn't use those. I guess it would fail, depending on if it works in Debug or not. Additionally, I'm not sure if the Windows store accepts such a modified Release-build, but as UWP-apps aren't forced to use native code at all, I guess there's a good chance things are going to work.

Runtime casting of COM objects in C#

I am working on a application which needs to communicate via COM interface with multiple CAD applications (not in the same time). I want to have nice and reusable code, but I came across problems with type casting of COM objects when I made generic application handle getter method.
What I tried so far:
This is the attempt I would like the most if it worked.
public static TCadAppType CadApp<TCadAppType>()
{
dynamic cadApp = default(TCadAppType);
//Here under Dynamic View/Message there is already an error
// Message = "Element not found. (Exception from HRESULT: 0x8002802B (TYPE_E_ELEMENTNOTFOUND))"
// cadVersion.Value evaluates to "SldWorks.Application"
cadApp = (TCadAppType)Marshal.GetActiveObject(cadVersion.Value);
//Following 2 lines of code are for testing purposes only, i am testing with Solidworks API
AssemblyDoc Assembly;
//The exception is thrown when I try to access some method from the Solidworks API
Assembly = (AssemblyDoc)cadApp.OpenDoc6("some parametras...");
}
Attempt using Convert class
// Another attempt using Convert class
public static TCadAppType CadApp<TCadAppType>()
{
dynamic cadApp = default(TCadAppType);
// cadVersion.Value evaluates to "SldWorks.Application"
cadApp = Marshal.GetActiveObject(cadVersion.Value);
cadApp = Convert.ChangeType(cadApp, typeof(SldWorks.SldWorks));
// Exception is thrown with the following message:
// Message = "Object must implement IConvertible."
}
I really thought that I am on the right track, since there is an article on Microsoft Docs website explaining how dynamic can help you with com interopt: https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/types/using-type-dynamic#com-interop
Any ideas how I can do this runtime casting a keep my code as reusable as possible?
My software setup:
Win 10
Project is targeted for .NET 4.7.2
First Tests are with Solidworks 2019
Turns out that the my coding attempt 1 was valid c# code indeed.
I tried it using with Autodesk Inventor, and it works.
So the only thing left for me is to conclude that this is some bug from Solidworks and their COM interfacing.
Thank you Optional Option for your interest in the topic.

The description string for parameter reference (%1) could not be found

I'm getting this exception when trying to read from the Windows Log using C#'s method EventRecord.FormatDescription():
System.Diagnostics.Eventing.Reader.EventLogException: The description string for parameter reference (%1) could not be found
at System.Diagnostics.Eventing.Reader.EventLogException.Throw(Int32 errorCode)
at System.Diagnostics.Eventing.Reader.NativeWrapper.EvtFormatMessageRenderName(EventLogHandle pmHandle, EventLogHandle eventHandle, EvtFormatMessageFlags flag)
at System.Diagnostics.Eventing.Reader.ProviderMetadataCachedInformation.GetFormatDescription(String ProviderName, EventLogHandle eventHandle)
The exception happens when the text of the event contains the string %% followed by a long number (some events from a source I don't control contain that pattern). Those %% are intended to be just text, I don't expect any parsing intelligence from Windows at that point.
Do you know what I can do to avoid .Net from throwing this error when the text of an event contains that pattern?
Here are the PowerShell commands that will cause the exception next time you try to read the event from a C# program:
New-EventLog -LogName Application -Source MyApp
Write-EventLog -Source MyApp -LogName Application -Message "%%4294967295" -EventId 3
The workaround I ended up implementing is as follows:
private string FormatEventDescription(EventRecord eventRecord)
{
try
{
return eventRecord.FormatDescription();
}
catch (EventLogException e)
{
return eventRecord.ToXml();
}
}
This is less than satisfactory, as that XML is not user-friendly, but at least it has all the information needed in case we need to know the original content of the EventRecord. Note the XML doesn't necessarily contain the description string inside, sometimes these events have a list of parameters which are used to fill a message template to generate the description string, so in this case you'll get the raw params.

Serializing/Deserializing a roundtrip with NetTopologySuite's IO Library for GeoJson reveals a potential bug

I'm having trouble using NetTopologySuite's GeoJsonReader to deserialize Feature objects. In particular, I'm receiving the following exception (which at first glance seems straightforward, so please read on):
An unhandled exception of type 'System.ArgumentException' occurred in Newtonsoft.Json.dll. Additional information: Expected token '{' not found.
Just doing a simple round-trip results in this exception:
public static string DoIt( Feature feature )
{
GeoJsonWriter writer = new GeoJsonWriter();
var geoJson = writer.Write(feature);
GeoJsonReader reader = new GeoJsonReader();
var deserializedFeature = reader.Read<Feature>(geoJson );
}
in this case, geoJson is pretty straightforward:
"{\"type\":\"Feature\",\"geometry\":{\"type\":\"Polygon\",\"coordinates\":[[[-104.50348159865847,40.891762392617345],[-104.50348672999991,40.891415817000279],[-104.50355999200002,40.887782408000135],[-104.5036332529998,40.884149000000093],[-104.50845260799991,40.884357883000121],[-104.51307160051412,40.884558081989375],[-104.51307160051412,40.891762392617345],[-104.50348159865847,40.891762392617345]]]},\"properties\":null}"
Please let me know what I'm doing wrong. By the way, I'm using NetTopologySuite 1.14, NetTopologySuite.IO.GeoJSON 1.14, & Json.Net 9.0.1.
this is actually a bug.
code fixed, see #120

Cannot easily access excel range by name in excel add-in in C#

I am new to writing add-ins in C# (to C# as well). I have seen that ExcelDNA works very well for simple functions, but I got stuck with a simple task: manipulating ranges (especially addressed by their name). You see that I tried to use the Interop for this task, which looks the easy way to me. What am I doing wrong in this very simple piece of code? I already went to the ExcelDNA google groups and I only found very awkward answers to the
Thanks very much in advance
using ExcelDna.Integration;
namespace MyAddIn
{
public class MyClass {
[ExcelFunction(Category = "MyFunctions", IsMacroType = true)]
public static string MyMacro(int a, int b)
{
var app = (Microsoft.Office.Interop.Excel.Application) ExcelDnaUtil.Application;
var range = app.get_Range("MyTag"); // this line does not fail, but I don't know if it
// selects the right range -- although MyTag exists
range.set_Value("hello") // it fails here
return (string) range.Value2; // or it would fail here as well
}
}
}
It throws this error
A first chance exception of type 'System.Reflection.TargetInvocationException' occurred in mscorlib.dll
A first chance exception of type 'System.Runtime.InteropServices.COMException' occurred in mscorlib.dll
If you comment out the set_range line, and ensure that the MyTag cell has a string in, your function would work fine.
The main issue is with the set_Range attempt. Excel does not allow you to set some other part of the sheet from a worksheet function. You need to instead change it to a macro (return 'void') that is triggered by a menu or ribbon button. (Setting IsMacroType=true does not turn your function into a macro, it just registers your function as a special type.)
You could try:
[ExcelCommand(MenuName="My Macros", MenuText="Set MyTag value")]
public static void MySetterMacro()
{
var app = (Microsoft.Office.Interop.Excel.Application) ExcelDnaUtil.Application;
var range = app.Range["MyTag"];
range.Value = "Hello there!";
}
I'm assuming you are using C# 4, so we don't need the get_Value, set_Value stuff.
If you are using C# 3.5, I think you need to say
range.set_Value(Type.Missing, "Old-Style Hello");
because Value is a parameterized property, and the C# / COM interop before C# 4 was retarded.

Categories