How do I encode an array of Byte32 values for Web3j to pass to my smart contract? - web3-java

Contract function is defined as:
function createAggregate (string memory key, bytes32[2] memory part_array) public returns (bytes32)
and have incoming a list of parts, defined as...
List<Bytes32> elements
so was trying to use:
List<Type> items = new ArrayList<Type>();
items.add(...); // user reference
items.add(new DynamicArray<>(elements));
final Function function = new Function("createAggregate",
items,
Arrays.asList(new TypeReference<Bytes32>() {})
);
...
But this does not work, seems to be an encoding issue - what is the right what of encoding the Bytes32 ? (This seems to work fine for an array of strings)

Sort of solved this with the following (although was really looking for a more dynamic size solution)
new StaticArray2(Bytes32.class, Utils.typeMap(elements, Bytes32.class));

Related

Ordering when using scala.collection.Searching

I have an Array of [Long, Q] and would like to make a binary search on it. I tried below :
import scala.collection.Searching._
class Q (val b:Double, val a:Double)
val myArray = Array(5L -> new Q(1,2), 6L-> new Q(6,9), 7L-> new Q(7,6))
val i = myArray.search(6L).insertionPoint
but had this error
No implicit Ordering defined for Any
Unspecified value parameter ord.
I understand that I need to specify an odering rule for this collection Array[(Long,Q)] but can't figure this out myself.
Please help
Signature of search is search[B >: A](elem: B)(implicit ord: Ordering[B]). You've got an array of type [Long, Q]. So in order for the compiler to infer Ordering correctly, you'd have to invoke search like that:
myArray.search(6L-> q/*Q(6,9)*/)(Ordering.by(_._1)) //ordering by the first value in a tuple.
and what you're doing is: myArray.search(6L). If I understand correctly what you're trying to do, it's probably to find both value and position in the array.
You could solve it by using two separate data structures:
keys could be stored in the array, like this:
val myArray = Array(5L, 6L, 7L).toList
myArray.search(6L).insertionPoint
and if you'd need values, you could use map which would work as a dictionary:
val dictionary = Map(
5L -> new Q(1,2),
6L-> new Q(6,9),
7L-> new Q(7,6)
)
EDIT:
Actually, I noticed something like that would work:
val dummy = new Q(0,0) //any instance of Q
myArray.search(6L-> dummy)(Ordering.by(_._1)).insertionPoint //1
It works since for lookup of the insertion point Ordering is used and no equality test is performed.

How to use Array in JEXL?

Using JEXL, I am trying to initialize array and than adding elements into it, however below code gives me 'unsolvable property '0' error.
var abc=[];
abc[0]=5;
1) How can I initialize empty array and keep adding values in it?
2) Can I use it like List, where I do not need to specify size at the time of initialization ?
in JEXL syntax you can initialize objects with new function.
Other option is to add to context arraylist:
This is a working example with jexl2:
JexlEngine jexl = new JexlEngine();
String jexlExp = "var abc=new(\"java.util.ArrayList\", 1);abc[0]=5";
Expression e = jexl.createExpression( jexlExp );
List<Integer> abc = new ArrayList<>(1);
JexlContext jc = new MapContext();
//jc.set("abc", abc ); second option to add arraylist to context
Object o = e.evaluate(jc);
In JEXL, the syntax [] creates a Java array, not a List. As an array, it has a fixed size, so you cannot add values to it. However, JEXL 3.2 has a new syntax for creating an ArrayList literal. Basically, you add ... as the final element.
So in JEXL 3.2, your example could be written as:
var abc=[...];
abc.add(5);
See the JEXL literal syntax reference for more information.

Flash getter method is not able to return a 2D Array

As the title says. I tried it with a String or a normal Array and it works. But when I try to pass on my 2D Array my class won't get anything. We're talking about an Array 16 width and about 50 in length.
In my XMLLoader.as class I have this:
function getConvoArray():Array
{
trace("convoArray send");
return convoArray;
}
And in my DialogueGenerator.as class I have this:
xmlLoader = new XMLLoader("ConvoLines.xml");
convoArray = xmlLoader.getConvoArray();
I've checked if the variable convoArray is filled in the XMLLoader.as class by tracing it in a for loop; it works perfectly. But then, when I try to pass it on to the DialogueGenerator.as class it seems to be empty. I cannot excess anything and Flash doesn't give me an error or a warning.
I simply have my Array in DialogueGenerator declared as this:
public var convoArray:Array;
But I tried different ways of declaring it.
Is there a solution for this? A workaround?
For loading xml I use something like this....
var fileName:String = "ConvoLines.xml";
var loader:URLLoader = new URLLoader();
loader.addEventListener(Event.COMPLETE, LoaderComplete);
loader.addEventListener(IOErrorEvent.IO_ERROR, LoaderError);
loader.load(new URLRequest(fileName + "?rnd=" + Math.random()));
// we affix rand to prevent it from caching the file,
// you don't have to add the ? variable if you aren't worried about it
// updating smoothly
Then in the "LoaderComplete" function we just get the xml out. Hope that helps.
var convoXML:XML = new XML(event.target.data);

