How to return properly in a Solidity function? - return

I'm a total beginner with solidity, I've searched on google and here but unfortunately I have not found what I'm looking for.
So my problem is with the following lines :
pragma solidity ^0.8.0;
contract PsoukraceFactory {
struct Psoukrace {
string name;
string title;
uint level;
uint HP;
uint defence;
uint dodge;
uint luck;
uint intelligence;
uint strenghth;
uint attack;
uint speed;
}
Psoukrace [] public psoukraces;
function _createPsoukrace( string memory name, string memory title, uint level, uint HP, uint defence, uint dodge, uint luck, uint intelligence, uint strength, uint attack, uint speed) public view returns (string memory, uint) {
psoukraces.push(Psoukrace(name, title, level, HP, defence, dodge, luck, intelligence, strength, attack, speed));
return ("test1",
"test2",
1,
2,
3,
4,
5,
6,
7,
8,
9);
}
}
I get the following error :
Different number of arguments in return statement than in returns declaration.
--> contracts/Psoukrace.sol:27:8:
I don't understand what happened as I have seen (maybe I'm wrong here) I have 11 variables as arguments ( 2 string + 9 uint ) same into my psoukraces array and into my Psoukrace struct
Any help will be appreciated, thank you in advance!

You have this return statement
returns (string memory, uint)
this saying you are going to return 2 things: string and uint. However, in function, you are returning
return ("test1",
"test2",
1,
2,
3,
4,
5,
6,
7,
8,
9);
11 elements. you have to add each type into returns().
returns (string memory,string memory,uint,uint...9times)
after you fixed this you will get another error saying that "Function declared as view, but this expression (potentially) modifies the state and thus requires non-payable". Becase your marked your function as view which means that your function is not going to modify the state but you are actually modifying by pushing psoukraces.push(). so you also have to remove the view from the function.

Related

How to pass out parameter to function from Swift FFI?

Let's say I have a function defined in Rust, which looks like this:
#[no_mangle]
pub unsafe extern "C" fn do_something(
my_value: *mut MyStruct,
some_param: c_uint,
content: *mut *mut u8,
length: *mut c_uint,
capacity: *mut c_uint,
) -> *mut MyStruct {
// Do something and obtain an `ffi_result`...
let heap_data = ffi_result.as_mut_ptr();
// These values are passed as "out" parameters.
*length = ffi_result.len() as c_uint;
*capacity = ffi_result.capacity() as c_uint;
*content = heap_data;
// We intentionally "leak" this data to the heap.
// The caller is responsible for cleaning it up by calling another function.
std::mem::forget(ffi_result);
std::boxed::Box::into_raw(value_of_type_my_struct)
}
It takes in a pointer to a struct, a simple integer parameter, several out parameters that can later be used to create an Array and it returns a pointer to a struct.
Now I compile the rust library into a static library for the target aarch64-apple-ios. I set up a XCode project, add the static library as a dependency as explained here with an "Objective-C Bridging Header" where I import the following header file
#ifndef libmy_project_h
#define libmy_project_h
#include <stdint.h>
struct myStruct;
struct myStruct *do_something(struct myStruct *state, int someParam, char **content, int *length, int *capacity);
#endif
Up until this point everything seems to work fine and I have already successfully used this procedure for a whole bunch of other functions. However in this special case I can not figure out how to call this function from swift. I need to call the function from swift and pass content, length and capacity as out parameters so that I can later use the pointers to create an Array in Swift like so.
This is what I tried so far:
var content = UnsafeMutablePointer<UnsafeMutablePointer<CChar>?>(UnsafeMutablePointer(bitPattern: 0))
var length = UnsafeMutablePointer<Int32>(bitPattern: 0)
var capacity = UnsafeMutablePointer<Int32>(bitPattern: 0)
let my_struct = do_something(my_struct, Int32(some_param), content, length, capacity)
let buffer = UnsafeRawBufferPointer(start: content?.pointee, count: Int(length!.pointee))
var data = Array(repeating: UInt8(0), count: Int(length!.pointee))
data.withUnsafeMutableBytes { arrayPtr in
arrayPtr.copyBytes(from: buffer)
}
However now when I execute this swift snippet, I get an EXC_BAD_ACCESS error, which I think occurs because the pointers I manually created do not belong to the adress space of my application. How can I create pointers that I can use as out parameters?
P.S. For reference here is the same interop code in C#:
[DllImport("my_dll")]
private static extern IntPtr do_something(IntPtr state, uint someParam, out IntPtr content, out uint length, out uint capacity);
Which can be called like so:
IntPtr contentPointer;
uint length, capacity;
IntPtr my_struct = do_something(state, myParam, out contentPointer, out length, out capacity);
byte[] rawContent = new byte[length];
Marshal.Copy(contentPointer, rawContent, 0, (int)length);
// Free the data owned by rust with another FFI call:
free_do_something_result(contentPointer, length, capacity);
var length = UnsafeMutablePointer<Int32>(bitPattern: 0)
You need to pass storage for your out-parameters. This is defining a null pointer. When Rust tries to write the result to address 0, it crashes, since you don't have access to write there.
Instead of creating two layers of pointers, create a value of the type you want, and then pass the address (&) of that value; this will add the extra layer of pointer automatically.
// Create storage
var content: UnsafeMutablePointer<CChar>? // Could be NULL, so Optional
var length: Int32 = 0
var capacity: Int32 = 0
// Pass as references
do_something(&content, &length, &capacity)
// Copy the data
let data = Array(UnsafeRawBufferPointer(start: content, count: Int(length)))
content is still a pointer here because the thing being updated is a pointer. You're not providing storage for content, Rust is. But you do need to provide storage for the pointer (and that's what this does).
I can't compile your code because it's missing a lot (an MCVE would be much better here), so I can't test that this is doing exactly what you mean, but it should be close.
In your example, you're leaking the memory, but since your C# calls free_do_something_result (which I assume cleans it up), I assume you're actually doing the same in the Swift.

