Multiaddress utility in front-end-template - substrate

Extending the front end template to do some new things and running into issues with multiaddress lookup functionality as specified in our chain here: https://github.com/Greenetwork/BLX_chain/blob/f14ad8705debcc8033069b4fdda046271e1b61f1/pallets/allocator/src/lib.rs#L140
So it seems that the issue is that we are missing one piece of data that the extrinsic (tradeTokens) wants (the piece that defines which "type" for fromapn:Source and toapn:Source)
You can see below that the using the dropdown menus to select Address32 in polkadot js apps yields a 3 being populated in the encoded call data (Address32 is the 3rd entry in the Source enum)
and further here that 3 is shown as ‘snip< Address32: >snip’
Currently as the code in our front-end-template:
https://github.com/Greenetwork/BLX_frontend_new/blob/afe6f9f256e6c9c2a3164f72cf80d4a9057bb893/src/Transfer.js#L71-L72
the error is:
Unhandled Rejection (Error): createType(Call):: Call: failed decoding allocator.tradeTokens:: Struct: failed on args: {"asset_id":"AssetId","fromapn":"Source","toapn":"Source","amt":"Balance1"}:: Struct: failed on fromapn: {"_enum":{"Id":"AccountId","Index":"AccountIndex","Raw":"Bytes","Address32":"[u8;32]","Address20":"[u8;20]"}}:: Invalid AccountId provided, expected 32 bytes, found 31
I think the issue is that the extrinsic is reading the first (or second, see call data in first picture) value of the data being submitted to fromapn as the index of Source, in the current case, that is 0, so it is proceeding to treat the remainder of the data that it was passed as an AccountId.
It is failing on the fact that by using one of the values as the index of Source so we are only left with 31 bytes instead of 32. AccountId is also 32 bytes i think.
Do we need another helper function to append that extra piece of data which specifies the type? Or is there another path?

pre-pended Address32 with and index character to make it 33 bytes:
https://github.com/Greenetwork/BLX_frontend_new/blob/71a0fbee21c08b2374bddfcdca0fe204d3e36aa7/src/helpers.js#L39-L51

Related

My flow fails for no reason: Invalid Template Language? This is what I do

Team,
Occasionally my flow fails and its enough test it manually to running again. However, I want to avoid that this error ocurrs again to stay in calm.
The error that appears is this:
Unable to process template language expressions in action 'Periodo' inputs at line '0' and column '0': 'The template language function 'split' expects its first parameter to be of type string. The provided value is of type 'Null'. Please see https://aka.ms/logicexpressions#split for usage details.'.
And it appears in 2 of the 4 variables that I create:
Client and Periodo
The variable Clientlooks this:
The same scenario to "Periodo".
The variables are build in the same way:
His formula:
trim(first(split(first(skip(split(outputs('Compos'),'client = '),1)),'indicator')))
His formula:
trim(first(split(first(skip(split(outputs('Compos'),'period = '),1)),'DATA_REPORT_DELIVERY')))
The same scenario to the 4 variables. 4 of them strings (numbers).
Also I attached email example where I extract the info:
CO NIV ICE REFRESCOS DE SOYA has finished successfully.CO NIV ICE REFRESCOS DE SOYA
User
binary.struggle#mail.com
Parameters
output = 7
country = 170
period = 202204012
DATA_REPORT_DELIVERY = NO
read_persistance = YES
write_persistance = YES
client = 18277
indicator_group = SALES
Could you give some help? I reach some attepmpts succeded but it fails for no apparent reason:
Thank you.
I'm not sure if you're interested but I'd do it a slightly different way. It's a little more verbose but it will work and it makes your expressions a lot simpler.
I've just taken two of your desired outputs and provided a solution for those, one being client and the other being country. You can apply the other two as need be given it's the same pattern.
If I take client for example, this is the concept.
Initialize Data
This is your string that you provided in your question.
Initialize Split Lines
This will split up your string for each new line. The expression for this step is ...
split(variables('Data'), '\n')
However, you can't just enter that expression into the editor, you need to do it and then edit in in code view and change it from \\n to \n.
Filter For 'client'
This will filter the array created from the split line step and find the item that contains the word client.
`contains(item(), 'client')`
On the other parallel branches, you'd change out the word to whatever you're searching for, e.g. country.
This should give us a single item array with a string.
Initialize 'client'
Finally, we want to extract the value on the right hand side of the equals sign. The expression for this is ...
trim(split(body('Filter_For_''client''')[0], '=')[1])
Again, just change out the body name for the other action in each case.
I need to put body('Filter_For_''client''')[0] and specify the first item in an array because the filter step returns an array. We're going to assume the length is always 1.
Result
You can see from all of that, you have the value as need be. Like I said, it's a little more verbose but (I think) easier to follow and troubleshoot if something goes wrong.

