Using "ERC20" and interfaces names as variable (in functions) - solidity

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.

Related

Using a state variable from another contract

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.

"python function decorator" for objective-c to change a method's behavior

I want to modify the behavior of some function without being the author of that function. What I control is that I can ask the author to follow some pattern, e.g. use a base class, use a certain decorator, property etc.
If in python, I would use a decorator to change the behavior of a method.
As an example, My goal: Improve code coverage by automatically testing over multiple input data.
Pseudo code:
#implementation SomeTestSuiteClass
// If in python, I would add a decorator here to change the behavior of the following method
-(void)testSample1 {
input = SpecialProvider();
output = FeatureToTest(input);
SpecialAssert(output);
}
#end
What I want: During test, the testSample1 method will be called multiple times. Each time, the SpecialProvider will emit a different input data. Same for the SpecialAssert, which can verify the output corresponding to the given input.
SpecialProvider and SpecialAssert will be API under my control/ownership (i.e. I write them).
The SomeTestSuiteClass together with the testSample1 will be written by the user (i.e. test writer).
Is there a way for Objective-C to achieve "what I want" above?
You could mock objects and/or its methods using objective-c runtime or some third party frameworks. I discourage it though. That is a sign of poor architecture choices in the 1st place. The main problem in your approach are hidden dependencies in your code directly referencing
SpecialProvider & SpecialAssert symbols directly.
A much better way to this would be like this:
-(void)testSample1:(SpecialProvider*)provider assert:(BOOL (^)(parameterTypes))assertBlock {
input = provider;
output = FeatureToTest(input);
if (assertBlock != nil) {
assertBlock(output);
}
}
Since Objective-c does not support default argument values like Swift does you could emulate it with:
-(void)testSample1 {
[self testSample1:DefaultSpecialProvider() assert:DefaultAssert()];
}
not to call the explicit -(void)testSample1:(SpecialProvider*)provider assert:(BOOL (^)(parameterTypes))assertBlock all the time, however in tests you would always use the explicit 2 argument variant to allow substituting the implementation(s) not being under test.
Further improvement idea:
Put the SpecialProvider and SpecialAssert behind protocols(i.e. equivalent of interfaces in other programming languages) so you can easily exchange the implementation.

Calling function from already deployed contract in solidity?

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.

Explanation on Function literal with receiver in Kotlin

I was following this link https://kotlin.link/articles/DSL-builder-in-Kotlin.html to understand the builder implementation in Kotlin. I didn't understand the methods inside Builder class. Method name() receives Extension Function as an argument which receives nothing and returns String. And the caller calls name { "ABC" }. If the caller is passing String to name method, how does it translate to an Extension method which returns String ?
I tried following Kotlin documentation for Function literals with receivers but all had samples which returns Unit or refers to DSL Builders. Tried googling it as well to understand but no luck in grasping the concept.
The call to name { "ABC" } is a combination of two Kotlin conventions.
There is a convention that if the last parameter to a function is a function you can omit the parenthesis. Also since there are no parameters to the lambda, "ABC" is what is returned by it.
So the caller is actually passing a lambda in the form name ({() -> "ABC"}), rather than a String.
Looking at the example in the link, it doesn't look like the receiver is necessary for name(), which is why it could be misleading.

Calling a function by name input by user

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)();
}