TypeError: Type is not callable - on compile - solidity

I have created a game where I have an interface and a contract with a Game function
But when I compile it throws an exception:
TypeError: Type is not callable
myGameContract.depositPlayer(0, msg.value)();
It is clear that it refers to the fallback after: msg.value)();
But, I don't know how to fix the interface.
interface Game{
function depositPlayer(uint256 _pid, uint256 _amount) external payable;
function myGame(address _reciever) external payable {
addressBoard = payable(_reciever);
myGameContract= Game(addressBoard );
myGameContract.depositPlayer(0, msg.value)();
I need in this case it to contain a fallback
();
More bellow:
For more clarification, comment as the answer indicates, only the call
function contains a fallback

You can execute an external function without the empty parentheses.
Example that executes the external depositPlayer function:
myGameContract.depositPlayer(0, msg.value); // removed the `()`
You can execute the fallback function by sending an empty data field.
address(myGameContract).call("");
But the fallback function is executed when no suitable function (specified in the data field) is found. It's not executed after each function. So you can't execute both depositPlayer and fallback in the same call (except for executing depositPlayer from the fallback).

This is an easy error to make when you accidentally make an argument shadow a function. Here's an easy to understand place this error would pop up:
constructor(address owner, address[] memory defaultOperators) ERC777("Shipyard", "SHIP", defaultOperators) {
transferOwnership(owner);
ico = address(new ShipICO(this));
_mint(owner(), INITIAL_SUPPLY, "", "");
_pause();
}
Note that the argument owner has the same name as the function called in the _mint(owner()) line. Because of the argument having the same name, you're now trying to call the argument owner, which is of type address, as if it were a function. (Note that in this case, owner() is a function inherited from the OZ Ownable contract, making it especially easy to miss.
Easy, common convention is to add an underscore. In this case, _owner may already be taken, so you may add an underscore to the end (owner_ ) for the argument.
As to the OP's question:
This means that myGameContract.depositPlayer is not a function. Go figure out why you think it is, and the compiler thinks it isn't.

Related

How would you call a contract method that takes Enum type via hardhat?

In your contract, if you have method that receives an Enum type, how would you pass the arguments from hardhat script?
contract SomeContract {
enum WinStatus {
PENDING,
LOST,
WON
}
WinStatus status;
function updateWinStatus(WinStatus _status) public {
status = _status;
}
}
// in your hardhat script
...
await someContract.updateWinStatus() // how should i call it. bare in mind hardhat is setup using javascript not typescript in my case.
i tried passing a number, hoping it will get it by order(index). But I am getting 'invalid BigNumber value'. Also, I tried passing a string like "PENDING" or "WinType.PENDING" :thinking:
Javascript natively doesn't support very large numbers (up to the uint256 type supported in Solidity), so Ethers.js (included in Hardhat) accepts a BigNumber instance instead.
const myNumber = ethers.BigNumber.from("0") // pass the numeric value as a string
await someContract.updateWinStatus(myNumber) // pass the BigNumber instance

address(this).send(msg.value) returning false but ethers got transfered

Below is my function:
// Function
function deposit() payable external {
// if(!wallet_address.send(msg.value)){
// revert("doposit fail");
// }
bool isErr = address(this).send(msg.value);
console.log(isErr);
emit Deposit(msg.sender, msg.value, address(this).balance);
}
I use Remix IDE with solidity version 0.8.7 and my question is why send() returns false but the ethers got transferred. Is send() returns false when it success by default?
address(this).send(msg.value) effectively just creates an unnecessary internal transaction redirecting the value accepted by "this contract" to "this contract"
This internal transaction fails because because your contract does not implement the receive() nor fallback() special functions that are needed to accept ETH sent to your contract from send(), transfer(), call() in some cases, and generally any transaction (internal or main) that does not invoke any specific existing function. It does not fail the main transaction, just returns false from the send() method.
TLDR: The send() function is in this case redundant and you can safely remove it. Your contract is able to accept ETH from the deposit() function even without it.
It is low level function call, it can fail in after transfer step. If you don't check success variable, the compiler is warning you that the call could revert and you might carry on unaware that you ignored failure.
So you should check success variable to ensure transaction is success.
require(success, "ETH_TRANSFER_FAILED");

solidity, set value to state Variables, the value not changed

I'm trying to change the state variable value of solidity, and test on the geth console, but the value of state variable is not changed.
The steps are as below:
1: Write a simple smart contract code by solidity as below
pragma solidity ^0.4.0;
contract SimpleStorage {
uint public storedData=99;
mapping(string => uint) balances;
function set(uint x) public returns (uint){
storedData = x;
return storedData;
}
function get() public constant returns (uint) {
return storedData;
}
function multiply(uint a) returns(uint d) {
return a * 7;
}
function setmapping(string key,uint value) returns(uint v)
{
balances[key] = value;
return balances[key];
}
function getmapping(string key) returns(uint v)
{
return balances[key];
}
function kill()
{
}
}
2: compile the code by the truffle, use command
truffle compile
3:start the geth, unlock account, and start the minner
4:deploy the smart contract
truffle migration --reset
and then I see the console output as below
Using network 'development'.
Running migration: 1_initial_migration.js
Replacing Migrations...
... 0x8ccf9e1599c2760ff3eed993be10929403e1faa05489a247a067f4f06536c74c
Migrations: 0xec08113a9e810e527d99a1aafa8376425c4a75ed
Saving successful migration to network...
... 0xedbf12715b736759e9d9297cbaaeb3151d95f478c2f1ee71bff4819d2dbb47e5
Saving artifacts...
Running migration: 2_deploy_contracts.js
Replacing SimpleStorage...
... 0xff5b00f9b14d8ecea4828c3ad8e9dbfa9d685bc0b81530fc346759d7998b060f
SimpleStorage: 0x96cf1e076f4d99a5d0823bd76c8de6a3a209d125
Saving successful migration to network...
... 0x3452a9e76b73e250de80874ebc3fd454724ebf6a15563bee0d5ba89b7b41909f
Saving artifacts...
which means the smart contract deployed to geth successfully
5: Then in the geth console, I set abi variable as below:
abi=[{"constant":true,"inputs":[],"name":"storedData","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[],"name":"changeStorage","outputs":[],"payable":false,"type":"function"},{"constant":false,"inputs":[],"name":"kill","outputs":[],"payable":false,"type":"function"},{"constant":false,"inputs":[],"name":"getAll","outputs":[{"name":"","type":"uint256"},{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"x","type":"uint256"}],"name":"set","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"get","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"key","type":"string"},{"name":"value","type":"uint256"}],"name":"setmapping","outputs":[{"name":"v","type":"uint256"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"refrenceType","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[],"name":"changeMemory","outputs":[],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"key","type":"string"}],"name":"getmapping","outputs":[{"name":"v","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"a","type":"uint256"}],"name":"multiply","outputs":[{"name":"d","type":"uint256"}],"payable":false,"type":"function"}]
6: Get an contract instant as below:
test=eth.contract(abi).at("0x2f3970e8e4e2f5ed4ccb37b0f79fe5598700e2f0")
7: Run the set()
test.set.call(22);
The out put is 22, which I think the state variable storedData was successfully set to the new value 22, but when I run below code to read the storedData,
test4.get()
the return value is still 99, which mean the value of storedData was not changed, beside use the uint to do the testing, I also tried the mapping, but the answer is as same as uint, I don't know if I was wrong in somewhere or the state variable is not allowed to be modified, could anyone help me?
Thanks.
From the question, this is the call that is not changing state:
test.set.call(22)
In order to change state, you must issue a transaction. A call(...) only tells you what would happen if you were to send a transaction. For more background, see: What is the difference between a transaction and a call?
So you can replace the above line with:
test.set.sendTransaction(22)
Alternatively, web3.js will automatically attempt to decide whether to use a transaction or a call. So in this case you can use simply:
test.set(22)
For more background on how web3.js decides, see: How does web3.js decide to run a call() or sendTransaction() on a method call?

Pass callbacks with managed parameters and return types between managed and unmanaged C++

I am writing a native C++ project with a managed C++ wrapper that can receive and invoke callbacks from C#. The managed side should be able to retrieve back that callback and trigger on the managed environment as well.
The signature of the said callback is:
// Native C++
typedef EvaluateResult (*NativeFunction) (std::vector<EvaluateResult> args);
// Managed C++ wrapper
delegate EvaluateResultWrapper^ ManagedFunction (List<EvaluateResultWrapper^> args);
The EvaluateResultWrapper is the managed wrapper class for the native class EvaluateResult. The conversion between the EvaluateResult is:
EvaluateResult result;
EvaluateResultWrapper^ wrapper = gcnew EvaluateResultWrapper (result);
result = EvaluateResult (*wrapper.original);
I want to implement the constructor EvaluateResultWrapper::EvaluateResultWrapper (ManagedFunction^ func) that can roughly do the following:
// NOTE: Pseudo code
void EvaluateResultWrapper::EvaluateResultWrapper (ManagedFunction^ func) {
this->func = func; // Store the func as a member to avoid GC
// original is the pointer to the EvaluateResult that this object is wrapping around
this->original = new EvaluateResult ([&func](std::vector<EvaluateResult> args) -> EvaluateResult {
List<EvaluateResultWrapper^>^ argsList; // Convert args from vector to List. Assuming it is done under the hood
EvaluateResultWrapper^ wrapper = func->Invoke (argsList); // Invoke the managed callback
return EvaluateResult (wrapper.GetOriginal ()); // Convert the managed result to the native counterpart
});
}
I know the above code will not work, but the idea I should be able to wrap the managed callback with codes that able to do conversion of both the callback arguments and return types, so that it is native friendly.
Ideally, I can also do the other way around (not important)
// NOTE: Pseudo code
ManagedFunction^ EvaluateResultWrapper::GetFunction (ManagedFunction^ func) {
// if the callback is set by the managed side, return the same callback back
if (this->func != nullptr) return this->func;
// Otherwise, the callback is a native one
NativeFunction nativeFunc = this->original->GetFunction ();
return gcnew ManagedFunction ([&nativeFunc] (List<EvaluateResultWrapper^>^ args) -> EvaluaResultWrapper {
std::vector argsList; // Convert the args from List back to vector. Assuming it is done under the hood
EvaluateResult result = nativeFunc (argsList); // Invoke the native function
return gcnew EvaluateResultWrapper (result); // Convert the native result into the managed one
});
}
I wonder whether this can be done?
A little bit of context: I am writing an external scripting system on native C++ for our games (similar to Lua scripting). The EvaluateResult is a class representing an evaluation result of any statement. It is basically a value coupled with the type. The type can be either number, boolean, string, array, object, or in this case: function callback.
The function callback can be either set within the native C++ (when the interpreter pass the user-defined function in the scripts) or a function set by the host (managed side).
The idea is the host (C# side) should be able to define and set functions into the memory (defining print() function to print into the host console for example). The callback is wrapped as an EvaluateResult class before storing into the the scripting memory.
For inspection purpose, C# side must be able to get the function callback. Therefor, the ability to get the function is nice to have (but not important, since I can always instruct the native side to execute the function for me)

Is it possible to indirectly load a value type on the stack

In Microsoft IL, to call a method on a value type you need an indirect reference. Lets say we have an ILGenerator named "il" and that currently we have a Nullable on top of the stack, if we want to check whether it has a value then we could emit the following:
var local = il.DeclareLocal(typeof(Nullable<int>));
il.Emit(OpCodes.Stloc, local);
il.Emit(OpCodes.Ldloca, local);
var method = typeof(Nullable<int>).GetMethod("get_HasValue");
il.EmitCall(OpCodes.Call, method, null);
However it would be nice to skip saving it as a local variable, and simply call the method on the address of the variable already on the stack, something like:
il.Emit(/* not sure */);
var method = typeof(Nullable<int>).GetMethod("get_HasValue");
il.EmitCall(OpCodes.Call, method, null);
The ldind family of instructions looks promising (particularly ldind_ref) but I can't find sufficient documentation to know whether this would cause boxing of the value, which I suspect it might.
I've had a look at the C# compiler output, but it uses local variables to achieve this, which makes me believe the first way may be the only way. Anyone have any better ideas?
**** Edit: Additional Notes ****
Attempting to call the method directly, as in the following program with the lines commented out, doesn't work (the error will be "Operation could destabilise the runtime"). Uncomment the lines and you'll see that it does work as expected, returning "True".
var m = new DynamicMethod("M", typeof(bool), Type.EmptyTypes);
var il = m.GetILGenerator();
var ctor = typeof(Nullable<int>).GetConstructor(new[] { typeof(int) });
il.Emit(OpCodes.Ldc_I4_6);
il.Emit(OpCodes.Newobj, ctor);
//var local = il.DeclareLocal(typeof(Nullable<int>));
//il.Emit(OpCodes.Stloc, local);
//il.Emit(OpCodes.Ldloca, local);
var getValue = typeof(Nullable<int>).GetMethod("get_HasValue");
il.Emit(OpCodes.Call, getValue);
il.Emit(OpCodes.Ret);
Console.WriteLine(m.Invoke(null, null));
So you can't simply call the method with the value on the stack because it's a value type (though you could if it was a reference type).
What I'd like to achieve (or to know whether it is possible) is to replace the three lines that are shown commented out, but keep the program working, without using a temporary local.
I figured it out! Luckily I was reading about the unbox opcode and noticed that it pushes the address of the value. unbox.any pushes the actual value. So, in order to call a method on a value type without having to store it in a local variable and then load its address, you can simply box followed by unbox. Using your last example:
var m = new DynamicMethod("M", typeof(bool), Type.EmptyTypes);
var il = m.GetILGenerator();
var ctor = typeof(Nullable<int>).GetConstructor(new[] { typeof(int) });
il.Emit(OpCodes.Ldc_I4_6);
il.Emit(OpCodes.Newobj, ctor);
il.Emit(OpCodes.Box, typeof(Nullable<int>)); // box followed by unbox
il.Emit(OpCodes.Unbox, typeof(Nullable<int>));
var getValue = typeof(Nullable<int>).GetMethod("get_HasValue");
il.Emit(OpCodes.Call, getValue);
il.Emit(OpCodes.Ret);
Console.WriteLine(m.Invoke(null, null));
The downside to this is that boxing causes memory allocation for the boxed object, so it is a bit slower than using local variables (which would already be allocated). But, it saves you from having to determine, declare, and reference all of the local variables you need.
If the variable is already on the stack, you can go ahead and just emit the method call.
It seems that the constructor doesn't push the variable on the stack in a typed form. After digging into the IL a bit, it appears there are two ways of using the variable after constructing it.
You can load the variable that will store the reference onto the evaluation stack before calling the constructor, and then load that variable again after calling the constructor like so:
DynamicMethod method = new DynamicMethod("M", typeof(bool), Type.EmptyTypes);
ILGenerator il = method.GetILGenerator();
Type nullable = typeof(Nullable<int>);
ConstructorInfo ctor = nullable.GetConstructor(new Type[] { typeof(int) });
MethodInfo getValue = nullable.GetProperty("HasValue").GetGetMethod();
LocalBuilder value = il.DeclareLocal(nullable);
// load the variable to assign the value from the ctor to
il.Emit(OpCodes.Ldloca_S, value);
// load constructor args
il.Emit(OpCodes.Ldc_I4_6);
il.Emit(OpCodes.Call, ctor);
il.Emit(OpCodes.Ldloca_S, value);
il.Emit(OpCodes.Call, getValue);
il.Emit(OpCodes.Ret);
Console.WriteLine(method.Invoke(null, null));
The other option is doing it the way you have shown. The only reason for this that I can see is that the ctor methods return void, so they don't put their value on the stack like other methods. It does seem strange that you can call Setloc if the new object isn't on the stack.
After looking at the options some more and further consideration, I think you're right in assuming it can't be done. If you examine the stack behaviour of MSIL instructions, you can see that no op leaves its operand(s) on the stack. Since this would be a requirement for a 'get address of stack entry' op, I'm fairly confident one doesn't exist.
That leaves you with either dup+box or stloc+ldloca. As you've pointed out, the latter is likely more efficient.
#greg: Many instructions leave their result on the stack, but no instructions leave any of their operands on the stack, which would be required for a 'get stack element address' instruction.
Just wrote a class that does what the OP is asking... here's the IL code that C# compiler produces:
IL_0008: ldarg.0
IL_0009: ldarg.1
IL_000a: newobj instance void valuetype [mscorlib]System.Nullable`1<int32>::.ctor(!0)
IL_000f: stfld valuetype [mscorlib]System.Nullable`1<int32> ConsoleApplication3.Temptress::_X
IL_0014: nop
IL_0015: ret