Comments (18)
Error is coming from the ArrayTypeDecoder.DecodeStaticElement (for static elements), line 117, where var decodedListOutput = (IList) Activator.CreateInstance(type)
is used; system cannot create an array without size being specified. Then, if using Activator.CreateInstance(type, size)
we are facing the issue where the size is fixed and we cannot add elements in DecodeAndAddElement
.
The code should be changed into
var elementType = GetIListElementType(type);
if (elementType == null)
throw new Exception("Only types that implement IList<T> are supported to decoded Array Types");
var decodedListOutput = (IList) Activator.CreateInstance(typeof(List<>).MakeGenericType(elementType));
if (decodedListOutput == null)
throw new Exception("Only types that implement IList<T> are supported to decoded Array Types");
var currentIndex = 0;
while (currentIndex < size)
{
var encodedElement = encoded.Skip(currentIndex * ElementType.FixedSize).Take(ElementType.FixedSize).ToArray();
DecodeAndAddElement(elementType, decodedListOutput, encodedElement);
currentIndex++;
}
return ToArray(decodedListOutput, elementType, size);
Where
private object ToArray(IList list, Type elementType, int size)
{
var array = Array.CreateInstance(elementType, size);
for (int i = 0; i < size; i++) array.SetValue(list[i], i);
return array;
}
from nethereum.
How are you declaring the DTO / Struct in Nethereum?
from nethereum.
The output parameters were declared as arrays in the function DTO (address[] and uint256[]).
from nethereum.
The output parameters were declared as arrays in the function DTO (address[] and uint256[]).
No I mean can you copy and paste your csharp code
from nethereum.
The function DTOs are created dynamically (so nothing easily readable) at runtime based on the specifications of the function definitions. The function definition looks like:
<Function>
<Reference>1</Reference>
<Name>getPoolTokens</Name>
<FunctionType>GetPoolTokens</FunctionType>
<Constant>true</Constant>
<InputParameters>
<Parameter Alias="PoolId" Name="poolId" Type="bytes32" Order="1"></Parameter>
</InputParameters>
<OutputParameters>
<Parameter Alias="Tokens" Name="tokens" Type="address[]" Order="1"></Parameter>
<Parameter Alias="Balances" Name="balances" Type="uint256[]" Order="2"></Parameter>
<Parameter Alias="LastChangeBlock" Name="lastChangeBlock" Type="uint256" Order="3"></Parameter>
</OutputParameters>
</Function>
The parameters are used to declare the properties of the function output DTO, with the corresponding ParameterAttribute (where type of parameter attribute is equal to the Type of the spec). The property of the C# class will be converted such as (for example): uint256 -> BigInteger, address -> string
from nethereum.
Why don't just use the code generator, that is why is there, instead of using your own custom.. just use the abi to generate your code instead of xml, you might be doing something wrong with your custom generator.
So make sure what you do generate is right ...
from nethereum.
from nethereum.
Invalid issue, closing
from nethereum.
@foued1979 Can you let me know if this some tool or third party service, and which one it is if so?
from nethereum.
Why don't just use the code generator, that is why is there, instead of using your own custom.. just use the abi to generate your code instead of xml, you might be doing something wrong with your custom generator.
So make sure what you do generate is right ...
My code is 100% correct; it is not a third party, it is all developed by me for high frequency trading. I use my own ABI conventions to have my own contract ABIs, more flexible and able to read / write all type of contracts (whether EVM or not).
I was expecting the Nethereum code to be more flexible (i.e. not being too strongly typed when declaring parameters) => the modification I brought to the Nethereum code is (I believe) more flexible and is now working (enables to create fully custom ABIs).
from nethereum.
You might have missed something
from nethereum.
You don't need to be strongly typed either https://playground.nethereum.com/csharp/id/1070
from nethereum.
But really cool regardless !! I hope is helping you
from nethereum.
I got you know, so you are creating FunctionABIs etc from Xml instead the json ABI, or human readable http://playground.nethereum.com/csharp/id/1068
There are extensions to deserialise to default to dynamic, json etc.. just have a look, all arrays are supported.
from nethereum.
In fact, I have created my own mapping with my own function names so that different contracts with same functionalities are interpreted in the same way by my code <=> for example, a swap, regardless of the signature or contract format, is understood as a swap by my code. Same as for any smart contract functionality (getBalance, allowance, getReserves, etc.).
I have exchange / blockchain managers acting in parallel and managing pairs / tokens across different blockchains and exchanges, simultaneously, to detect DEX vs DEX arbitrage opportunities (within less than 1s for 2000 paths, approximately - and my ABI typology helps avoiding data collision when using RPC requests) => as you can imagine, I needed to have the lightest code as possible to have the code being straight to the point (and also flexible enough to onboard any future format - including digital assets).
Btw, your Nethereum code has been exceptionally helping for my implementation; that's a really great library.
from nethereum.
In fact, I have created my own mapping with my own function names so that different contracts with same functionalities are interpreted in the same way by my code <=> for example, a swap, regardless of the signature or contract format, is understood as a swap by my code. Same as for any smart contract functionality (getBalance, allowance, getReserves, etc.).
Ah excellent that was mainly the idea of the typed objects, that they can be reused across a Swap is a swap across many standards and GetBalance etc, now i see your point of using the custom xml as it is easier to onboard, ie does this system have x and y functionality.
I have TODO to use generators that will speed up the encoding / decoing, so that might help you in the future even if typed.
I have exchange / blockchain managers acting in parallel and managing pairs / tokens across different blockchains and exchanges, simultaneously, to detect DEX vs DEX arbitrage opportunities (within less than 1s for 2000 paths, approximately - and my ABI typology helps avoiding data collision when using RPC requests) => as you can imagine, I needed to have the lightest code as possible to have the code being straight to the point (and also flexible enough to onboard any future format - including digital assets).
Awesome, that is great. I would never have thought that will be still arbing opportunities.
from nethereum.
Well if it helps on the dynamic
using System;
using System.Collections.Generic;
using System.Numerics;
using System.Threading.Tasks;
using Nethereum.ABI.FunctionEncoding.Attributes;
using Nethereum.ABI.FunctionEncoding;
using Nethereum.ABI.Model;
using Nethereum.Contracts;
using Nethereum.Web3.Accounts;
using Nethereum.Web3;
using Nethereum.Hex.HexConvertors.Extensions;
using Nethereum.Hex.HexTypes;
using System.Linq;
public class DynamicRebalancer
{
public static async Task Main()
{
var web3 = new Web3("https://mainnet.infura.io/v3/ddd5ed15e8d443e295b696c0d07c8b02");
var contract = web3.Eth.GetContract(@"
[{'inputs':[{'internalType':'bytes32','name':'poolId','type':'bytes32'}],'name':'getPoolTokens','outputs':[{'internalType':'contract IERC20[]','name':'tokens','type':'address[]'},{'internalType':'uint256[]','name':'balances','type':'uint256[]'},{'internalType':'uint256','name':'lastChangeBlock','type':'uint256'}],'stateMutability':'view','type':'function'}]", "0xba12222222228d8ba445958a75a0704d566bf2c8");
var getPoolTokensFunction = contract.GetFunction("getPoolTokens");
var output = await getPoolTokensFunction.CallDecodingToDefaultAsync("0xa6f548df93de924d73be7d25dc02554c6bd66db500020000000000000000000e".HexToByteArray());
var jobject = output.ConvertToJObject();
Console.WriteLine(jobject.ToString());
}
}
from nethereum.
Thanks - I will have a look. I assume that a conversion occurs when parameters are created using GetContract; conversion doesn't occur when I dynamically create the parameters and attach "my" ABI to the Nethereum contract.ABI class. The initial error i was getting (in the decoder) was "cannot dynamically create instance of System.String[]"; which is due to the fact that size of array must be specified with the Activator.CreateInstance (or the Array.CreateInstance). But then, when using the size of the parameter to create the array, I was confronted to the fixed size and therefore the impossibility to use Add => I changed the code to create instance of List and then convert the list to Array.
This is how I create the contractABI; abi that I attach to the new Contract(new RPC.EthApiService(web3.Client), typeof(AbiModel.ContractABI), contractId).ContractBuilder.ContractABI:
var abiContract = new ContractABI();
var abiFunctions = new List();
foreach (var function in listOfFunctions)
{
var functionAbi = new FunctionABI(function.Name, function.Constant);
var newAliases = new SortedDictionary<string, string>();
var inputParameters = new List<EthAbi.Parameter>();
var outputParameters = new List<EthAbi.Parameter>();
if (function.InputParameters != null)
foreach (var parameter in function.InputParameters)
{
var inputParam = new EthAbi.Parameter(parameter.Type, parameter.Name, parameter.Order);
if (parameter.Type == "tuple")
{
var component = StructuresDef.Structures.First(c => c.Name == parameter.ComponentName);
var tupleParameters = new List<EthAbi.Parameter>();
foreach (var componentParameter in component.Parameters)
{
tupleParameters.Add(new EthAbi.Parameter(componentParameter.Type, componentParameter.Name, componentParameter.Order));
}
(inputParam.ABIType as TupleType)!.SetComponents(tupleParameters.ToArray());
}
inputParameters.Add(inputParam);
}
if (function.OutputParameters != null)
foreach (var parameter in function.OutputParameters)
{
outputParameters.Add(new EthAbi.Parameter(parameter.Type, parameter.Name, parameter.Order));
if (!functionOutputAliases.ContainsKey(parameter.Name)) newAliases.Add(parameter.Name, parameter.Alias);
}
functionAbi.InputParameters = inputParameters.ToArray();
functionAbi.OutputParameters = outputParameters.ToArray();
abiFunctions.Add(functionAbi);
if (function.FunctionType == "Other") functionNameMapping.Add(function.Name, function.Name);
else functionNameMapping.Add(function.FunctionType, function.Name);
functionOutputAliases.Add(function.Name, newAliases);
}
abiContract.Events = listOfEvents.ToArray();
abiContract.Functions = abiFunctions.ToArray();
from nethereum.
Related Issues (20)
- How to call the smart contract write function? HOT 2
- Hi
- Running on Windows 11 - onecore\net\netprofiles\service\src\nsp\dll\namespaceserviceprovider.cpp(550)\ HOT 4
- How can I use EstimateGasAsync? help. HOT 3
- EIP712 Encoding shouldn't need the Domain in the types HOT 1
- Metamask seed/password phrase generates different accounts. HOT 1
- BigInteger JSON serialization should be string if their value is bigger than 2^53
- The reader's MaxDepth of 64 has been exceeded Newtonsoft HOT 2
- [bug] input string too long for common.Address HOT 2
- Microsoft.Extensions.Logging and Microsoft.Extensions.Logging.Abstractions version outside of dependency constraint
- BSC Block 30501963 is NULL??? HOT 3
- how to use http proxy?
- Error occurred when trying to send rpc requests(s)
- Serializing `bytes32`, then encoding from JSON does not work HOT 14
- EstimateGasAsync fails when function is onlyOwner HOT 2
- How to use struct parameters HOT 1
- Everything i post to contract throws 'System.ArgumentOutOfRangeException' with Number was less than the array's lower bound in the first dimension. (Parameter 'destinationIndex') HOT 2
- StreamingWebSocketClient.SendRequestAsync handled but not processed HOT 4
- StreamingWebSocketClient never close HOT 2
- Get a HIGH CPU usage HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from nethereum.