Type error when using List<int> variable as an argument to a List<double> method parameter

I'm learning the dart language, and I encountered this problem with lists.
I created a sum function to calculate the sum of a list, here is the code:
double sum(List<double> elements) {
var el = 0.0;
for (var elem in elements) {
el += elem;
}
return el;
}
And I call it from the main menu in 2 ways:
void main(List<String> args) {
var sm = sum([1, 3, 4, 6]);
print(sm)
}
And it worked fine. But when I try to use a middle variable:
var test = [1, 3, 4, 6];
var sm = sum(test);
print(sm);
I get an error :
Error: The argument type 'List<int>' can't be assigned to the parameter type
'List<double>'.
functions.dart:5
- 'List' is from 'dart:core'.
var sm = sum(test);
^
I know that i have to use List as i'm using list of int but it appears that that function I made could work with both types, double and int, but i can't understand the problem when I use a middle variable?
In your first example the list of int literals is automatically converted to double, which is a new feature of Dart 2.1. (source) - int literals get converted automatically to doubles in a double context:
var sm = sum([1, 3, 4, 6]);
Before that, you would experience a compilation error and would have to explicitly provide a double list as a parameter:
var sm = sum([1.0, 3.0, 4.0, 6.0]);
On your second example however, you are implicitly defining a List<int> variable, which cannot be passed as a List<double> parameter.

Multiply-with-carry in Swift

