I want to know how to call a function from already deployed contract in solidity. I tried below one but it's throwing error and require without imorting the deployed contract
contract B {
watch_addr = 0x1245689;
function register(string _text) {
watch_addr.call(bytes4(keccak256("register(string)")), _text);
}
}
Can any one please tell me the solution?
error:browser/delegate.sol:14:31: TypeError: Invalid type for argument in function call. Invalid implicit conversion from bytes4 to bytes memory requested. This function requires a single bytes argument. If all your arguments are value types, you can use abi.encode(...) to properly generate it.
watch_addr.call(bytes4(keccak256(abi.encode("register(string)"))));
In version 5.0 Solidity had some breaking changes:
The functions .call() ... now accept only a single bytes argument. Moreover, the argument is not padded. This was changed to make more explicit and clear how the arguments are concatenated. Change ... every .call(signature, a, b, c) to use .call(abi.encodeWithSignature(signature, a, b, c)) (the last one only works for value types). ... Even though it is not a breaking change, it is suggested that developers change x.call(bytes4(keccak256("f(uint256)"), a, b) to x.call(abi.encodeWithSignature("f(uint256)", a, b)).
So, the suggested way to call other contract is like this:
pragma solidity ^0.5.3;
contract test3 {
address watch_addr = address(0x1245689);
function register(string memory _text) public {
watch_addr.call(abi.encodeWithSignature("register(string)", _text));
}
}
Also note added memory keyword: you now need to specify data location for function parameters of complex types:
Explicit data location for all variables of struct, array or mapping types is now mandatory. This is also applied to function parameters and return variables.
Related
I'm having problems wrapping my head around ERC20 and interfaces passed as variables.
Examples:
function foo(ERC20 _project) external { //some code }
function fuu(IERC4626 _project) external { ERC20(_project.asset()) }
What does this exactly do and how do we use it?
Haven't been able to find any explanation next to: Using interface name as Variable type. A link to the explanation is also fine.
My guesses:
Example 1: we input an address type which simply refers to an ERC20 contract, which we can use then as:
Project project = _project;
project.withdraw();
If above is true, why don't we simply take in an address type in the function instead of "ERC20" type?
Example 2: Calls an ERC20 contract which implements the IERC4626 interface? If so, how is that checked? tbh I have no idea.
How I can use a state variable which is in another contract(contract_a) in my contract(contract_b).
That variable is public. I just want to use some special variables not all data that are in contract_1.
First answer here, I wish it'll be helpful.
It looks like every variable of a contract has an implicit getter method, which at first I thought was a little unusual.
When you call this variable from another contract, you are calling its getter method.
So, instead of calling car.color, you've got to call car.color().
I'm still learning, so DYOR.
When you use the import statement in a contract you import all the functions and all the variables of the smart contract you are importing.
In your contractB you need to have an instance of the contractA (or its address) and then call through this instance the variable you want to access. E.g:
import "./ContractA.sol"
contract ContractB {
ContractA instanceOfA;
function callA() public {
instanceOfA.variableYouWantToAccess();
}
}
Note the parentheses () after the name of the variable you want to access, that is because Solidity, for all the varibles, specifies a getter function which is the function you call in order to access these varibles.
function _postValidatePurchase (
address _beneficiary,
uint256 _weiAmount
)
pure internal
{
// optional override
}
When I compile I get this error in parts of my smart contract that mimic the function above: "Warning: Unused function parameter. Remove or comment out the variable name to silence this warning.uint256 _weiAmount". However, when I comment out the uint and weiAmount, I get these errors :
DocstringParsingError: Documented parameter "_beneficiary" not found in the parameter list of the function.
DocstringParsingError: Documented parameter "_weiAmount" not found in the parameter list of the function.
libs/openzeppelin/crowdsale/Crowdsale.sol:105:5: TypeError: Wrong argument count for function call: 2 arguments given but expected 0.
_postValidatePurchase(_beneficiary, weiAmount);
regarding this line:
_postValidatePurchase(_beneficiary, weiAmount);
}
"Warning: Unused function parameter" is not an error, just a warning. If you have a function with parameters you are not using inside the function, why do you need them? You can just remove them from the input. The only case I can think of is when you are overriding the function. In any case, a warning does not prevent the contract from being compiled. You can just ignore the warning.
I am a newbie in Kotlin, I just started to learn it,
I get the following code example about literal/high order function:
fun myHigherOrderFun(functionArg: (Int)->String) = functionArg(5)
println ( myHigherOrderFun { "The Number is $it" })
prints "The Number is 5"
Which I have difficulty to understand: the function myHigherOrderFun get a lambda function as parameter but i can't understand, where is the (Int) input parameter? I see is passed in functionArg(5)... but i can't realize how is possible that?
Thanks in advance.
To start from the beginning, in Kotlin functions are first-class types, just like numbers and Strings and stuff. So a function can take another function as a parameter, and/or return a function as its result. A function which does this is called a ‘higher-order function’.
And that's what you have in your example! The line:
fun myHigherOrderFun(functionArg: (Int)->String) = functionArg(5)
defines myHigherOrderFun() as a function which takes one parameter, which is itself a function taking a single Int parameter and returning a String. (myHigherOrderFun() doesn't specify an explicit return type, so it's inferred to be a String too.)
The next line is probably where things are less clear:
println(myHigherOrderFun{ "The Number is $it" })
The first non-obvious thing is that it's calling myHigherOrderFun() with a parameter. Because that parameter is a lambda, Kotlin lets you omit the usual (…), and use only the braces.
The other non-obvious thing is the lambda itself: { "The Number is $it" }. This is a literal function taking one parameter (of unspecified type).
Normally, you'd have to specify any parameters explicitly, e.g.: { a: Char, b: Int -> /* … */ }. But if there's exactly one parameter, and you aren't specifying its type, then you can skip that and just refer to the parameter as it. That's what's happening here.
(If the lambda didn't reference it, then it would be a function taking no parameters at all.)
And because the lambda is being passed to something expecting a function taking an Int parameter, Kotlin knows that it must be an Int, which is why we can get away without specifying that.
So, Kotlin passes that lambda to the myHigherOrderFun(), which executes the lambda, passing 5 as it. That interpolates it into a string, which it returns as the argument to println().
Many lambdas take a single parameter, so it gets used quite a lot in Kotlin; it's more concise (and usually more readable) than the alternative. See the docs for more info.
Is it possible to call a function by name in Objective C? For instance, if I know the name of a function ("foo"), is there any way I can get the pointer to the function using that name and call it? I stumbled across a similar question for python here and it seems it is possible there. I want to take the name of a function as input from the user and call the function. This function does not have to take any arguments.
For Objective-C methods, you can use performSelector… or NSInvocation, e.g.
NSString *methodName = #"doSomething";
[someObj performSelector:NSSelectorFromString(methodName)];
For C functions in dynamic libraries, you can use dlsym(), e.g.
void *dlhandle = dlopen("libsomething.dylib", RTLD_LOCAL);
void (*function)(void) = dlsym(dlhandle, "doSomething");
if (function) {
function();
}
For C functions that were statically linked, not in general. If the corresponding symbol hasn’t been stripped from the binary, you can use dlsym(), e.g.
void (*function)(void) = dlsym(RTLD_SELF, "doSomething");
if (function) {
function();
}
Update: ThomasW wrote a comment pointing to a related question, with an answer by dreamlax which, in turn, contains a link to the POSIX page about dlsym. In that answer, dreamlax notes the following with regard to converting a value returned by dlsym() to a function pointer variable:
The C standard does not actually define behaviour for converting to and from function pointers. Explanations vary as to why; the most common being that not all architectures implement function pointers as simple pointers to data. On some architectures, functions may reside in an entirely different segment of memory that is unaddressable using a pointer to void.
With this in mind, the calls above to dlsym() and the desired function can be made more portable as follows:
void (*function)(void);
*(void **)(&function) = dlsym(dlhandle, "doSomething");
if (function) {
(*function)();
}