Hi I am new to solidity and I am wondering why we use the keyword memory when declaring a function, what happens if we choose not to use it? For example
function createObject(string _name, uint _dna) public {
object.push(Object(_name, _dna));
}
instead of
function createObject(string memory _name, uint _dna) public {
object.push(Object(_name, _dna));
if you don't write it, easily it will give error
Without the memory keyword, Solidity tries to declare variables in storage.
Much like RAM, Memory in Solidity is a temporary place to store data whereas Storage holds data between function calls. The Solidity Smart Contract can use any amount of memory during the execution but once the execution stops, the Memory is completely wiped off for the next execution. Whereas Storage on the other hand is persistent, each execution of the Smart contract has access to the data previously stored on the storage area.
That is, the structure of storage is set in stone at the time of contract creation based on your contract-level variable declarations and cannot be changed by future method calls. BUT -- the contents of that storage can be changed with sendTransaction calls. Such calls change “state” which is why contract-level variables are called “state variables”. So a variable uint8 storagevar; declared at the contract level can be changed to any valid value of uint8 (0-255) but that “slot” for a value of type uint8 will always be there.
If you declare variables in functions without the memory keyword, then solidity will try to use the storage structure, which currently compiles, but can produce unexpected results. memory tells solidity to create a chunk of space for the variable at method runtime, guaranteeing its size and structure for future use in that method.
memory cannot be used at the contract level. Only in methods.
The memory keyword tells Solidity to store the parameter in a certain place which allows you to change that parameter inside the function itself. Pretty much like RAM.
Calldata is the same but the parameter is immutable. It's better to use that if you don't plan on changing the parameter inside the function because it's more efficient.
Storage tells Solidity that the value is in the state of the smart contract. It's also more efficient than memory if the parameter is indeed in the state.
You can get more information about the difference between these 3 keywords in this article
Related
I want to interact solidity simple smart contract using Golang based Go-ethereum package, which showing me the error of *types.transaction and *big.int (returning these instead of string and uint) while functions are:
function Vote() public payable returns (string memory)
function Result() public view returns (uint)
My question is how can I manage them, so that I can get exactly the same value as required.
I think this is because transaction is being performed before this function call, which may be the cause.
By your guess, you have to wait for the transaction to be mined before you can see any resulting value of the transaction.
However, in your case the results are *types.Transaction and *big.Int, this indicates that you are using the deploy-time contract instance, or not initializing the deployed contract (need RPC connection).
You can refer section "Accessing an Ethereum contract" from here, hope you can find the answer
I see that in many smart contracts address(0) is being used as shorthand for 0x0000000000....
However since it appears very often in almost all smart contracts, I am wondering if it is, or ever becomes gas efficient to simply create the variable as constant in the blockchain instead, and just reference it when necessary, or if it really is just cheaper to constantly write address(0) inline every time.
address public constant NULLADDRESS = address(0); vs using address(0) inline 50 times.
So i just tested this out with this code
pragma solidity >=0.4.22 <0.9.0;
contract NullContract{
address public constant NULLADDRESS = address(0);
function retrieve() public pure returns(address){
return (address(0));
}
}
constant NULLADDRESS needed 21442 gas
and retrieve function which returns value doesn't change anything in the blockchain needed 21420 gas. so its basically the same
I'm new to solidity and I came across the following statement:
address[] memory path = new address[](2);
Someone please break it down for me. Specifically, what does new address[](2) do?
TIA
It initializes new dynamic-length array variable called path
items are of type address
the array is stored in memory, non-persistent data location that is accessible only during the transaction
The right-side of the expression new address[](2) initializes the array with 2 empty items.
In Solidity, there is a difference between dynamic-length and fixed-length arrays. So if your function is expected to return array[] (dynamic-length), the compiler doesn't allow you to return array[2] (fixed-length).
Because of how the memory is structured, it's not possible to resize an array in memory. (However you can resize a storage array.) So this approach is used when you need to return a dynamic-length array. You need to initialize it in memory first with a predefined amount of empty values, and then rewrite those values. See this post for a code example.
I am new to solidity, and I'm trying to wrap my head around memory, it seems we use the memory keyword when dealing with strings, structs etc... in functions, how come we dont do the same when passing in a uint? (at least in my crypto zombies tutorial)
e.g
function createObject(string memory _name, uint _dna) public {
object.push(Object(_name, _dna));
Data location (memory, storage, and calldata) needs to be specified for reference type variables.
Since uint is a value type, its is't specified.
I'm trying to simulate a call the transfer / transferFrom function from a certain contract without submitting it to the blockchain.
This function is used by some contracts to implement some sort of taxing system before any buy/sell.
An example of some tax implementation would be:
function transfer(address recipient, uint256 amount) public override returns (bool) {
amount = amount.mul(0.8); // tax 20%
_transfer(_msgSender(), recipient, amount);
return true;
}
The leading _transfer call is then altering the internal _balances variable with the modified amount variable.
Straight of the bat, I do not want to change the state of anything as that destroys the purpose of the simulation I'm trying to achieve.
This means that I have to use address.staticcall to call this function, since it does not alter the original state. (at least that's what I think it does, correct me if I'm wrong).
The issue now is that the transfer function does not return the modified amount variable. It only returns true or false, and this is pretty much where I get stuck.
How could I retrieve the modified amount variable? Do I need to use assembly or is there some other way of achieving this?