The following code snippet is a direct translation of the multiply-with-carry algorithm which can be found in various places (I took this one as a reference).
public class MultiplyWithCarryRandomGenerator
{
struct Static {
static var m_w:UInt = 521748629
static var m_z:UInt = 762436069
}
class var m_w:UInt{get{return Static.m_w } set{Static.m_w = newValue}};
class var m_z:UInt{get{return Static.m_z } set{Static.m_z = newValue}};
private class func GetUint()->UInt
{
m_z = 36969 * (m_z & 65535) + (m_z >> 16);
m_w = 18000 * (m_w & 65535) + (m_w >> 16);
return (m_z << 16) + m_w;
}
public class func GetUniform()->Double
{
return ((Double(GetUint()) + 1.0) * 2.32830643545449e-10);
}
}
Within XCode playground the uniform distribution remains somewhere between 0 and 40K while it should be in the interval (0,1).
Is there an obvious mistake in my code or an artifact of iOS, the playground...?
There are two differences between C# (the language of that example) and Swift that are causing this problem. The first is that a C# uint is a 32-bit unsigned integer, while a UInt in Swift is an unsigned integer matched to the architecture of the system it's executing on, which means in most cases today UInt is a 64-bit unsigned integer. Since all the constants in your code are geared toward 32 bits, simply change all the UInt declarations to UInt32 and you're halfway there.
The second difference is that addition operations overflow automatically in C# when working with unsigned integers, while in Swift an overflow crashes. You aren't seeing an issue yet, since you're using 32-bit constants with a 64-bit datatype, but after switching to UInt32 you'll start crashing on the overflow in this line:
return (m_z << 16) + m_w;
Swift provides an alternate set of operators, prefixed by &, that silently allow overflow—using &+ in that line solves the issue:
return (m_z << 16) &+ m_w;
And now you get the graph you were hoping for:

Dart Metadata and symbols

