Hi,
I am trying to deploy a contract that needs a map(address, int)
as parameter for the init function and cannot get it working
I try to deploy it as follows:
let myMap= new Map();
myMap.set(keyPair1.publicKey, 30);
myMap.set(keyPair2.publicKey, 70);
console.log(myMap);
contractSource = utils.readFileRelative('./contracts/MyContract.aes', "utf-8"); // Read the aes file
contractClient = await clientOwner.getContractInstance(contractSource);
const deploy = await contractClient.deploy([myMap]);
When running forgae test
I always get the following error:
Error: Http request for https://compiler.aepps.com/encode-calldata failed with status code 403. Status: Forbidden.
Error data: {"reason":"Parse errors\nline 29, column 37: Unexpected token con"}
I appreciate your help. Thanks!
2 Likes
Hello @marco.chain,
there seems to be a bug in our SDK in the version you use. When you update the SDK in your package.json
to 3.2.1
. Your exact example should be working.
Instead of new Map();
you can also pass javascript objects {[keyPair1.publicKey]: 30, [keyPair2.publicKey]: 70}
. Both will work.
Hope this helps Let me know if you have any more questions.
3 Likes
sounds good. hopefully I hadn’t used that already
1 Like
this seems to work now, great!
@philipp.chain can you also help me out how to access a list converted from a map? I have a map where I need to iterate over and sum up all int
values
private function validateConditions(myMap': map(address, int)) : bool =
let myList: list((address, int)) = Map.to_list(myMap')
???
true
I want to iterate over that list and sum up all int values but I don’t know how to do that
1 Like
You will need to make a recursive function call where you deconstruct the list/tuples. Do you want to check if all entries of the map behave to a condition? is it fine if the return value is not boolean, but abort if the condition is not meet for one entry?
yeah it would be ok to abort if the condition is not met. but the condition is that the sum of all int
values equals 100
Even better, thats more simple
first lets define some list helper functions
private function map(f : 'a => 'b, l : list('a)) : list('b) =
switch(l)
[] => []
e :: l' => f(e) :: map(f, l')
private function foldr(f : (('a, 'b) => 'b), z: 'b, l : list('a)) : 'b =
switch(l)
[] => z
e :: l' => f(e, foldr(f, z, l'))
private function sum(l : list('a), f : 'a => int) : int =
foldr((x, y) => x + y, 0, map(f, l))
private function pair_second(tuple) =
switch(tuple)
(_, e) => e
then you can go ahead and do
private function validateConditions(myMap: map(address, int)) : bool =
let myList: list((address, int)) = Map.to_list(myMap')
let intList: list(int) = map(pair_second, myList)
let intSum: int = sum(intList, x => x)
true
I have not tried this, but it should be working like this.
1 Like
as already figured out in telegram this is working fine, thanks!
the only thing that I needed to change was using sum(intList, (x) => x)
instead of sum(intList, x => x)
but I definitely need to better understand what’s going on under the hood of these helper functions
2 Likes
I was and am still in contact with @philipp.chain regarding the development of my contract.
For some reason I am not able to test the function payAndSplit
in my contract. With the current state of the source code I always get an error out of gas
(which should never be the case because of the automated fee calculation).
When I manually set a quite high amount of gas in the function call I get an error that the await fails after wating for 10 blocks. The tx isn’t mined.
However it seems like there is an issue with my function or with my setup but I can’t find it. Any help is appreciated!
Here the current source-code:
The error is in this switch
statement:
private function split(recipientConditions': list((address, int)), totalValue: int) =
switch(recipientConditions')
(recipient, weight) :: l' =>
Chain.spend(recipient, totalValue / 100 * weight)
split(l', totalValue)
It is missing the base case. What would it do when the list of recipientConditions is empty? There is no matching switch statement thus it will run out of gas. So adding:
[] => ()
should solve that.
And in the second case, what happens if you too much gas is that the transaction no longer fits in a microblock and it will not be mined.
2 Likes
will check as soon as I am at home
edit: it works now, thx @hanssv.chain!
1 Like