Error(-17994): Invalid arguments for lr_save_string

I am trying to get the random value from list of data. But I am geting the error(-17994).
web_reg_save_param("c_Log",
"LB=LogNumber:",
"RB=\"",
"Ordinal=All",LAST);
lr_save_string(lr_paramarr_random("c_Log"),"randomValue");
If this is the precise ordering in your code then your pseudo array is unlikely to have any values in it until the next page/HTTP request is made. You would be attempting a random assignment of an empty set.
Try setting your lr_save_string() after the next page load when the c_log array is likely to have some values seeded, assuming the expected page loads correctly
web_reg_save_param(...);
web_url(...);
lr_save_string(...);

To have a distribution for integer

I have a parameter that says default value 120 in the main that is linked to the initial number of agents for a particular agent. Now if I wanted that parameter to provide random numbers between 115 to 125 I tried using some distribution but it didn't work.
The error shown in the screenshot refers to type mismatch. triangular() returns a double but the parameter is of type int. This particular error can be fixed by changing the code to (int)triangular(2,5).
Admittingly, it would be good to understand what the purpose of this is in order to provide a more useful method as this approach will generate a sample value between 2 and 5 only at model start.

What is the meaning of MAKEINTRESOURCE((id>>4)+1)?

I am trying to mimic the behavior of CString::LoadString(HINSTANCE hInst, DWORD id, WORD langID) without introducing a dependency on MFC into my app. So I walked through the source. The first thing it does is to immediately call AtlGetStringResourceImage(hInst, id, langID), and then this in turn contains the following line of code:
hResource = ::FindResourceExW(hInst, (LPWSTR)RT_STRING, MAKEINTRESOURCEW((id>>4)+1), langID);
(It's not verbatim like this, but I trimmed out some unimportant stuff).
What is the meaning of shifting the ID by 4 and adding 1? According to the documentation of FindResourceEx, you should pass in MAKEINTRESOURCE(id), and I can't find any example code that is manipulating the id before passing it to MAKEINTRESOURCE. At the same time, if I make my code call MAKEINTRESOURCE(id) then it doesn't work and FindResourceEx returns null, whereas if I use the above shift + add, then it does work.
Can anyone explain this?
From the STRINGTABLE resource documentation:
RC allocates 16 strings per section and uses the identifier value to determine which section is to contain the string. Strings whose identifiers differ only in the bottom 4 bits are placed in the same section.
The code you are curious about locates the section a given string identifier is stored in by ignoring the low 4 bits.

Cannot access animate-properties in Clutter

I am trying to animate an actor in Clutter, but when I enter a property that exists, something goes wrong.
actor.animate( AnimationMode.LINEAR, 400, scale_x:2);
gives me this error
Clutter-WARNING **: Cannot bind property '\x83\xec\u0014\x89\xc6e\xa1\u000c': objects of type 'ClutterTexture' do not have this property
Looks like Unicode-characters to me.
However, when I enter a property that does NOT exist
actor.animate( AnimationMode.LINEAR, 400, thisdoesntwork:2);
I get an error that makes much more sense
Clutter-WARNING **: Cannot bind property 'thisdoesntwork': objects of type 'ClutterTexture' do not have this property
I get the exact same problem when I try this alternative approach:
actor.animate( AnimationMode.LINEAR, 400, "scale-x", 2);
How come all properties that actually exist get converted to some mess, and what can I do to get this to work?
You should be using 2.0 for the value, not 2. 2 is an integer, 2.0 is a double. Vala can't provide type safety for variadic methods, so you have to be careful.
As for why you're seeing the behavior you are for properties which exist, my guess is it has to do with the fact that 2 is a (32-bit) integer and 2.0 is a (64-bit) double. This is simplifying things a bit, and I don't know how much experience you have with C (probably not a lot, since this is the sort of mistake someone coming from a dynamically typed language would make), however... Clutter (well, va_arg) expects a double so it parses 64 bits of data, but you only provided 32 bits, so the first 32-bits of the next argument (NULL) are included. Now, when it starts trying to parse the next argument it starts from the wrong location (32-bits into the argument), so you get the the remainder of NULL and part of whatever garbage happened to be on the stack... Unsuprisingly, that doesn't just so happen to be 32-bits of 0s so when Clutter tests to see if the value it just read == NULL it isn't and Clutter thinks it's been given a pointer to an null-terminated array of characters (which is how strings are represented in C). It reads the data at that location, which just so happens to be \x83\xec\u0014\x89\xc6e\xa1\u000c, and checks to see if there is a property with that name. There isn't, so it emits the error message you saw.
Now, if you switch to using a property which doesn't exist, Clutter will parse the argument (the name of the property), notice that it doesn't exist (just like it did with the second property above), and emit an error.

Resources