I am creating a library to emulate C's stdio library. Is working but the functions (2/3 of which are actually Function objects at the moment) look terrible. I am having a really difficult time figuring out Metadata, Symbols and Mirrors. From what I can tell, they are very useful and they might do what I need. So 3 questions:
Can InstanceMirrors be used like pointers?
Can either of them be used in a similar fashion to macros like those
in C (#define MAC / #define F_MAC(a, b))?
Is there a clean way to implement var_args* and polymorphic functions**? am hoping for something which the editor will actually recognize as a function.
Please include explanations and examples (I am pretty dense so if you don't include examples, you will likely be wasting your time).
*I already know about this: Creating function with variable number of arguments or parameters in Dart, I am hoping for something the editor will recognize as a function rather than an object.
**I am currently just using dynamic parameters and generating the behavior based on the types passed in at run-time, but that is, while effective, horrifying to look at and document.
Ideally I would like my documentation output to resemble this
// var_args hack
int printf (String format, ...) //C
// actually looks good
int vprintf (String format, List<dynamic> args) //C
// var_args hack
int fprintf (dynamic stream, String format, ...) //C
// var_args hack
int fnprintf (dynamic stream, int maxsize, String format, ...) //C
// actually looks good
int vfprintf (dynamic stream, String format, List<dynamic> args) //C
// actually looks good
int vfnprintf (dynamic stream, int maxsize, String format, List<dynamic> args) //C
// --1st first param optional so polymorphic is necessary, + var_args--
int sprintf (StringBuffer stream, String format, ...) //C
String sprintf (String format, ...)
// --1st first param optional so polymorphic is necessary, + var_args--
int snprintf (StringBuffer stream, int maxsize, String format, ...)//C
String snprintf (String format, int maxsize, ...)
// --1st first param optional so polymorphic is necessary--
int vsprintf (StringBuffer stream, String format, List<dynamic> args)//C
String vsprintf (String format, List<dynamic> args)
// --1st first param optional so polymorphic is necessary--
int vsnprintf(StringBuffer stream, int maxsize, String format, List<dynamic> args) //C
String vsnprintf(String format, int maxsize, List<dynamic> args)
// --1st first param optional so polymorphic is necessary--
int strftime(StringBuffer buffer, int maxsize, String format, DateTime date) //C
String strftime(int maxsize, String format, DateTime date)
int strftime(StringBuffer buffer, String format, DateTime date)
String strftime(String format, DateTime date)
// will need something like a pointer or reference
String vsprintf(String buffer, String format, List<dynamic> args) //C
Edit:
sorry, I was called away and didn't have time to my question. In order:
what I meant was something like this:
String f(String *arg0, int *arg1, double *arg2, bool *arg3)
currently I am doing:
String arg0 = ...;
int arg1 = ...;
double arg2 = ...;
bool arg3 = ...;
List<dynamic> args = [arg0, arg1, arg2, arg3];
f1(args);
arg0 = args[0];
arg1 = args[1];
arg2 = args[2];
arg3 = args[3];
List<dynamic> args0 = [arg0];
List<dynamic> args1 = [arg1];
List<dynamic> args2 = [arg2];
List<dynamic> args3 = [arg3];
f2(args0, args1, args2, args3);
arg0 = args0[0];
arg1 = args1[0];
arg2 = args2[0];
arg3 = args3[0];
I am hoping to find a better way
I would like to be able to do the equivalent of this:
#define private:
#define public:
#define enum class
so that I could:
enum E
{
static int VALUE_0 = 0;
static int VALUE_1 = 1;
static int VALUE_2 = 2;
static int VALUE_3 = 3;
int value;
}
class C
{
private:
int _private0;
int _private1;
int _private2;
int _private3;
public:
int _public0;
int _public1;
int _public2;
int _public3;
}
It essentially for commenting purposes (just curious)
yea, I know it works, I was just wondering if it was a better way.
P.S. Any good tutorials on mirrors, or Symbols?
Can InstanceMirrors be used like pointers?
import 'dart:math' as math;
import 'dart:mirrors' as mirr;
void main() {
math.Rectangle r = new math.Rectangle(10, 10, 20, 20);
mirr.InstanceMirror im = mirr.reflect(r);
var r2 = im.reflectee;
print('r top-left: ${r.topLeft}, r2 top-left: ${r2.topLeft}');
}
Can either of them be used in a similar fashion to macros like those in C (#define MAC / #define F_MAC(a, b))?
can you elaborate a bit more what you want to accomplish?
Is there a clean way to implement var_args* and polymorphic functions**? am hoping for something which the editor will actually recognize as a function.
I think the question/answer you linked to has all information about this topic

How to find out the max value for Int in Swift

I want to understand how to access the "struct" type of Int. When I cmd-clicked Int it took me to this class, i want to find out what is the maximum value this can hold. Is there a way to pull from one of this properties ?. what is max and min in this structure ?
struct Int : SignedInteger {
var value: Builtin.Word
init()
init(_ v: Builtin.Word)
init(_ value: Int)
static func convertFromIntegerLiteral(value: Int) -> Int
typealias ArrayBoundType = Int
func getArrayBoundValue() -> Int
static var max: Int { get }
static var min: Int { get }
}
“You can access the minimum and maximum values of each integer type with its min and max properties:
let minValue = UInt8.min // minValue is equal to 0, and is of type UInt8
let maxValue = UInt8.max // maxValue is equal to 255, and is of type UInt8
The values of these properties are of the appropriate-sized number type (such as UInt8 in the example above) and can therefore be used in expressions alongside other values of the same type.”
Excerpt From: Apple Inc. “The Swift Programming Language.” iBooks. https://itun.es/in/jEUH0.
Try this in Swift 3:
let value = Int.max
You can access the minimum and maximum values of each integer type with its min and max properties:
let minValue = UInt8.min // minValue is equal to 0, and is of type UInt8
let maxValue = UInt8.max // maxValue is equal to 255, and is of type UInt8
The values of these properties are of the appropriate-sized number type (such as UInt8 in the example above) and can therefore be used in expressions alongside other values of the same type.
from: https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/TheBasics.html
You can access these as static properties as suggested in other answers.
I see in some comments people are wondering why you can't access them as instance variables.
This is like asking "what is the max value of 5?" and expecting a sensible answer.
One of the main uses for these variables is guarding against integer overflows.
Something along the lines of "if I add something to this integer that makes it bigger than Int.max i.e. it triggers an overflow " and act accordingly.
More on how Apple address the issue of integer overflows here.

Resources