Array, Object, Memory. Actionscript

I have a question related to memory. I will give an example to make it clear how everything works now.
I have 2 arrays:
var ArrayNew:Array = new Array();
var ArrayOld:Array = new Array();
Also i have a class to store my objects (3 properties). For example:
public Id {get; set;}
public Name {get; set;}
public Type {get; set;}
The thing is, that i'm filling the ArrayNew with new objects every (for example 12 hours):
ArrayNew.push(x, x, x)
.....
ArrayNew.push(x, x, x)
It may be about ~200 records or even more.
After that i make this:
ArrayOld = ArrayNew;
ArrayNew = null;
So the thing is, how memory works in this situation and what happens with objects? Does ArrayOld = ArrayNew make a copy of objects (cause now it works)? Does ArrayNew=null delete created objects?
I wish you undearstand the situation. :)
The objects stored in arrayOld get garbage collected if there are no other references to them. The ones from arrayNew are not copied - they are referenced by arrayOld after the assignment.
It's to say that that after:
arrayNew[0].name = 'a random silly text';
arrayOld = arrayNew;
arrayOld[0].name = 'another silly string';
trace(arrayNew[0]);
You'd get:
another silly string
Style note: Normally you don't start variable/object names with capitals, it's reserved for classes.
If I understand you correctly you want to know what happened to ArrayOld.
My code:
var arr_1:Array = ["Hello world!"];
var arr_2:Array = ["My name is Stas!"];
arr_2 = arr_1;
arr_1 = null;
trace(arr_2);// Hello world!
If I made a mistake with the understanding of the issue do explain it properly.
ArrayOld = ArrayNew is simply making ArrayOld reference the same thing as ArrayNew at that point. The actual data in memory is not copied.
ArrayNew = null is simply assigning null value to the ArrayNew reference. It doesn't delete the data ArrayNew previously referenced, nor does it affect other references to that data (such as ArrayOld).
At this point, the original data that ArrayNew used to reference has not changed in any way, you've just handed off what variable refers to it.
At this point if you did ArrayOld = null, then the original data in memory no longer has any reference to it and it will eventually be purged by garbage collection, but not right away. It will happen "later" at a time the runtime decides is convenient.

as3 check for 2 objects with same property in array

I have an array, lets call it _persons.
I am populating this array with Value Objects, lets call this object PersonVO
Each PersonVO has a name and a score property.
What I am trying to do is search the array &
//PSEUDO CODE
1 Find any VO's with same name (there should only be at most 2)
2 Do a comparison of the score propertys
3 Keep ONLY the VO with the higher score, and delete remove the other from the _persons array.
I'm having trouble with the code implementation. Any AS3 wizards able to help?
You'd better use a Dictionary for this task, since you have a designated unique property to query. A dictionary approach is viable in case you only have one key property, in your case name, and you need to have only one object to have this property at any given time. An example:
var highscores:Dictionary;
// load it somehow
function addHighscore(name:String,score:Number):Boolean {
// returns true if this score is bigger than what was stored, aka personal best
var prevScore:Number=highscores[name];
if (isNaN(prevScore) || (prevScore<score)) {
// either no score, or less score - write a new value
highscores[name]=score;
return true;
}
// else don't write, the new score is less than what's stored
return false;
}
The dictionary in this example uses passed strings as name property, that is the "primary key" here, thus all records should have unique name part, passed into the function. The score is the value part of stored record. You can store more than one property in the dictionary as value, you'll need to wrap then into an Object in this case.
you want to loop though the array and check if there are any two people with the same name.
I have another solution that may help, if not please do say.
childrenOnStage = this.numChildren;
var aPerson:array = new array;
for (var c:int = 0; c < childrenOnStage; c++)
{
if (getChildAt(c).name == "person1")
{
aPerson:array =(getChildAt(c);
}
}
Then trace the array,

Resources